From 1178461dffe2068e0edc74fcdab939d2fbfacc25 Mon Sep 17 00:00:00 2001 From: kx9x Date: Wed, 5 Jan 2022 18:05:18 -0800 Subject: [PATCH 01/83] Update run-help.yml --- .github/workflows/run-help.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/run-help.yml b/.github/workflows/run-help.yml index 42bd91c..6369688 100644 --- a/.github/workflows/run-help.yml +++ b/.github/workflows/run-help.yml @@ -1,5 +1,7 @@ name: Multisig-Run help +on: [pull_request] + jobs: runHelp: runs-on: ubuntu-latest From cd4642e2cd174ad7b31fb42b0de3c61fa6617ded Mon Sep 17 00:00:00 2001 From: kx9x Date: Wed, 5 Jan 2022 18:28:46 -0800 Subject: [PATCH 02/83] Update README.md --- README.md | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1e95a95..106f2eb 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,26 @@ Collection of useful scripts to manage gnosis multisig wallets - [Gnosis Safe link](https://gnosis-safe.io/app/) -## Bootstrap +## Bootstrapping If you have downloaded this template repository, you need to fill in some config values and add some repository secrets. -List of tasks: -- +### Secrets +Add these repository secrets. Go to https://github.com/{org}/{repo}/settings/secrets/actions + +1. PAT - generate personal access token. Go to https://github.com/settings/tokens/new and click repo for scopes. Make sure to reset this secret when the PAT expires. +2. *SCAN_TOKEN - Put in a token from *scan, where * can be ether, ftm, snow, bsc, arbi, or polygon +3. TELEGRAM_TOKEN - This is the token for your telegram bot that will send messages to channels. If you are in the yearn org, contact kx9x for the robowoofy token. +4. PRIVATE_KEY - Generate a private key for your multisig delegate and put it in a github secret. Do not use this private key for anything else. We recommend that you just throw it away once you add the secret. Anyone with access to your repo and the actions will be able to take this private key, so don't make any assumptions. Be ready to revoke your delegate if you see any suspicious transactions queued to it. + +### Config values +In .github/workflows/run-command.yml, fill in eth_safe and ftm_safe with the addresses for your eth and ftm safes. + +Fill in the telegram channel ids as well. You can find these ids by opening your chat in telegram web, taking the number from the url, and adding a 100 between the - and the number. For example, -3456789 would become -1003456789. Announcement and group chats allow you to notify 2 seperate channels. Leave telegram chat ids blank if you don't want notifications. + +Fill in everything in the .env file. + +Optional: +Fill in scripts/shame.py with a mapping of addresses to signer names for the /shame command. ## Usage Follow the process steps below for queuing transaction to your multisig @@ -59,4 +74,4 @@ Run a multisig tx function on ftm ``` brownie run main run_example --network ftm-main-fork -``` \ No newline at end of file +``` From 48825599792d9779d1a32a743596cdf2701efcbe Mon Sep 17 00:00:00 2001 From: kx9x Date: Wed, 5 Jan 2022 18:29:17 -0800 Subject: [PATCH 03/83] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 106f2eb..e44ed5a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# strategist-ms +# yearn-multisig-actions -Collection of useful scripts to manage gnosis multisig wallets +Collection of useful scripts and pipelines to manage gnosis multisig wallets - [Gnosis Safe link](https://gnosis-safe.io/app/) ## Bootstrapping From ffef6be0d891bb2c5da79aea7f5d95f32497112b Mon Sep 17 00:00:00 2001 From: kx9x Date: Wed, 5 Jan 2022 18:29:52 -0800 Subject: [PATCH 04/83] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e44ed5a..60bc1f0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # yearn-multisig-actions -Collection of useful scripts and pipelines to manage gnosis multisig wallets +Collection of useful scripts and pipelines to delegate transactions to gnosis multisig wallets - [Gnosis Safe link](https://gnosis-safe.io/app/) ## Bootstrapping From dcc166237449050091b757045f706a537cf15e5d Mon Sep 17 00:00:00 2001 From: kx9x Date: Wed, 5 Jan 2022 19:25:11 -0800 Subject: [PATCH 05/83] Update brownie-config.yaml --- brownie-config.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/brownie-config.yaml b/brownie-config.yaml index 3310ad7..dcf532f 100644 --- a/brownie-config.yaml +++ b/brownie-config.yaml @@ -2,3 +2,4 @@ networks: default: eth-main-fork autofetch_sources: true +dotenv: .env From 64b466b02e99d8ccedd8afcfcc5069970223df91 Mon Sep 17 00:00:00 2001 From: kx9x Date: Wed, 5 Jan 2022 19:37:39 -0800 Subject: [PATCH 06/83] Update requirements-dev.txt --- requirements-dev.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index dfaed42..7357d2b 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -7,4 +7,3 @@ regex==2021.10.8 tomli==1.2.1 tenacity==8.0.1 psutil==5.8.0 -python-dotenv==0.16.0 \ No newline at end of file From 872e5496087d4f62ac93a973327ad0936d757aec Mon Sep 17 00:00:00 2001 From: kx9x Date: Wed, 5 Jan 2022 19:38:07 -0800 Subject: [PATCH 07/83] Update safes.py --- ci/safes.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/ci/safes.py b/ci/safes.py index 30cdf6e..b0a2955 100644 --- a/ci/safes.py +++ b/ci/safes.py @@ -1,10 +1,8 @@ import os -from dotenv import load_dotenv from ci.ci_override import DelegateSafe as ApeSafe from brownie import network -load_dotenv() if network.chain.id == 250: safe = ApeSafe(os.getenv("FTM_SAFE_ADDRESS")) elif network.chain.id == 137: From 130052666e1541413cf63f2fe6b8a356b4955c7e Mon Sep 17 00:00:00 2001 From: listonjesse Date: Wed, 2 Feb 2022 20:07:09 -0800 Subject: [PATCH 08/83] feat: add rin --- .env | 3 ++- ci/safes.py | 2 ++ network-config.yaml | 18 ++++++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/.env b/.env index ad71737..e8e3925 100644 --- a/.env +++ b/.env @@ -4,4 +4,5 @@ DELEGATE_ADDRESS= ETH_SAFE_ADDRESS= FTM_SAFE_ADDRESS= POLYGON_SAFE_ADDRESS= -BSC_SAFE_ADDRESS= \ No newline at end of file +BSC_SAFE_ADDRESS= +RIN_SAFE_ADDRESS= \ No newline at end of file diff --git a/ci/safes.py b/ci/safes.py index b0a2955..22c4051 100644 --- a/ci/safes.py +++ b/ci/safes.py @@ -9,5 +9,7 @@ safe = ApeSafe(os.getenv("POLYGON_SAFE_ADDRESS")) elif network.chain.id == 56: safe = ApeSafe(os.getenv("BSC_SAFE_ADDRESS")) +elif network.chain.id == 4: + safe = ApeSafe(os.getenv("RIN_SAFE_ADDRESS")) else: safe = ApeSafe(os.getenv("ETH_SAFE_ADDRESS")) diff --git a/network-config.yaml b/network-config.yaml index cee065a..bfc1636 100644 --- a/network-config.yaml +++ b/network-config.yaml @@ -27,6 +27,12 @@ live: id: ftm-main host: https://rpc.ftm.tools explorer: https://api.ftmscan.com/api +- name: Rinkeby + networks: + - chainid: 4 + host: https://rinkeby.infura.io/v3/b795a81f7b664a4494b10fa8d0244776 + id: rin-main + name: Mainnet development: - cmd: ganache-cli @@ -77,3 +83,15 @@ development: id: matic-main-fork name: Ganache-CLI (MATIC-Mainnet Fork) timeout: 1200 +- cmd: ganache-cli + cmd_settings: + accounts: 10 + evm_version: istanbul + fork: rin-main + gas_limit: 12000000 + mnemonic: brownie + port: 8545 + host: http://127.0.0.1 + id: rin-main-fork + name: Ganache-CLI (RINKEYBY-Mainnet Fork) + timeout: 1200 From 19a2c8f14d9832c3a7bbb0e376b8a61fe96ae604 Mon Sep 17 00:00:00 2001 From: listonjesse Date: Wed, 2 Feb 2022 20:13:15 -0800 Subject: [PATCH 09/83] chore: bump ci ver --- .github/workflows/run-command.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/run-command.yml b/.github/workflows/run-command.yml index d19022e..8458f6a 100644 --- a/.github/workflows/run-command.yml +++ b/.github/workflows/run-command.yml @@ -31,7 +31,7 @@ on: jobs: dispatchCommand: - uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.0.11 + uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.0.12 with: ref: ${{ github.event.inputs.ref }} comment-id: ${{ github.event.inputs.comment-id }} @@ -56,6 +56,8 @@ jobs: failure_telegram_chat_id: '' ftm_safe: '' eth_safe: '' + home_path: /home/runner + cached_runner: false secrets: TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }} FTMSCAN_TOKEN: ${{ secrets.FTMSCAN_TOKEN }} From 00dfb5dea23f546ef46381019fa914370f5af7a7 Mon Sep 17 00:00:00 2001 From: listonjesse Date: Wed, 2 Feb 2022 20:21:14 -0800 Subject: [PATCH 10/83] chore: add be and bump ci --- .github/workflows/run-command.yml | 8 +++---- ci/ci_override.py | 40 +++++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/.github/workflows/run-command.yml b/.github/workflows/run-command.yml index 8458f6a..beae124 100644 --- a/.github/workflows/run-command.yml +++ b/.github/workflows/run-command.yml @@ -26,12 +26,13 @@ on: delete-branch-after-send: description: 'Set to true to delete the PR branch after running with send=true' default: 'true' - pull_request_author: + be: required: false + description: 'backend for gnosis' jobs: dispatchCommand: - uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.0.12 + uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.0.13 with: ref: ${{ github.event.inputs.ref }} comment-id: ${{ github.event.inputs.comment-id }} @@ -54,10 +55,9 @@ jobs: group_telegram_chat_id: '' announcement_telegram_chat_id: '' failure_telegram_chat_id: '' - ftm_safe: '' - eth_safe: '' home_path: /home/runner cached_runner: false + be: ${{ github.event.inputs.be }} secrets: TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }} FTMSCAN_TOKEN: ${{ secrets.FTMSCAN_TOKEN }} diff --git a/ci/ci_override.py b/ci/ci_override.py index 4125dc3..6e5fa78 100644 --- a/ci/ci_override.py +++ b/ci/ci_override.py @@ -1,6 +1,6 @@ import os -from ape_safe import ApeSafe -from brownie import accounts +from ape_safe import ApeSafe, transaction_service +from brownie import accounts, network from gnosis.safe.safe_tx import SafeTx from typing import Optional, Union from brownie.network.account import LocalAccount @@ -14,8 +14,36 @@ DELEGATE_ADDRESS = os.environ.get("DELEGATE_ADDRESS") home_directory = os.environ.get("HOME") +gnosis_frontend_urls = { + 'gnosis': { + 1: 'https://gnosis-safe.io/app/eth:{0}/transactions/queue', + 4: 'https://gnosis-safe.io/app/rin:{0}/transactions/queue', + 56: 'https://gnosis-safe.io/app/bsc:{0}/transactions/queue', + 100: 'https://gnosis-safe.io/app/xdai:{0}/transactions/queue', + 137: 'https://gnosis-safe.io/app/matic:{0}/transactions/queue', + 250: 'https://safe.fantom.network/#/safes/{0}/transactions', + 42161: 'https://gnosis-safe.io/app/arbi:{0}/transactions/queue' + } +} class DelegateSafe(ApeSafe): + def __init__(self, address, base_url=None, multisend=None): + """ + Create an ApeSafe from an address or a ENS name and use a default connection. + """ + backend_urls = { + 'gnosis': transaction_service, + } + + # default to gnosis if we don't have a custom version + if network.chain.id not in backend_urls[self.backend_type]: + backend_url_from_config = backend_urls["gnosis"][network.chain.id] + else: + backend_url_from_config = backend_urls[self.backend_type][network.chain.id] + + self.base_url = base_url or backend_url_from_config + super().__init__(address, base_url, multisend) + @property def is_ci(self): return os.environ.get("CI", "").lower() == "true" @@ -24,6 +52,11 @@ def is_ci(self): def is_send(self): return os.environ.get("GITHUB_ACTION_SEND", "").lower() == "true" + @property + def backend_type(self): + backend_from_env = os.environ.get("BE", "").lower() + return backend_from_env if backend_from_env != "" else "gnosis" + def post_transaction(self, safe_tx: SafeTx): super().post_transaction(safe_tx) @@ -41,6 +74,9 @@ def preview(self, safe_tx: SafeTx, events=True, call_trace=False, reset=True): def get_signer(self, signer: Optional[Union[LocalAccount, str]] = None) -> LocalAccount: if self.is_ci: + with open(os.path.join(home_directory, "safe.txt"), "w") as f: + f.write(str(self.frontend_url.format(self.address))) + if self.is_send: key = os.environ.get("PRIVATE_KEY") assert ( From 0a7a7066081ec72eeff5d2548a2dee9fe6b999ac Mon Sep 17 00:00:00 2001 From: listonjesse Date: Wed, 2 Feb 2022 20:31:10 -0800 Subject: [PATCH 11/83] chore: fix hydrate with new format --- ci/hydrate_ci_cache.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ci/hydrate_ci_cache.py b/ci/hydrate_ci_cache.py index 7b95a81..dd64318 100644 --- a/ci/hydrate_ci_cache.py +++ b/ci/hydrate_ci_cache.py @@ -6,6 +6,7 @@ import ci.ci_override vyper_releases = [ + "https://github.com/vyperlang/vyper/releases/download/v0.3.1/vyper.0.3.1.linux", "https://github.com/vyperlang/vyper/releases/download/v0.3.0/vyper.0.3.0+commit.8a23feb.linux", "https://github.com/vyperlang/vyper/releases/download/v0.2.16/vyper.0.2.16+commit.59e1bdd.linux", "https://github.com/vyperlang/vyper/releases/download/v0.2.15/vyper.0.2.15+commit.6e7dba7.linux", @@ -27,6 +28,8 @@ solc_url_prefix = "https://solc-bin.ethereum.org/linux-amd64/solc-linux-amd64-" solc_release_versions = [ + "v0.8.11+commit.d7f03943", + "v0.8.10+commit.fc410830", "v0.8.9+commit.e5eed63a", "v0.8.8+commit.dddeac2f", "v0.8.7+commit.e28d00a7", @@ -101,7 +104,8 @@ def hydrate_compiler_cache(): for vyper_release in vyper_releases: - name = vyper_release[vyper_release.index("vyper.") : vyper_release.index("+")] + mod = vyper_release.index("+") if "+" in vyper_release else vyper_release.index(".linux") + name = vyper_release[vyper_release.index("vyper.") : mod] print("Downloading " + name) r = requests.get(vyper_release, allow_redirects=True) vvm_folder = os.path.join(home_directory, ".vvm/") From f5750eec196a645f242397c1be82920165be15c1 Mon Sep 17 00:00:00 2001 From: listonjesse Date: Wed, 2 Feb 2022 20:34:37 -0800 Subject: [PATCH 12/83] chore: bump v0.0.16 --- .github/workflows/run-command.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/run-command.yml b/.github/workflows/run-command.yml index beae124..4da1a49 100644 --- a/.github/workflows/run-command.yml +++ b/.github/workflows/run-command.yml @@ -32,7 +32,7 @@ on: jobs: dispatchCommand: - uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.0.13 + uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.0.16 with: ref: ${{ github.event.inputs.ref }} comment-id: ${{ github.event.inputs.comment-id }} @@ -42,7 +42,6 @@ jobs: send: ${{ github.event.inputs.send }} pull_request_number: ${{ github.event.inputs.pull_request_number }} delete-branch-after-send: ${{ github.event.inputs.delete-branch-after-send }} - pull_request_author: ${{ github.event.inputs.pull_request_author }} github_run_id: $GITHUB_RUN_ID github_repository: $GITHUB_REPOSITORY github_workspace: $GITHUB_WORKSPACE From cb286b3606c1074a6c1618502989c3c02c6ca57c Mon Sep 17 00:00:00 2001 From: listonjesse Date: Wed, 2 Feb 2022 20:48:13 -0800 Subject: [PATCH 13/83] chore: update readme.md --- .github/workflows/run-command.yml | 8 ++++---- README.md | 30 ++++++++++++++++++++++++------ 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/.github/workflows/run-command.yml b/.github/workflows/run-command.yml index 4da1a49..3176dad 100644 --- a/.github/workflows/run-command.yml +++ b/.github/workflows/run-command.yml @@ -61,9 +61,9 @@ jobs: TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }} FTMSCAN_TOKEN: ${{ secrets.FTMSCAN_TOKEN }} ETHERSCAN_TOKEN: ${{ secrets.ETHERSCAN_TOKEN }} - POLYGONSCAN_TOKEN: '' - BSCSCAN_TOKEN: '' - ARBISCAN_TOKEN: '' - SNOWTRACE_TOKEN: '' + POLYGONSCAN_TOKEN: ${{ secrets.POLYGONSCAN_TOKEN }} + BSCSCAN_TOKEN: ${{ secrets.POLYGONSCAN_TOKEN }} + ARBISCAN_TOKEN: ${{ secrets.ARBISCAN_TOKEN }} + SNOWTRACE_TOKEN: ${{ secrets.SNOWTRACE_TOKEN }} PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }} PAT: ${{ secrets.PAT }} diff --git a/README.md b/README.md index 60bc1f0..0645197 100644 --- a/README.md +++ b/README.md @@ -6,18 +6,33 @@ Collection of useful scripts and pipelines to delegate transactions to gnosis mu ## Bootstrapping If you have downloaded this template repository, you need to fill in some config values and add some repository secrets. +#### Adding a delegate account +Generate a private key for your multisig delegate. Do not use this private key for anything else. We recommend that you just throw it away once you add the secret. Anyone with access to your repo and the actions will be able to take this private key, so don't make any assumptions. + +Be ready to revoke your delegate if you see any suspicious transactions queued to it. + +You must be a owner of the safe to add a delegate to it. + +You can generate a new delegate using the brownie console. Before you start, make sure that you have your safe owner account in brownie: `brownie accounts new multi-sig-delegator` + +Modify scripts/delegates.py with your safe and delegator details. + +To create and add a new delegate, run `brownie run delegates create_and_add_delegate` + +To add an existing account as a delegate, run `brownie run delegates add_delegate_from_existing_address
` + +If you want to add a delegate via a UI, you can also use https://gnosis-safe-delegate.vercel.app/ + ### Secrets Add these repository secrets. Go to https://github.com/{org}/{repo}/settings/secrets/actions 1. PAT - generate personal access token. Go to https://github.com/settings/tokens/new and click repo for scopes. Make sure to reset this secret when the PAT expires. -2. *SCAN_TOKEN - Put in a token from *scan, where * can be ether, ftm, snow, bsc, arbi, or polygon +2. *SCAN_TOKEN - Put in a token from *scan, where * can be ether, ftm, snow, bsc, arbi, or polygon. If you don't need token, then either set the secret to something random or edit run-command.yml to pass in '' for the token you don't need. 3. TELEGRAM_TOKEN - This is the token for your telegram bot that will send messages to channels. If you are in the yearn org, contact kx9x for the robowoofy token. -4. PRIVATE_KEY - Generate a private key for your multisig delegate and put it in a github secret. Do not use this private key for anything else. We recommend that you just throw it away once you add the secret. Anyone with access to your repo and the actions will be able to take this private key, so don't make any assumptions. Be ready to revoke your delegate if you see any suspicious transactions queued to it. +4. PRIVATE_KEY - Private key for your delegate (get this from the previous step where you added your delegate account) ### Config values -In .github/workflows/run-command.yml, fill in eth_safe and ftm_safe with the addresses for your eth and ftm safes. - -Fill in the telegram channel ids as well. You can find these ids by opening your chat in telegram web, taking the number from the url, and adding a 100 between the - and the number. For example, -3456789 would become -1003456789. Announcement and group chats allow you to notify 2 seperate channels. Leave telegram chat ids blank if you don't want notifications. +Fill in the telegram channel ids. You can find these ids by opening your chat in telegram web, taking the number from the url, and adding a 100 between the - and the number. For example, -3456789 would become -1003456789. Announcement and group chats allow you to notify 2 seperate channels. Leave telegram chat ids blank if you don't want notifications. Fill in everything in the .env file. @@ -30,8 +45,11 @@ Follow the process steps below for queuing transaction to your multisig 2. Create PR on new branch 3. Add a comment on PR to trigger bot to dry-run the txn: ``` - /run file=[main|hydrate_ci_cache] fn=[name_of_fxn] network=[eth|bsc|matic|ftm] + /run file=[main|../ci/hydrate_ci_cache] fn=[name_of_fxn] network=[eth|bsc|matic|ftm] ``` + Note: remove the [ ] symbols, e.g. /run fn=run_example network=matie + file defaults to main, so you can omit it usually + - The GitHub action runner will respond with: - a reply comment with link to the [action which was triggered](https://github.com/yearn/strategist-ms/actions/) - 👀 to indicate command is detected From fa13085ce131ca83c8ef956bb522ec4560a0fa61 Mon Sep 17 00:00:00 2001 From: listonjesse Date: Wed, 2 Feb 2022 21:15:02 -0800 Subject: [PATCH 14/83] fix: remove author --- .github/workflows/shame-command.yml | 2 -- .github/workflows/slash-command.yml | 1 - 2 files changed, 3 deletions(-) diff --git a/.github/workflows/shame-command.yml b/.github/workflows/shame-command.yml index a0217ba..d620aca 100644 --- a/.github/workflows/shame-command.yml +++ b/.github/workflows/shame-command.yml @@ -8,8 +8,6 @@ on: pull_request_number: description: 'Set to the pull request number for this command dispatch' required: false - pull_request_author: - required: false jobs: dispatchCommand: diff --git a/.github/workflows/slash-command.yml b/.github/workflows/slash-command.yml index ae629dd..4da72f5 100644 --- a/.github/workflows/slash-command.yml +++ b/.github/workflows/slash-command.yml @@ -39,7 +39,6 @@ jobs: comment-id=${{ github.event.comment.id }} ref=${{ fromJSON(steps.get-pr.outputs.result).head.ref }} pull_request_number=${{ github.event.issue.number }} - pull_request_author=${{ github.event.issue.user.login }} - name: Edit comment with error message if: failure() || steps.scd.outputs.error-message From 7165db39e9156672d91ef11d6caf13e3410fefcb Mon Sep 17 00:00:00 2001 From: listonjesse Date: Wed, 2 Feb 2022 21:17:50 -0800 Subject: [PATCH 15/83] fix: bug with frontend var --- ci/ci_override.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ci/ci_override.py b/ci/ci_override.py index 6e5fa78..2e756ae 100644 --- a/ci/ci_override.py +++ b/ci/ci_override.py @@ -38,8 +38,10 @@ def __init__(self, address, base_url=None, multisend=None): # default to gnosis if we don't have a custom version if network.chain.id not in backend_urls[self.backend_type]: backend_url_from_config = backend_urls["gnosis"][network.chain.id] + self.frontend_url = gnosis_frontend_urls["gnosis"][network.chain.id] else: backend_url_from_config = backend_urls[self.backend_type][network.chain.id] + self.frontend_url = gnosis_frontend_urls[self.backend_type][network.chain.id] self.base_url = base_url or backend_url_from_config super().__init__(address, base_url, multisend) From 7f93f038b7b26eaeb08b2f04b5309fca94fe6b9c Mon Sep 17 00:00:00 2001 From: kx9x Date: Fri, 4 Feb 2022 18:43:19 -0800 Subject: [PATCH 16/83] fix: don't break hardhat and bump workflow --- .github/workflows/run-command.yml | 2 +- ci/ci_override.py | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/.github/workflows/run-command.yml b/.github/workflows/run-command.yml index 3176dad..ef9bb6c 100644 --- a/.github/workflows/run-command.yml +++ b/.github/workflows/run-command.yml @@ -32,7 +32,7 @@ on: jobs: dispatchCommand: - uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.0.16 + uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.0.17 with: ref: ${{ github.event.inputs.ref }} comment-id: ${{ github.event.inputs.comment-id }} diff --git a/ci/ci_override.py b/ci/ci_override.py index 2e756ae..9ca05c7 100644 --- a/ci/ci_override.py +++ b/ci/ci_override.py @@ -35,16 +35,20 @@ def __init__(self, address, base_url=None, multisend=None): 'gnosis': transaction_service, } - # default to gnosis if we don't have a custom version - if network.chain.id not in backend_urls[self.backend_type]: - backend_url_from_config = backend_urls["gnosis"][network.chain.id] - self.frontend_url = gnosis_frontend_urls["gnosis"][network.chain.id] + # default to gnosis if we don't have a yearn version + if network.chain.id in backend_urls["gnosis"]: + if network.chain.id not in backend_urls[self.backend_type]: + backend_url_from_config = backend_urls["gnosis"][network.chain.id] + self.frontend_url = gnosis_frontend_urls["gnosis"][network.chain.id] + else: + backend_url_from_config = backend_urls[self.backend_type][network.chain.id] + self.frontend_url = gnosis_frontend_urls[self.backend_type][network.chain.id] else: - backend_url_from_config = backend_urls[self.backend_type][network.chain.id] - self.frontend_url = gnosis_frontend_urls[self.backend_type][network.chain.id] + backend_url_from_config = backend_urls["gnosis"][1] + self.frontend_url = gnosis_frontend_urls["gnosis"][1] self.base_url = base_url or backend_url_from_config - super().__init__(address, base_url, multisend) + super().__init__(address, base_url=self.base_url, multisend=multisend) @property def is_ci(self): From 94b9dafd58e1ecd50d38163328316eaaa2fe0016 Mon Sep 17 00:00:00 2001 From: kx9x Date: Fri, 4 Feb 2022 18:43:49 -0800 Subject: [PATCH 17/83] fix: remove todo --- ci/ci_override.py | 1 - 1 file changed, 1 deletion(-) diff --git a/ci/ci_override.py b/ci/ci_override.py index 9ca05c7..4b18557 100644 --- a/ci/ci_override.py +++ b/ci/ci_override.py @@ -10,7 +10,6 @@ # that it writes a file with the nonce. This is used to later tag # the pull request with a label matching the nonce -# TODO: configuration file DELEGATE_ADDRESS = os.environ.get("DELEGATE_ADDRESS") home_directory = os.environ.get("HOME") From a9702d0a0ddef580a41d4d57d12ef8f8013183cf Mon Sep 17 00:00:00 2001 From: kx9x Date: Fri, 4 Feb 2022 18:46:18 -0800 Subject: [PATCH 18/83] feat: arbitrum --- .env | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.env b/.env index e8e3925..1766c27 100644 --- a/.env +++ b/.env @@ -5,4 +5,5 @@ ETH_SAFE_ADDRESS= FTM_SAFE_ADDRESS= POLYGON_SAFE_ADDRESS= BSC_SAFE_ADDRESS= -RIN_SAFE_ADDRESS= \ No newline at end of file +RIN_SAFE_ADDRESS= +ARB_SAFE_ADDRESS= \ No newline at end of file From 0d3e0ce2371f485d061676d2f2dc9765380459c1 Mon Sep 17 00:00:00 2001 From: kx9x Date: Fri, 4 Feb 2022 18:46:31 -0800 Subject: [PATCH 19/83] feat: arbitrum (forgot some files) --- ci/ci_override.py | 2 +- ci/safes.py | 2 ++ network-config.yaml | 18 ++++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/ci/ci_override.py b/ci/ci_override.py index 4b18557..6950861 100644 --- a/ci/ci_override.py +++ b/ci/ci_override.py @@ -21,7 +21,7 @@ 100: 'https://gnosis-safe.io/app/xdai:{0}/transactions/queue', 137: 'https://gnosis-safe.io/app/matic:{0}/transactions/queue', 250: 'https://safe.fantom.network/#/safes/{0}/transactions', - 42161: 'https://gnosis-safe.io/app/arbi:{0}/transactions/queue' + 42161: 'https://gnosis-safe.io/app/arb1:{0}/transactions/queue' } } diff --git a/ci/safes.py b/ci/safes.py index 22c4051..c495d9d 100644 --- a/ci/safes.py +++ b/ci/safes.py @@ -11,5 +11,7 @@ safe = ApeSafe(os.getenv("BSC_SAFE_ADDRESS")) elif network.chain.id == 4: safe = ApeSafe(os.getenv("RIN_SAFE_ADDRESS")) +elif network.chain.id == 42161: + safe = ApeSafe(os.getenv("ARB_SAFE_ADDRESS")) else: safe = ApeSafe(os.getenv("ETH_SAFE_ADDRESS")) diff --git a/network-config.yaml b/network-config.yaml index bfc1636..9dd25e8 100644 --- a/network-config.yaml +++ b/network-config.yaml @@ -33,6 +33,13 @@ live: host: https://rinkeby.infura.io/v3/b795a81f7b664a4494b10fa8d0244776 id: rin-main name: Mainnet +- name: Arbitrum One + networks: + - chainid: 42161 + host: https://arb1.arbitrum.io/rpc + id: arb-main + name: Mainnet + explorer: https://api.arbiscan.io/api development: - cmd: ganache-cli @@ -95,3 +102,14 @@ development: id: rin-main-fork name: Ganache-CLI (RINKEYBY-Mainnet Fork) timeout: 1200 +- cmd: ganache-cli + cmd_settings: + accounts: 10 + evm_version: istanbul + fork: arb-main + gas_limit: 12000000 + mnemonic: brownie + port: 8545 + host: http://127.0.0.1 + id: arb-main-fork + name: Ganache-CLI (ARBITRUMONE-Mainnet Fork) \ No newline at end of file From 1f6d9379f5cffa08744a7d1fddc68b2849d19c27 Mon Sep 17 00:00:00 2001 From: kx9x Date: Sat, 5 Feb 2022 19:10:08 -0800 Subject: [PATCH 20/83] feat: multisig_ci is now a package --- ci/ci_override.py | 103 ------------------------------- ci/hydrate_ci_cache.py | 135 ----------------------------------------- ci/run_brownie.py | 67 -------------------- ci/safes.py | 17 ------ ci/sign.py | 25 -------- requirements-dev.txt | 1 + scripts/main.py | 8 +-- scripts/shame.py | 2 +- 8 files changed, 6 insertions(+), 352 deletions(-) delete mode 100644 ci/ci_override.py delete mode 100644 ci/hydrate_ci_cache.py delete mode 100644 ci/run_brownie.py delete mode 100644 ci/safes.py delete mode 100644 ci/sign.py diff --git a/ci/ci_override.py b/ci/ci_override.py deleted file mode 100644 index 6950861..0000000 --- a/ci/ci_override.py +++ /dev/null @@ -1,103 +0,0 @@ -import os -from ape_safe import ApeSafe, transaction_service -from brownie import accounts, network -from gnosis.safe.safe_tx import SafeTx -from typing import Optional, Union -from brownie.network.account import LocalAccount - -# CI horribleness lurks below -# If running in CI, let's override ApeSafe.post_transaction so -# that it writes a file with the nonce. This is used to later tag -# the pull request with a label matching the nonce - -DELEGATE_ADDRESS = os.environ.get("DELEGATE_ADDRESS") -home_directory = os.environ.get("HOME") - -gnosis_frontend_urls = { - 'gnosis': { - 1: 'https://gnosis-safe.io/app/eth:{0}/transactions/queue', - 4: 'https://gnosis-safe.io/app/rin:{0}/transactions/queue', - 56: 'https://gnosis-safe.io/app/bsc:{0}/transactions/queue', - 100: 'https://gnosis-safe.io/app/xdai:{0}/transactions/queue', - 137: 'https://gnosis-safe.io/app/matic:{0}/transactions/queue', - 250: 'https://safe.fantom.network/#/safes/{0}/transactions', - 42161: 'https://gnosis-safe.io/app/arb1:{0}/transactions/queue' - } -} - -class DelegateSafe(ApeSafe): - def __init__(self, address, base_url=None, multisend=None): - """ - Create an ApeSafe from an address or a ENS name and use a default connection. - """ - backend_urls = { - 'gnosis': transaction_service, - } - - # default to gnosis if we don't have a yearn version - if network.chain.id in backend_urls["gnosis"]: - if network.chain.id not in backend_urls[self.backend_type]: - backend_url_from_config = backend_urls["gnosis"][network.chain.id] - self.frontend_url = gnosis_frontend_urls["gnosis"][network.chain.id] - else: - backend_url_from_config = backend_urls[self.backend_type][network.chain.id] - self.frontend_url = gnosis_frontend_urls[self.backend_type][network.chain.id] - else: - backend_url_from_config = backend_urls["gnosis"][1] - self.frontend_url = gnosis_frontend_urls["gnosis"][1] - - self.base_url = base_url or backend_url_from_config - super().__init__(address, base_url=self.base_url, multisend=multisend) - - @property - def is_ci(self): - return os.environ.get("CI", "").lower() == "true" - - @property - def is_send(self): - return os.environ.get("GITHUB_ACTION_SEND", "").lower() == "true" - - @property - def backend_type(self): - backend_from_env = os.environ.get("BE", "").lower() - return backend_from_env if backend_from_env != "" else "gnosis" - - def post_transaction(self, safe_tx: SafeTx): - super().post_transaction(safe_tx) - - if self.is_ci and self.is_send: - with open(os.path.join(home_directory, "nonce.txt"), "w") as f: - f.write(str(safe_tx.safe_nonce)) - exit(0) - - def preview(self, safe_tx: SafeTx, events=True, call_trace=False, reset=True): - if self.is_ci: - events = False - call_trace = False - - return super().preview(safe_tx, events=events, call_trace=call_trace, reset=reset) - - def get_signer(self, signer: Optional[Union[LocalAccount, str]] = None) -> LocalAccount: - if self.is_ci: - with open(os.path.join(home_directory, "safe.txt"), "w") as f: - f.write(str(self.frontend_url.format(self.address))) - - if self.is_send: - key = os.environ.get("PRIVATE_KEY") - assert ( - key is not None - ), "CI environment missing PRIVATE_KEY environment variable. Please add it as a repository secret." - user = accounts.add(key) - assert ( - user.address == DELEGATE_ADDRESS - ), "Delegate address mismatch. Check you have correct private key." - return user - else: - print("CI dry-run enabled, set send to true to run to completion") - exit(0) - else: - return super().get_signer(signer) - - -with open(os.path.join(home_directory, "alive.signal"), "w") as f: - f.write("I am alive") diff --git a/ci/hydrate_ci_cache.py b/ci/hydrate_ci_cache.py deleted file mode 100644 index dd64318..0000000 --- a/ci/hydrate_ci_cache.py +++ /dev/null @@ -1,135 +0,0 @@ -import requests -import os, stat -from brownie import Contract, network, exceptions -from ape_safe import ApeSafe -import time -import ci.ci_override - -vyper_releases = [ - "https://github.com/vyperlang/vyper/releases/download/v0.3.1/vyper.0.3.1.linux", - "https://github.com/vyperlang/vyper/releases/download/v0.3.0/vyper.0.3.0+commit.8a23feb.linux", - "https://github.com/vyperlang/vyper/releases/download/v0.2.16/vyper.0.2.16+commit.59e1bdd.linux", - "https://github.com/vyperlang/vyper/releases/download/v0.2.15/vyper.0.2.15+commit.6e7dba7.linux", - "https://github.com/vyperlang/vyper/releases/download/v0.2.12/vyper.0.2.12+commit.2c6842c.linux", - "https://github.com/vyperlang/vyper/releases/download/v0.2.11/vyper.0.2.11+commit.5db35ef.linux", - "https://github.com/vyperlang/vyper/releases/download/v0.2.8/vyper.0.2.8+commit.069936f.linux", - "https://github.com/vyperlang/vyper/releases/download/v0.2.7/vyper.0.2.7+commit.0b3f3b3.linux", - "https://github.com/vyperlang/vyper/releases/download/v0.2.6/vyper.0.2.6+commit.35467d5.linux", - "https://github.com/vyperlang/vyper/releases/download/v0.2.5/vyper.0.2.5+commit.a0c561c.linux", - "https://github.com/vyperlang/vyper/releases/download/v0.2.4/vyper.0.2.4+commit.7949850.linux", - "https://github.com/vyperlang/vyper/releases/download/v0.2.3/vyper.0.2.3+commit.006968f.linux", - "https://github.com/vyperlang/vyper/releases/download/v0.2.2/vyper.0.2.2+commit.337c2ef.linux", - "https://github.com/vyperlang/vyper/releases/download/v0.2.1/vyper.0.2.1+commit.cac3d7d.linux", - "https://github.com/vyperlang/vyper/releases/download/v0.2.0/vyper.0.2.0+commit.d2c0c87.linux", - "https://github.com/vyperlang/vyper/releases/download/v0.1.0-beta.17/vyper.0.1.0-beta.17+commit.0671b7b.linux", - "https://github.com/vyperlang/vyper/releases/download/v0.1.0-beta.16/vyper.0.1.0-beta.16+commit.5e4a94a.linux", -] - -solc_url_prefix = "https://solc-bin.ethereum.org/linux-amd64/solc-linux-amd64-" - -solc_release_versions = [ - "v0.8.11+commit.d7f03943", - "v0.8.10+commit.fc410830", - "v0.8.9+commit.e5eed63a", - "v0.8.8+commit.dddeac2f", - "v0.8.7+commit.e28d00a7", - "v0.8.6+commit.11564f7e", - "v0.8.5+commit.a4f2e591", - "v0.8.4+commit.c7e474f2", - "v0.8.3+commit.8d00100c", - "v0.8.2+commit.661d1103", - "v0.8.1+commit.df193b15", - "v0.8.0+commit.c7dfd78e", - "v0.7.6+commit.7338295f", - "v0.7.5+commit.eb77ed08", - "v0.7.4+commit.3f05b770", - "v0.7.3+commit.9bfce1f6", - "v0.7.2+commit.51b20bc0", - "v0.7.1+commit.f4a555be", - "v0.7.0+commit.9e61f92b", - "v0.6.12+commit.27d51765", - "v0.6.11+commit.5ef660b1", - "v0.6.10+commit.00c0fcaf", - "v0.6.9+commit.3e3065ac", - "v0.6.8+commit.0bbfe453", - "v0.6.7+commit.b8d736ae", - "v0.6.6+commit.6c089d02", - "v0.6.5+commit.f956cc89", - "v0.6.4+commit.1dca32f3", - "v0.6.3+commit.8dda9521", - "v0.6.2+commit.bacdbe57", - "v0.6.1+commit.e6f7d5a4", - "v0.6.0+commit.26b70077", - "v0.5.17+commit.d19bba13", - "v0.5.16+commit.9c3226ce", - "v0.5.15+commit.6a57276f", - "v0.5.14+commit.01f1aaa4", - "v0.5.13+commit.5b0b510c", - "v0.5.12+commit.7709ece9", - "v0.5.11+commit.22be8592", - "v0.5.11+commit.c082d0b4", - "v0.5.10+commit.5a6ea5b1", - "v0.5.9+commit.c68bc34e", - "v0.5.9+commit.e560f70d", - "v0.5.8+commit.23d335f2", - "v0.5.7+commit.6da8b019", - "v0.5.6+commit.b259423e", - "v0.5.5+commit.47a71e8f", - "v0.5.4+commit.9549d8ff", - "v0.5.3+commit.10d17f24", - "v0.5.2+commit.1df8f40c", - "v0.5.1+commit.c8a2cb62", - "v0.5.0+commit.1d4f565a", - "v0.4.26+commit.4563c3fc", - "v0.4.25+commit.59dbf8f1", - "v0.4.24+commit.e67f0147", - "v0.4.23+commit.124ca40d", - "v0.4.22+commit.4cb486ee", - "v0.4.21+commit.dfe3193c", - "v0.4.20+commit.3155dd80", - "v0.4.19+commit.c4cbbb05", - "v0.4.18+commit.9cf6e910", - "v0.4.17+commit.bdeb9e52", - "v0.4.16+commit.d7661dd9", - "v0.4.15+commit.8b45bddb", - "v0.4.15+commit.bbb8e64f", - "v0.4.14+commit.c2215d46", - "v0.4.13+commit.0fb4cb1a", - "v0.4.12+commit.194ff033", - "v0.4.11+commit.68ef5810", -] - -home_directory = os.environ.get("HOME") - - -def hydrate_compiler_cache(): - for vyper_release in vyper_releases: - mod = vyper_release.index("+") if "+" in vyper_release else vyper_release.index(".linux") - name = vyper_release[vyper_release.index("vyper.") : mod] - print("Downloading " + name) - r = requests.get(vyper_release, allow_redirects=True) - vvm_folder = os.path.join(home_directory, ".vvm/") - if not os.path.exists(vvm_folder): - os.mkdir(vvm_folder) - file_name = vvm_folder + name.replace(".", "-", 1) - with open(file_name, "wb+") as f: - f.write(r.content) - st = os.stat(file_name) - os.chmod(file_name, st.st_mode | stat.S_IEXEC) - - for solc_release_version in solc_release_versions: - solc_release_url = solc_url_prefix + solc_release_version - prefix = "solc-linux-amd64" - start = solc_release_url.index(prefix) + len(prefix) - end = solc_release_url.index("+") - name = "solc" + solc_release_url[start:end] - print("Downloading " + name) - r = requests.get(solc_release_url, allow_redirects=True) - solcx_folder = os.path.join(home_directory, ".solcx/") - if not os.path.exists(solcx_folder): - os.mkdir(solcx_folder) - file_name = os.path.join(home_directory, ".solcx/") + name - with open(file_name, "wb+") as f: - f.write(r.content) - st = os.stat(file_name) - os.chmod(file_name, st.st_mode | stat.S_IEXEC) \ No newline at end of file diff --git a/ci/run_brownie.py b/ci/run_brownie.py deleted file mode 100644 index 41de7f2..0000000 --- a/ci/run_brownie.py +++ /dev/null @@ -1,67 +0,0 @@ -from subprocess import Popen -from tenacity import * -import sys, time, os, signal, psutil - -home_directory = os.environ.get("HOME") -signal_file_path = os.path.join(home_directory, "alive.signal") -nonce_file_path = os.path.join(home_directory, "nonce.txt") -current_try_count = 0 - - -@retry(stop=stop_after_attempt(5)) -def run_brownie(args): - global current_try_count - - # Kill processes to make sure we start clean - kill_process_by_cmdline("ganache-cli") - kill_process_by_name("brownie") - - if os.path.exists(signal_file_path) and current_try_count == 0: - os.remove(signal_file_path) - print("cleaning up signal from last run") - - if os.path.exists(nonce_file_path): - if current_try_count == 0: - os.remove(nonce_file_path) - else: - print("nonce found, aborting before we trigger another tx") - exit(1) - - p = Popen(args) - - # sleep 10, 20, 30, 40, 50, or 60 seconds based on retries - sleep_time = 10 + min(current_try_count * 10, 50) - print(f"waiting for alive signal, sleeping for {sleep_time} seconds") - time.sleep(sleep_time) - - current_try_count += 1 - - if not os.path.exists(signal_file_path): - print(f"alive signal not found, killing brownie and ganache. queuing try #{current_try_count}") - p.terminate() - kill_process_by_cmdline("ganache-cli") - raise Exception() - - print("found alive signal, waiting for process to complete") - exit_code = p.wait() - os.remove(signal_file_path) - exit(exit_code) - - -def kill_process_by_cmdline(cmdline_arg_find): - for proc in psutil.process_iter(): - for cmdline_arg in proc.cmdline(): - if cmdline_arg_find in cmdline_arg: - pid = proc.pid - os.kill(int(pid), signal.SIGKILL) - - -def kill_process_by_name(proc_name): - for proc in psutil.process_iter(): - if proc_name == proc.name(): - pid = proc.pid - os.kill(int(pid), signal.SIGKILL) - - -if __name__ == "__main__": - run_brownie(sys.argv[1:]) diff --git a/ci/safes.py b/ci/safes.py deleted file mode 100644 index c495d9d..0000000 --- a/ci/safes.py +++ /dev/null @@ -1,17 +0,0 @@ -import os -from ci.ci_override import DelegateSafe as ApeSafe -from brownie import network - - -if network.chain.id == 250: - safe = ApeSafe(os.getenv("FTM_SAFE_ADDRESS")) -elif network.chain.id == 137: - safe = ApeSafe(os.getenv("POLYGON_SAFE_ADDRESS")) -elif network.chain.id == 56: - safe = ApeSafe(os.getenv("BSC_SAFE_ADDRESS")) -elif network.chain.id == 4: - safe = ApeSafe(os.getenv("RIN_SAFE_ADDRESS")) -elif network.chain.id == 42161: - safe = ApeSafe(os.getenv("ARB_SAFE_ADDRESS")) -else: - safe = ApeSafe(os.getenv("ETH_SAFE_ADDRESS")) diff --git a/ci/sign.py b/ci/sign.py deleted file mode 100644 index 731025b..0000000 --- a/ci/sign.py +++ /dev/null @@ -1,25 +0,0 @@ -from ci.safes import safe - - -def sign(nonce_arg = None, skip_preview = False, post_tx = False): - def _sign(func): - def wrapper(): - func() - safe_tx = safe.multisend_from_receipts(safe_nonce=nonce) - if not skip_preview: - safe.preview(safe_tx, call_trace=False) - - if not post_tx and not safe.is_ci: - print("dry-run finished, run again with @sign(post_tx = True) to sign and submit the tx.") - else: - safe.sign_transaction(safe_tx) - safe.post_transaction(safe_tx) - - return wrapper - - if callable(nonce_arg): - nonce = None - return _sign(nonce_arg) - - nonce = int(nonce_arg) if nonce_arg else nonce_arg - return _sign diff --git a/requirements-dev.txt b/requirements-dev.txt index 7357d2b..cb96e54 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -7,3 +7,4 @@ regex==2021.10.8 tomli==1.2.1 tenacity==8.0.1 psutil==5.8.0 +multisig-ci==0.0.1 \ No newline at end of file diff --git a/scripts/main.py b/scripts/main.py index a05c4b6..72229c3 100644 --- a/scripts/main.py +++ b/scripts/main.py @@ -1,7 +1,7 @@ -import ci.ci_override -from ci.ci_override import DelegateSafe as ApeSafe -from ci.safes import safe -from ci.sign import sign +import multisig_ci.ci_override +from multisig_ci.ci_override import DelegateSafe as ApeSafe +from multisig_ci.safes import safe +from multisig_ci.sign import sign @sign diff --git a/scripts/shame.py b/scripts/shame.py index 6da61db..15c78dc 100644 --- a/scripts/shame.py +++ b/scripts/shame.py @@ -1,5 +1,5 @@ from brownie import * -from ci.safes import safe +from multisig_ci.safes import safe import requests from contextlib import redirect_stdout import os From 95ac2d79813e85d517ad175abb4c312c7208af75 Mon Sep 17 00:00:00 2001 From: kx9x Date: Sat, 5 Feb 2022 19:25:13 -0800 Subject: [PATCH 21/83] chore: bump to 0.0.2 --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index cb96e54..e53f015 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -7,4 +7,4 @@ regex==2021.10.8 tomli==1.2.1 tenacity==8.0.1 psutil==5.8.0 -multisig-ci==0.0.1 \ No newline at end of file +multisig-ci==0.0.2 \ No newline at end of file From 5457d6455b72d0171e8f5c17d3d204986d226a3a Mon Sep 17 00:00:00 2001 From: kx9x Date: Sat, 5 Feb 2022 19:28:04 -0800 Subject: [PATCH 22/83] feat: add hydrate compiler cache instructions --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 0645197..2426bed 100644 --- a/README.md +++ b/README.md @@ -93,3 +93,13 @@ Run a multisig tx function on ftm ``` brownie run main run_example --network ftm-main-fork ``` + +## Hydrating the compiler cache + +This is important if you want fast runs. + +1. In run-command.yml, bump compiler_cache_version by 1 (i.e. v0.0.1 to v0.0.2) +2. Check this change into your master/main branch +3. Create a PR from master into a random branch. This is important. Master has to be the base branch for this PR. +4. Comment "/run fn=hydrate_compiler_cache" +5. After this command finishes, you will have all vyper and solc compilers in your cache for each subsequent run. \ No newline at end of file From 458be9fd3c1a7d5cbca0d711676eaacc48af822b Mon Sep 17 00:00:00 2001 From: kx9x Date: Sat, 5 Feb 2022 20:06:42 -0800 Subject: [PATCH 23/83] fix: - to _ --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index e53f015..5b163bb 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -7,4 +7,4 @@ regex==2021.10.8 tomli==1.2.1 tenacity==8.0.1 psutil==5.8.0 -multisig-ci==0.0.2 \ No newline at end of file +multisig_ci==0.0.2 \ No newline at end of file From 9c720b5c986ed41239b3c67cc71d185df9d60b7c Mon Sep 17 00:00:00 2001 From: kx9x Date: Sat, 5 Feb 2022 20:12:32 -0800 Subject: [PATCH 24/83] fix: bump to 0.0.3 --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 5b163bb..7aebd06 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -7,4 +7,4 @@ regex==2021.10.8 tomli==1.2.1 tenacity==8.0.1 psutil==5.8.0 -multisig_ci==0.0.2 \ No newline at end of file +multisig_ci==0.0.3 \ No newline at end of file From 507097d68872753575cff84dff096ba0b94081e5 Mon Sep 17 00:00:00 2001 From: kx9x Date: Sat, 5 Feb 2022 20:18:11 -0800 Subject: [PATCH 25/83] fix: fix --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 7aebd06..f23c06a 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -7,4 +7,4 @@ regex==2021.10.8 tomli==1.2.1 tenacity==8.0.1 psutil==5.8.0 -multisig_ci==0.0.3 \ No newline at end of file +multisig-ci==0.0.3 \ No newline at end of file From 4d6e15b2be789aa273610cc48ae803aac39f3968 Mon Sep 17 00:00:00 2001 From: kx9x Date: Sat, 5 Feb 2022 20:42:46 -0800 Subject: [PATCH 26/83] fix: bump to v0.0.18 --- .github/workflows/run-command.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-command.yml b/.github/workflows/run-command.yml index ef9bb6c..e268dee 100644 --- a/.github/workflows/run-command.yml +++ b/.github/workflows/run-command.yml @@ -32,7 +32,7 @@ on: jobs: dispatchCommand: - uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.0.17 + uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.0.18 with: ref: ${{ github.event.inputs.ref }} comment-id: ${{ github.event.inputs.comment-id }} From 9be416e46c09fe0b46704779482921aaa0ba060e Mon Sep 17 00:00:00 2001 From: kx9x Date: Sat, 5 Feb 2022 21:26:52 -0800 Subject: [PATCH 27/83] chore: update README.md --- README.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 2426bed..2e8f524 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ # yearn-multisig-actions -Collection of useful scripts and pipelines to delegate transactions to gnosis multisig wallets -- [Gnosis Safe link](https://gnosis-safe.io/app/) +Template repository for automating delegate transactions to [Gnosis Safe](https://gnosis-safe.io/app/) multisig wallets through Github Actions ## Bootstrapping If you have downloaded this template repository, you need to fill in some config values and add some repository secrets. @@ -45,10 +44,10 @@ Follow the process steps below for queuing transaction to your multisig 2. Create PR on new branch 3. Add a comment on PR to trigger bot to dry-run the txn: ``` - /run file=[main|../ci/hydrate_ci_cache] fn=[name_of_fxn] network=[eth|bsc|matic|ftm] + /run file=[main|hydrate_ci_cache] fn=[name_of_fxn] network=[eth|bsc|matic|ftm|rin|arb] ``` - Note: remove the [ ] symbols, e.g. /run fn=run_example network=matie - file defaults to main, so you can omit it usually + Note: remove the [ ] symbols, e.g. /run fn=run_example network=matic + The file param defaults to main, so you can usually omit it - The GitHub action runner will respond with: - a reply comment with link to the [action which was triggered](https://github.com/yearn/strategist-ms/actions/) @@ -59,7 +58,7 @@ Follow the process steps below for queuing transaction to your multisig 4. After successful dry run, get a peer review 5. When peer review is complete, they can indicate it by using GitHub runner bot to queue the transaction in Gnosis. This is done by adding same comment as step #3, but this time with "send=true" ``` - /run file=[main|hydrate_ci_cache] network=[eth|bsc|matic|ftm] fn=[name_of_fxn] send=[true|false] delete-branch-after-send=[true|false] + /run file=[main|hydrate_ci_cache] fn=[name_of_fxn] network=[eth|bsc|matic|ftm|rin|arb] send=[true|false] delete-branch-after-send=[true|false] ``` - delete-branch-after-send defaults to true, if you don't want your branch deleted, then set delete-branch-after-send=false 6. After a successful run with send=true, you can track a Gnosis TX back to its PR and original code by going to https://github.com/yearn/strategist-ms/labels and searching for the nonce number and clicking the matching nonce Github label. @@ -102,4 +101,4 @@ This is important if you want fast runs. 2. Check this change into your master/main branch 3. Create a PR from master into a random branch. This is important. Master has to be the base branch for this PR. 4. Comment "/run fn=hydrate_compiler_cache" -5. After this command finishes, you will have all vyper and solc compilers in your cache for each subsequent run. \ No newline at end of file +5. After this command finishes, you will have all vyper and solc compilers in your cache for each subsequent run. From 109ab21e3e1ead2797475a95f0dddc3795997e1e Mon Sep 17 00:00:00 2001 From: kx9x Date: Mon, 7 Feb 2022 22:14:42 -0800 Subject: [PATCH 28/83] fix: better fantom gas limit --- network-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/network-config.yaml b/network-config.yaml index 9dd25e8..a2cfaf6 100644 --- a/network-config.yaml +++ b/network-config.yaml @@ -71,7 +71,7 @@ development: accounts: 10 evm_version: istanbul fork: ftm-main - gas_limit: 12000000 + gas_limit: 8500000 mnemonic: brownie port: 8545 host: http://127.0.0.1 @@ -112,4 +112,4 @@ development: port: 8545 host: http://127.0.0.1 id: arb-main-fork - name: Ganache-CLI (ARBITRUMONE-Mainnet Fork) \ No newline at end of file + name: Ganache-CLI (ARBITRUMONE-Mainnet Fork) From f2e3980a2a5bba18adb1d8194c332e3739f397eb Mon Sep 17 00:00:00 2001 From: kx9x Date: Thu, 10 Mar 2022 14:07:50 -0800 Subject: [PATCH 29/83] chore: bump to v0.0.20 --- .github/workflows/run-command.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-command.yml b/.github/workflows/run-command.yml index e268dee..641954d 100644 --- a/.github/workflows/run-command.yml +++ b/.github/workflows/run-command.yml @@ -32,7 +32,7 @@ on: jobs: dispatchCommand: - uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.0.18 + uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.0.20 with: ref: ${{ github.event.inputs.ref }} comment-id: ${{ github.event.inputs.comment-id }} From 687cd66ccc1bf57bc788f5a62fd11b82012f0d55 Mon Sep 17 00:00:00 2001 From: kx9x Date: Thu, 10 Mar 2022 18:26:52 -0800 Subject: [PATCH 30/83] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2e8f524..fa336eb 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ If you want to add a delegate via a UI, you can also use https://gnosis-safe-del Add these repository secrets. Go to https://github.com/{org}/{repo}/settings/secrets/actions 1. PAT - generate personal access token. Go to https://github.com/settings/tokens/new and click repo for scopes. Make sure to reset this secret when the PAT expires. -2. *SCAN_TOKEN - Put in a token from *scan, where * can be ether, ftm, snow, bsc, arbi, or polygon. If you don't need token, then either set the secret to something random or edit run-command.yml to pass in '' for the token you don't need. +2. {NETWORK}SCAN_TOKEN - Define multiple secrets where {NETWORK} can be ether, ftm, snow, bsc, arbi, or polygon. If you don't need a token for a given network, then either set the secret to something random or edit run-command.yml to pass in '' for the token you don't need. 3. TELEGRAM_TOKEN - This is the token for your telegram bot that will send messages to channels. If you are in the yearn org, contact kx9x for the robowoofy token. 4. PRIVATE_KEY - Private key for your delegate (get this from the previous step where you added your delegate account) From 21d5348f73c4d8439ef6df8bf575efac14586e11 Mon Sep 17 00:00:00 2001 From: kx9x Date: Thu, 10 Mar 2022 18:28:10 -0800 Subject: [PATCH 31/83] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fa336eb..b7887b5 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ If you want to add a delegate via a UI, you can also use https://gnosis-safe-del Add these repository secrets. Go to https://github.com/{org}/{repo}/settings/secrets/actions 1. PAT - generate personal access token. Go to https://github.com/settings/tokens/new and click repo for scopes. Make sure to reset this secret when the PAT expires. -2. {NETWORK}SCAN_TOKEN - Define multiple secrets where {NETWORK} can be ether, ftm, snow, bsc, arbi, or polygon. If you don't need a token for a given network, then either set the secret to something random or edit run-command.yml to pass in '' for the token you don't need. +2. {NETWORK}SCAN_TOKEN - Define multiple secrets where {NETWORK} can be ETHER, FTM, SNOW, BSC, ARBI, or POLYGON. You can generate these tokens by making an account at the respective sites (e.g. etherscan.io, ftmscan.com, etc, etc). If you don't need a token for a given network, then either set the secret to something random or edit run-command.yml to pass in '' for the token you don't need. 3. TELEGRAM_TOKEN - This is the token for your telegram bot that will send messages to channels. If you are in the yearn org, contact kx9x for the robowoofy token. 4. PRIVATE_KEY - Private key for your delegate (get this from the previous step where you added your delegate account) From 559e3f9d3efd697df94e99d4c234639fad79c1c8 Mon Sep 17 00:00:00 2001 From: kx9x Date: Thu, 10 Mar 2022 18:51:10 -0800 Subject: [PATCH 32/83] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b7887b5..9ade9a0 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,9 @@ Add these repository secrets. Go to https://github.com/{org}/{repo}/settings/sec 4. PRIVATE_KEY - Private key for your delegate (get this from the previous step where you added your delegate account) ### Config values -Fill in the telegram channel ids. You can find these ids by opening your chat in telegram web, taking the number from the url, and adding a 100 between the - and the number. For example, -3456789 would become -1003456789. Announcement and group chats allow you to notify 2 seperate channels. Leave telegram chat ids blank if you don't want notifications. +Fill in the telegram channel ids in run-command.yml. You can find these ids by opening your chat in telegram web, taking the number from the url, and adding a 100 between the - and the number. For example, -3456789 would become -1003456789. Announcement and group chats allow you to notify 2 seperate channels. Leave telegram chat ids blank if you don't want notifications. + +Alternatively, you can message @username_to_id_bot on Telegram to find a chat id. Fill in everything in the .env file. From 36a35700e1d33b390ee051ce1edd6bcc9427eddc Mon Sep 17 00:00:00 2001 From: kx9x Date: Tue, 22 Mar 2022 09:42:43 -0700 Subject: [PATCH 33/83] fix: com -> io --- network-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network-config.yaml b/network-config.yaml index a2cfaf6..a8cf85b 100644 --- a/network-config.yaml +++ b/network-config.yaml @@ -5,7 +5,7 @@ live: chainid: 1 id: mainnet host: https://mainnet.infura.io/v3/$WEB3_INFURA_PROJECT_ID - explorer: https://api.etherscan.com/api + explorer: https://api.etherscan.io/api - name: Polygon networks: - name: Mainnet From f207cc5a9084289960929f59333edb0a73ff56d0 Mon Sep 17 00:00:00 2001 From: poolpitako <78830419+poolpitako@users.noreply.github.com> Date: Sat, 23 Apr 2022 16:10:19 -0500 Subject: [PATCH 34/83] Link to create a telegram bot --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9ade9a0..a2c48c2 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,8 @@ Add these repository secrets. Go to https://github.com/{org}/{repo}/settings/sec 1. PAT - generate personal access token. Go to https://github.com/settings/tokens/new and click repo for scopes. Make sure to reset this secret when the PAT expires. 2. {NETWORK}SCAN_TOKEN - Define multiple secrets where {NETWORK} can be ETHER, FTM, SNOW, BSC, ARBI, or POLYGON. You can generate these tokens by making an account at the respective sites (e.g. etherscan.io, ftmscan.com, etc, etc). If you don't need a token for a given network, then either set the secret to something random or edit run-command.yml to pass in '' for the token you don't need. -3. TELEGRAM_TOKEN - This is the token for your telegram bot that will send messages to channels. If you are in the yearn org, contact kx9x for the robowoofy token. -4. PRIVATE_KEY - Private key for your delegate (get this from the previous step where you added your delegate account) +3. TELEGRAM_TOKEN - This is the token for your telegram bot that will send messages to channels. To create a bot go to: https://core.telegram.org/bots. If you are in the yearn org, contact kx9x for the robowoofy token. +5. PRIVATE_KEY - Private key for your delegate (get this from the previous step where you added your delegate account) ### Config values Fill in the telegram channel ids in run-command.yml. You can find these ids by opening your chat in telegram web, taking the number from the url, and adding a 100 between the - and the number. For example, -3456789 would become -1003456789. Announcement and group chats allow you to notify 2 seperate channels. Leave telegram chat ids blank if you don't want notifications. From d246e997b0d9d25f5b378d469898b4313acb91c7 Mon Sep 17 00:00:00 2001 From: poolpitako <78830419+poolpitako@users.noreply.github.com> Date: Sat, 23 Apr 2022 16:13:14 -0500 Subject: [PATCH 35/83] fix enumeration --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a2c48c2..f920506 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Add these repository secrets. Go to https://github.com/{org}/{repo}/settings/sec 1. PAT - generate personal access token. Go to https://github.com/settings/tokens/new and click repo for scopes. Make sure to reset this secret when the PAT expires. 2. {NETWORK}SCAN_TOKEN - Define multiple secrets where {NETWORK} can be ETHER, FTM, SNOW, BSC, ARBI, or POLYGON. You can generate these tokens by making an account at the respective sites (e.g. etherscan.io, ftmscan.com, etc, etc). If you don't need a token for a given network, then either set the secret to something random or edit run-command.yml to pass in '' for the token you don't need. 3. TELEGRAM_TOKEN - This is the token for your telegram bot that will send messages to channels. To create a bot go to: https://core.telegram.org/bots. If you are in the yearn org, contact kx9x for the robowoofy token. -5. PRIVATE_KEY - Private key for your delegate (get this from the previous step where you added your delegate account) +4. PRIVATE_KEY - Private key for your delegate (get this from the previous step where you added your delegate account) ### Config values Fill in the telegram channel ids in run-command.yml. You can find these ids by opening your chat in telegram web, taking the number from the url, and adding a 100 between the - and the number. For example, -3456789 would become -1003456789. Announcement and group chats allow you to notify 2 seperate channels. Leave telegram chat ids blank if you don't want notifications. From 79082e8fc150ddb284df5b85fe1c0ef55df49ada Mon Sep 17 00:00:00 2001 From: kx9x Date: Sun, 24 Apr 2022 10:22:43 -0700 Subject: [PATCH 36/83] chore: bump workflows version --- .github/workflows/run-command.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-command.yml b/.github/workflows/run-command.yml index 641954d..34287b3 100644 --- a/.github/workflows/run-command.yml +++ b/.github/workflows/run-command.yml @@ -32,7 +32,7 @@ on: jobs: dispatchCommand: - uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.0.20 + uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.0.24 with: ref: ${{ github.event.inputs.ref }} comment-id: ${{ github.event.inputs.comment-id }} From 7670fdcd519ff6ee5afe90f1570802184ef54bc6 Mon Sep 17 00:00:00 2001 From: kx9x Date: Sun, 24 Apr 2022 10:23:03 -0700 Subject: [PATCH 37/83] chore: bump multisig-ci version --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index f23c06a..de49ede 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -7,4 +7,4 @@ regex==2021.10.8 tomli==1.2.1 tenacity==8.0.1 psutil==5.8.0 -multisig-ci==0.0.3 \ No newline at end of file +multisig-ci==0.0.7 From 8567ad80c72307ff59ecb5d689dc7078851016cf Mon Sep 17 00:00:00 2001 From: kx9x Date: Sun, 24 Apr 2022 10:24:07 -0700 Subject: [PATCH 38/83] chore: update error messaging --- .github/workflows/slash-command.yml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/slash-command.yml b/.github/workflows/slash-command.yml index 4da72f5..65103e4 100644 --- a/.github/workflows/slash-command.yml +++ b/.github/workflows/slash-command.yml @@ -29,6 +29,7 @@ jobs: - name: Slash Command Dispatch uses: peter-evans/slash-command-dispatch@v2 + id: scd with: dispatch-type: workflow token: ${{ secrets.PAT }} @@ -46,5 +47,13 @@ jobs: with: comment-id: ${{ github.event.comment.id }} body: | - > command failed, check your syntax - > /run network=[eth|bsc] fn=[valid_brownie_function_name] send=[true|false] delete-branch-after-send=[true|false] + - name: Edit comment with error message + if: failure() || steps.scd.outputs.error-message + uses: peter-evans/create-or-update-comment@v1 + with: + comment-id: ${{ github.event.comment.id }} + body: | + > command failed, first check your syntax + > /robowoofy network=[eth|bsc] fn=[valid_brownie_function_name] send=[true|false] delete-branch-after-send=[true|false] + > If that looks good, make sure you have write access on this repository. + > Also, make sure you are not running this from a repository fork. Robowoofy must be ran from branch on the repo. From 5f13680c51c30b9225d442f51c232df916bb45e9 Mon Sep 17 00:00:00 2001 From: kx9x Date: Sun, 24 Apr 2022 10:24:26 -0700 Subject: [PATCH 39/83] Update slash-command.yml --- .github/workflows/slash-command.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/slash-command.yml b/.github/workflows/slash-command.yml index 65103e4..e0fe31e 100644 --- a/.github/workflows/slash-command.yml +++ b/.github/workflows/slash-command.yml @@ -41,12 +41,6 @@ jobs: ref=${{ fromJSON(steps.get-pr.outputs.result).head.ref }} pull_request_number=${{ github.event.issue.number }} - - name: Edit comment with error message - if: failure() || steps.scd.outputs.error-message - uses: peter-evans/create-or-update-comment@v1 - with: - comment-id: ${{ github.event.comment.id }} - body: | - name: Edit comment with error message if: failure() || steps.scd.outputs.error-message uses: peter-evans/create-or-update-comment@v1 From c4bdcd42651c09ac97fc4e78fb27c7a485f6fcc5 Mon Sep 17 00:00:00 2001 From: kx9x Date: Fri, 2 Sep 2022 11:12:05 -0700 Subject: [PATCH 40/83] Update requirements-dev.txt --- requirements-dev.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index de49ede..47456dc 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,7 +1,7 @@ black==21.9b0 -eth_brownie==1.17 +eth-brownie==1.17 gnosis-py==3.6.0 -ape_safe==0.5.0 +ape-safe==0.5.0 click==8.0.3 regex==2021.10.8 tomli==1.2.1 From 5cfbd68f1d9522344b4577c8d9616d99efa0037a Mon Sep 17 00:00:00 2001 From: kx9x Date: Sat, 10 Sep 2022 15:43:30 -0700 Subject: [PATCH 41/83] Create delegates.py --- scripts/delegates.py | 64 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 scripts/delegates.py diff --git a/scripts/delegates.py b/scripts/delegates.py new file mode 100644 index 0000000..88ff3fc --- /dev/null +++ b/scripts/delegates.py @@ -0,0 +1,64 @@ +from time import time + +import requests +from brownie import * +from brownie.network.account import LocalAccount +from eth_account import Account + +BASE_URL = "https://safe-transaction.gnosis.io/api/v1" + +## Modify values here +# 1. Add your safe +safe = web3.ens.resolve("web.ychad.eth") ## TODO: Replace with your safe address + + +# 2. Add your delegator. This account needs to be a owner of the safe +_delegator = accounts.load('multi-sig-delegator') ## TODO: Load your account + + +# Use the Account from eth_account to make signing hashs easier +delegator = Account.from_key(_delegator.private_key) + + +## You can also use a hardware wallet like Trezor or Ledger with clef. See https://eth-brownie.readthedocs.io/en/stable/account-management.html?highlight=private%20key#using-a-hardware-wallet +# accounts.connect_to_clef("/Users/gazumps/Library/Signer/clef.ipc") +# delegator = accounts[1] + +# 3. Add your delegate +## Create a new throw away account + + +def list_delegates(safe: str): + response = requests.get(f"{BASE_URL}/delegates/", params={"safe": safe}) + print(response.json()["results"]) + + +def make_payload(safe: str, delegate: str, delegator: Account, label: str = None): + message = web3.keccak(text=delegate + str(int(time() // 3600))) + signature = delegator.signHash(message).signature.hex() + return {"safe": safe, "delegate": delegate, "signature": signature, "label": label} + + +def add_delegate(safe: str, delegate: str, delegator: Account, label: str = None): + payload = make_payload(safe, delegate, delegator, label) + response = requests.post(f"{BASE_URL}/safes/{safe}/delegates/", json=payload) + color = "green" if response.ok else "red" + print(f"{response.status_code}: {response.text}") + + +def create_and_add_delegate(): + delegate = Account.create() + add_delegate(safe, delegate.address, delegator, label="Robowoofy") + print("Delegate Address: ", delegate.address) + print("Delegate Private Key: ", delegate.privateKey.hex()) + print() + print("List of Delegates:") + print (list_delegates(safe)) + + +def add_delegate_from_existing_address(address): + add_delegate(safe, address, delegator, label="Robowoofy") + print("Delegate Address: ", address) + print() + print("List of Delegates:") + print (list_delegates(safe)) From 3b249cc32ea513fcc61205ab1bdc0f555e2c4387 Mon Sep 17 00:00:00 2001 From: kx9x Date: Sat, 10 Sep 2022 16:39:02 -0700 Subject: [PATCH 42/83] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f920506..804e42b 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,9 @@ Add these repository secrets. Go to https://github.com/{org}/{repo}/settings/sec 4. PRIVATE_KEY - Private key for your delegate (get this from the previous step where you added your delegate account) ### Config values -Fill in the telegram channel ids in run-command.yml. You can find these ids by opening your chat in telegram web, taking the number from the url, and adding a 100 between the - and the number. For example, -3456789 would become -1003456789. Announcement and group chats allow you to notify 2 seperate channels. Leave telegram chat ids blank if you don't want notifications. +Fill in the telegram channel ids in run-command.yml. + +You can find these ids by opening your chat in telegram web, taking the number from the url, and adding a `100` between the - and the number. For example, `-3456789` would become `-1003456789`. Announcement and group chats allow you to notify 2 seperate channels. Leave telegram chat ids blank if you don't want notifications. Alternatively, you can message @username_to_id_bot on Telegram to find a chat id. From 6654fedb35128e008d27b4d1e8a1f39958eacf9a Mon Sep 17 00:00:00 2001 From: kx9x Date: Sat, 10 Sep 2022 16:39:31 -0700 Subject: [PATCH 43/83] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 804e42b..7cbb265 100644 --- a/README.md +++ b/README.md @@ -31,13 +31,13 @@ Add these repository secrets. Go to https://github.com/{org}/{repo}/settings/sec 4. PRIVATE_KEY - Private key for your delegate (get this from the previous step where you added your delegate account) ### Config values -Fill in the telegram channel ids in run-command.yml. +1. Fill in the telegram channel ids in run-command.yml. -You can find these ids by opening your chat in telegram web, taking the number from the url, and adding a `100` between the - and the number. For example, `-3456789` would become `-1003456789`. Announcement and group chats allow you to notify 2 seperate channels. Leave telegram chat ids blank if you don't want notifications. + You can find these ids by opening your chat in telegram web, taking the number from the url, and adding a `100` between the - and the number. For example, `-3456789` would become `-1003456789`. Announcement and group chats allow you to notify 2 seperate channels. Leave telegram chat ids blank if you don't want notifications. -Alternatively, you can message @username_to_id_bot on Telegram to find a chat id. + Alternatively, you can message @username_to_id_bot on Telegram to find a chat id. -Fill in everything in the .env file. +1. Fill in everything in the .env file. Optional: Fill in scripts/shame.py with a mapping of addresses to signer names for the /shame command. From 07d692f624dd53278447998dd6d119e1c4b59d6e Mon Sep 17 00:00:00 2001 From: kx9x Date: Sat, 10 Sep 2022 16:40:28 -0700 Subject: [PATCH 44/83] Update README.md --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 7cbb265..ce97048 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ You can generate a new delegate using the brownie console. Before you start, mak Modify scripts/delegates.py with your safe and delegator details. -To create and add a new delegate, run `brownie run delegates create_and_add_delegate` +To create and add a new delegate, run `brownie run delegates create_and_add_delegate`. Note: adjust base url if you need to ue a network other than Ethereum. To add an existing account as a delegate, run `brownie run delegates add_delegate_from_existing_address
` @@ -25,10 +25,10 @@ If you want to add a delegate via a UI, you can also use https://gnosis-safe-del ### Secrets Add these repository secrets. Go to https://github.com/{org}/{repo}/settings/secrets/actions -1. PAT - generate personal access token. Go to https://github.com/settings/tokens/new and click repo for scopes. Make sure to reset this secret when the PAT expires. -2. {NETWORK}SCAN_TOKEN - Define multiple secrets where {NETWORK} can be ETHER, FTM, SNOW, BSC, ARBI, or POLYGON. You can generate these tokens by making an account at the respective sites (e.g. etherscan.io, ftmscan.com, etc, etc). If you don't need a token for a given network, then either set the secret to something random or edit run-command.yml to pass in '' for the token you don't need. -3. TELEGRAM_TOKEN - This is the token for your telegram bot that will send messages to channels. To create a bot go to: https://core.telegram.org/bots. If you are in the yearn org, contact kx9x for the robowoofy token. -4. PRIVATE_KEY - Private key for your delegate (get this from the previous step where you added your delegate account) +1. `PAT` - generate personal access token. Go to https://github.com/settings/tokens/new and click repo for scopes. Make sure to reset this secret when the PAT expires. +2. `{NETWORK}SCAN_TOKEN` - Define multiple secrets where {NETWORK} can be ETHER, FTM, SNOW, BSC, ARBI, or POLYGON. You can generate these tokens by making an account at the respective sites (e.g. etherscan.io, ftmscan.com, etc, etc). If you don't need a token for a given network, then either set the secret to something random or edit run-command.yml to pass in '' for the token you don't need. +3. `TELEGRAM_TOKEN` - This is the token for your telegram bot that will send messages to channels. To create a bot go to: https://core.telegram.org/bots. If you are in the yearn org, contact kx9x for the robowoofy token. +4. `PRIVATE_KEY` - Private key for your delegate (get this from the previous step where you added your delegate account) ### Config values 1. Fill in the telegram channel ids in run-command.yml. @@ -37,7 +37,7 @@ Add these repository secrets. Go to https://github.com/{org}/{repo}/settings/sec Alternatively, you can message @username_to_id_bot on Telegram to find a chat id. -1. Fill in everything in the .env file. +1. Fill in everything in the .env file. Leave placeholder values for any safes on networks you don't need. Optional: Fill in scripts/shame.py with a mapping of addresses to signer names for the /shame command. From a9993a774db93e10cef400e00d516f8fa137f901 Mon Sep 17 00:00:00 2001 From: kx9x Date: Sat, 10 Sep 2022 16:54:27 -0700 Subject: [PATCH 45/83] Delete run-help.yml --- .github/workflows/run-help.yml | 33 --------------------------------- 1 file changed, 33 deletions(-) delete mode 100644 .github/workflows/run-help.yml diff --git a/.github/workflows/run-help.yml b/.github/workflows/run-help.yml deleted file mode 100644 index 6369688..0000000 --- a/.github/workflows/run-help.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Multisig-Run help - -on: [pull_request] - -jobs: - runHelp: - runs-on: ubuntu-latest - steps: - - name: Find Comment - uses: peter-evans/find-comment@v1 - id: fc - with: - issue-number: ${{ github.event.pull_request.number }} - comment-author: 'github-actions[bot]' - body-includes: To transmit a multisig tx request - - - name: Create or update comment - uses: peter-evans/create-or-update-comment@v1 - with: - comment-id: ${{ steps.fc.outputs.comment-id }} - issue-number: ${{ github.event.pull_request.number }} - body: | - To transmit a multisig tx request, please run: - `/run file=[main|hydrate_ci_cache] network=[eth|bsc|ftm|matic] fn=[valid_brownie_function_name] send=[true|false] delete-branch-after-send=[true|false]` - - parameters: - **file** - defaults to **main**, so feel free to omit this if working in that file - **network** - defaults to **eth**, so feel free to omit this if working with eth mainnet - **fn** - any function name in the corresponding file for the file chosen (main.py for main, hydrate_ci_cache.py for hydrate_ci_cache) - **send** - defaults to **false**, setting to true will sign the TX with the delegate private key and submit to gnosis. This will also close the PR. - **delete-branch-after-send** - defaults to **true**, set to false to not have your branch deleted after completing a send. - - edit-mode: replace From a233163f44a55651eb29d31e35c5814fc5e6b516 Mon Sep 17 00:00:00 2001 From: kx9x Date: Sat, 10 Sep 2022 16:55:18 -0700 Subject: [PATCH 46/83] Update run-command.yml --- .github/workflows/run-command.yml | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/.github/workflows/run-command.yml b/.github/workflows/run-command.yml index 34287b3..99bac5b 100644 --- a/.github/workflows/run-command.yml +++ b/.github/workflows/run-command.yml @@ -32,7 +32,7 @@ on: jobs: dispatchCommand: - uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.0.24 + uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.2.26 with: ref: ${{ github.event.inputs.ref }} comment-id: ${{ github.event.inputs.comment-id }} @@ -42,19 +42,12 @@ jobs: send: ${{ github.event.inputs.send }} pull_request_number: ${{ github.event.inputs.pull_request_number }} delete-branch-after-send: ${{ github.event.inputs.delete-branch-after-send }} - github_run_id: $GITHUB_RUN_ID - github_repository: $GITHUB_REPOSITORY - github_workspace: $GITHUB_WORKSPACE - runs_on: ubuntu-latest - runner_name: runner - brownie_cache_version: v0.0.1 - compiler_cache_version: v0.0.1 - close_pr: 'true' - check_reviews: false group_telegram_chat_id: '' announcement_telegram_chat_id: '' failure_telegram_chat_id: '' - home_path: /home/runner + runs_on: ubuntu-latest + close_pr: 'true' + check_reviews: false cached_runner: false be: ${{ github.event.inputs.be }} secrets: From 5b5d1f744c963cf8d3f0e3252eb7697164090b13 Mon Sep 17 00:00:00 2001 From: kx9x Date: Sat, 10 Sep 2022 17:06:39 -0700 Subject: [PATCH 47/83] Update requirements-dev.txt --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 47456dc..70f0d25 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -7,4 +7,4 @@ regex==2021.10.8 tomli==1.2.1 tenacity==8.0.1 psutil==5.8.0 -multisig-ci==0.0.7 +multisig-ci==0.3.19 From 415480cbf5d86e19b1485d9d61c4b22d01549cff Mon Sep 17 00:00:00 2001 From: kx9x Date: Sat, 10 Sep 2022 17:07:48 -0700 Subject: [PATCH 48/83] Update network-config.yaml --- network-config.yaml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/network-config.yaml b/network-config.yaml index a8cf85b..0dae35b 100644 --- a/network-config.yaml +++ b/network-config.yaml @@ -40,6 +40,14 @@ live: id: arb-main name: Mainnet explorer: https://api.arbiscan.io/api +- name: Goerli + networks: + - chainid: 5 + host: https://goerli.infura.io/v3/$WEB3_INFURA_PROJECT_ID + id: gor-main + name: Mainnet + multicall2: '0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696' + explorer: https://api-goerli.etherscan.io/api development: - cmd: ganache-cli @@ -113,3 +121,14 @@ development: host: http://127.0.0.1 id: arb-main-fork name: Ganache-CLI (ARBITRUMONE-Mainnet Fork) +- cmd: ganache-cli + cmd_settings: + accounts: 10 + evm_version: istanbul + fork: gor-main + gas_limit: 12000000 + mnemonic: brownie + port: 8545 + host: http://127.0.0.1 + id: gor-main-fork + name: Ganache-CLI (Goreli-Mainnet Fork) From 99e9c8198035874e7093dd404074b3560372dac0 Mon Sep 17 00:00:00 2001 From: kx9x Date: Sat, 10 Sep 2022 17:12:10 -0700 Subject: [PATCH 49/83] Update README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ce97048..ccd9c9f 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,11 @@ Template repository for automating delegate transactions to [Gnosis Safe](https://gnosis-safe.io/app/) multisig wallets through Github Actions ## Bootstrapping -If you have downloaded this template repository, you need to fill in some config values and add some repository secrets. +NOTE: Please make sure your copy of this repository is private, not public when you use this template! Super important! You don't want randoms queuing TXs to your Gnosis Safe. + +1. Fork [yearn-workflows](https://github.com/yearn/yearn-workflows/fork), this should be public and you don't need to change it. You just need a fork of this because Github runners can only read workflows within the same organization/account. +2. +3. If you have downloaded this template repository, you need to fill in some config values and add some repository secrets. More details below. #### Adding a delegate account Generate a private key for your multisig delegate. Do not use this private key for anything else. We recommend that you just throw it away once you add the secret. Anyone with access to your repo and the actions will be able to take this private key, so don't make any assumptions. From 0fcdbbf1b897792ed5901b940e8564febf5864d3 Mon Sep 17 00:00:00 2001 From: kx9x Date: Sat, 10 Sep 2022 17:16:24 -0700 Subject: [PATCH 50/83] Update .env --- .env | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.env b/.env index 1766c27..9a4aa0a 100644 --- a/.env +++ b/.env @@ -6,4 +6,5 @@ FTM_SAFE_ADDRESS= POLYGON_SAFE_ADDRESS= BSC_SAFE_ADDRESS= RIN_SAFE_ADDRESS= -ARB_SAFE_ADDRESS= \ No newline at end of file +GOR_SAFE_ADDRESS= +ARB_SAFE_ADDRESS= From 23298c98d28d4a5ea012a2f5812224cf3fad6758 Mon Sep 17 00:00:00 2001 From: kx9x Date: Sat, 10 Sep 2022 17:31:18 -0700 Subject: [PATCH 51/83] Update README.md --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ccd9c9f..9812cf9 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,8 @@ Template repository for automating delegate transactions to [Gnosis Safe](https: ## Bootstrapping NOTE: Please make sure your copy of this repository is private, not public when you use this template! Super important! You don't want randoms queuing TXs to your Gnosis Safe. -1. Fork [yearn-workflows](https://github.com/yearn/yearn-workflows/fork), this should be public and you don't need to change it. You just need a fork of this because Github runners can only read workflows within the same organization/account. -2. -3. If you have downloaded this template repository, you need to fill in some config values and add some repository secrets. More details below. +1. Also fork [yearn-workflows](https://github.com/yearn/yearn-workflows/fork), this should be public and you don't need to change it. You just need a fork of this because Github runners can only read workflows within the same organization/account. +2. If you have downloaded this template repository, you need to fill in some config values and add some repository secrets. More details below. #### Adding a delegate account Generate a private key for your multisig delegate. Do not use this private key for anything else. We recommend that you just throw it away once you add the secret. Anyone with access to your repo and the actions will be able to take this private key, so don't make any assumptions. From 51823417856fe577ae735395ba485231482e2df3 Mon Sep 17 00:00:00 2001 From: kx9x Date: Sat, 10 Sep 2022 17:32:10 -0700 Subject: [PATCH 52/83] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9812cf9..cc24387 100644 --- a/README.md +++ b/README.md @@ -19,11 +19,11 @@ You can generate a new delegate using the brownie console. Before you start, mak Modify scripts/delegates.py with your safe and delegator details. -To create and add a new delegate, run `brownie run delegates create_and_add_delegate`. Note: adjust base url if you need to ue a network other than Ethereum. +To create and add a new delegate, run `brownie run delegates create_and_add_delegate`. Note: adjust base url if you need to ue a network other than Ethereum. Also, make note of the private key that is printed for the delegate, you will need that later. To add an existing account as a delegate, run `brownie run delegates add_delegate_from_existing_address
` -If you want to add a delegate via a UI, you can also use https://gnosis-safe-delegate.vercel.app/ +If you want to add a delegate via a UI, you can also use https://gnosis-safe-delegate.vercel.app/. Just create a new throwaway private key for the delegate, you will need it later. ### Secrets Add these repository secrets. Go to https://github.com/{org}/{repo}/settings/secrets/actions From a2aad4e3daa6d04619f3f3de0b19ef3e1c2bda4e Mon Sep 17 00:00:00 2001 From: kx9x Date: Sat, 10 Sep 2022 17:33:46 -0700 Subject: [PATCH 53/83] Update delegates.py --- scripts/delegates.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/delegates.py b/scripts/delegates.py index 88ff3fc..ab7370c 100644 --- a/scripts/delegates.py +++ b/scripts/delegates.py @@ -5,11 +5,12 @@ from brownie.network.account import LocalAccount from eth_account import Account +# BASE_URL = "https://safe-transaction.goerli.gnosis.io/api/vi" <- for goerli BASE_URL = "https://safe-transaction.gnosis.io/api/v1" ## Modify values here # 1. Add your safe -safe = web3.ens.resolve("web.ychad.eth") ## TODO: Replace with your safe address +safe = "" ## TODO: Replace with your safe address # 2. Add your delegator. This account needs to be a owner of the safe From e55db4a2ca51532bd6ed51b28d4326fbe7baef5b Mon Sep 17 00:00:00 2001 From: kx9x Date: Sat, 10 Sep 2022 17:41:25 -0700 Subject: [PATCH 54/83] Update requirements-dev.txt --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 70f0d25..0515dfa 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -7,4 +7,4 @@ regex==2021.10.8 tomli==1.2.1 tenacity==8.0.1 psutil==5.8.0 -multisig-ci==0.3.19 +multisig-ci==0.3.20 From 162579da4b3dee7235ce235757d31f2390d7ac37 Mon Sep 17 00:00:00 2001 From: kx9x Date: Sun, 11 Sep 2022 12:45:03 -0700 Subject: [PATCH 55/83] Create ahhh_im_noncing.py --- scripts/ahhh_im_noncing.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 scripts/ahhh_im_noncing.py diff --git a/scripts/ahhh_im_noncing.py b/scripts/ahhh_im_noncing.py new file mode 100644 index 0000000..e0f34c0 --- /dev/null +++ b/scripts/ahhh_im_noncing.py @@ -0,0 +1,21 @@ +from urllib.parse import urljoin +import requests + +def pending_nonce_override(self) -> int: + """ + Subsequent nonce which accounts for pending transactions in the transaction service. + """ + url = urljoin(self.base_url, f'/api/v1/safes/{self.address}/multisig-transactions/') + results = requests.get(url).json()['results'] + # loop through the TXs return and detect a gap in nonce + # if there is a gap, return a nonce so we fill that gap + i = 1 + while i < len(results): + nonce_after = results[i-1]['nonce'] + nonce_before = results[i]['nonce'] + if abs(nonce_after-nonce_before) > 1: + print(nonce_before + 1) + return nonce_before + 1 + i += 1 + + return results[0]['nonce'] + 1 if results else 0 From 69e2be890380b7cc76d6d4ec20c50e7a65716408 Mon Sep 17 00:00:00 2001 From: kx9x Date: Sun, 11 Sep 2022 12:45:41 -0700 Subject: [PATCH 56/83] add ahhh_im_noncing override to fix nonce issues --- scripts/main.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/main.py b/scripts/main.py index 72229c3..209936c 100644 --- a/scripts/main.py +++ b/scripts/main.py @@ -1,5 +1,7 @@ import multisig_ci.ci_override +from scripts.ahhh_im_noncing import pending_nonce_override from multisig_ci.ci_override import DelegateSafe as ApeSafe +ApeSafe.pending_nonce = pending_nonce_override from multisig_ci.safes import safe from multisig_ci.sign import sign From 7025a812d255a553bfbef3f28f6dee14996a6b85 Mon Sep 17 00:00:00 2001 From: MarcoWorms Date: Fri, 7 Oct 2022 13:24:09 -0300 Subject: [PATCH 57/83] improve copy and add preview image --- README.md | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index cc24387..99001bd 100644 --- a/README.md +++ b/README.md @@ -2,24 +2,28 @@ Template repository for automating delegate transactions to [Gnosis Safe](https://gnosis-safe.io/app/) multisig wallets through Github Actions +Allows for teams to be notified in Telegram when a new transaction is queued for signature in a multisig. Preview output: + +![](https://i.imgur.com/zKTnTY4.png) + ## Bootstrapping -NOTE: Please make sure your copy of this repository is private, not public when you use this template! Super important! You don't want randoms queuing TXs to your Gnosis Safe. +NOTE: Please ensure your copy of this repository is private, not public, when you use this template! Super important! You don't want randoms queuing TXs to your Gnosis Safe. 1. Also fork [yearn-workflows](https://github.com/yearn/yearn-workflows/fork), this should be public and you don't need to change it. You just need a fork of this because Github runners can only read workflows within the same organization/account. -2. If you have downloaded this template repository, you need to fill in some config values and add some repository secrets. More details below. +2. If you have downloaded this template repository, you must fill in some config values and add some repository secrets. (see below for more details on how to do this) #### Adding a delegate account -Generate a private key for your multisig delegate. Do not use this private key for anything else. We recommend that you just throw it away once you add the secret. Anyone with access to your repo and the actions will be able to take this private key, so don't make any assumptions. +Generate a private key for your multisig delegate. Do NOT use this private key for anything else. We recommend you throw it away once you add the secret. Anyone with access to your repo and the actions can take this private key, so don't make any assumptions. Be ready to revoke your delegate if you see any suspicious transactions queued to it. -You must be a owner of the safe to add a delegate to it. +You must be an owner of the safe to add a delegate to it. You can generate a new delegate using the brownie console. Before you start, make sure that you have your safe owner account in brownie: `brownie accounts new multi-sig-delegator` Modify scripts/delegates.py with your safe and delegator details. -To create and add a new delegate, run `brownie run delegates create_and_add_delegate`. Note: adjust base url if you need to ue a network other than Ethereum. Also, make note of the private key that is printed for the delegate, you will need that later. +To create and add a new delegate, run `brownie run delegates create_and_add_delegate`. Note: adjust base url if you need to use a network other than Ethereum. Also, make a note of the private key that is printed for the delegate, you will need that later. To add an existing account as a delegate, run `brownie run delegates add_delegate_from_existing_address
` @@ -28,7 +32,7 @@ If you want to add a delegate via a UI, you can also use https://gnosis-safe-del ### Secrets Add these repository secrets. Go to https://github.com/{org}/{repo}/settings/secrets/actions -1. `PAT` - generate personal access token. Go to https://github.com/settings/tokens/new and click repo for scopes. Make sure to reset this secret when the PAT expires. +1. `PAT` - generate a personal access token. Go to https://github.com/settings/tokens/new and click repo for scopes. Make sure to reset this secret when the PAT expires. 2. `{NETWORK}SCAN_TOKEN` - Define multiple secrets where {NETWORK} can be ETHER, FTM, SNOW, BSC, ARBI, or POLYGON. You can generate these tokens by making an account at the respective sites (e.g. etherscan.io, ftmscan.com, etc, etc). If you don't need a token for a given network, then either set the secret to something random or edit run-command.yml to pass in '' for the token you don't need. 3. `TELEGRAM_TOKEN` - This is the token for your telegram bot that will send messages to channels. To create a bot go to: https://core.telegram.org/bots. If you are in the yearn org, contact kx9x for the robowoofy token. 4. `PRIVATE_KEY` - Private key for your delegate (get this from the previous step where you added your delegate account) @@ -36,7 +40,7 @@ Add these repository secrets. Go to https://github.com/{org}/{repo}/settings/sec ### Config values 1. Fill in the telegram channel ids in run-command.yml. - You can find these ids by opening your chat in telegram web, taking the number from the url, and adding a `100` between the - and the number. For example, `-3456789` would become `-1003456789`. Announcement and group chats allow you to notify 2 seperate channels. Leave telegram chat ids blank if you don't want notifications. + You can find these ids by opening your chat on Telegram web, taking the number from the url, and adding a `100` between the "-" and the number. For example, `-3456789` would become `-1003456789`. Announcements and group chats allow you to notify 2 separate channels. Leave telegram chat ids blank if you don't want notifications. Alternatively, you can message @username_to_id_bot on Telegram to find a chat id. @@ -46,10 +50,10 @@ Optional: Fill in scripts/shame.py with a mapping of addresses to signer names for the /shame command. ## Usage -Follow the process steps below for queuing transaction to your multisig -1. Create script using ape safe syntax -2. Create PR on new branch -3. Add a comment on PR to trigger bot to dry-run the txn: +Follow the process steps below for queuing transactions to your multisig +1. Create a script using ape-safe syntax +2. Create a PR on a new branch +3. Add a comment on PR to trigger the bot to dry-run the txn: ``` /run file=[main|hydrate_ci_cache] fn=[name_of_fxn] network=[eth|bsc|matic|ftm|rin|arb] ``` @@ -62,19 +66,19 @@ Follow the process steps below for queuing transaction to your multisig - 🚀 to indicate script is being run - 🎉 to indicate script is run successfully - Note: main is the default target script and eth is the default network, you can omit both -4. After successful dry run, get a peer review -5. When peer review is complete, they can indicate it by using GitHub runner bot to queue the transaction in Gnosis. This is done by adding same comment as step #3, but this time with "send=true" +4. After a successful dry run, get a peer review +5. When peer review is complete, they can indicate it by using GitHub runner bot to queue the transaction in Gnosis. To do this, add the same comment as step #3 but this time with "send=true" ``` /run file=[main|hydrate_ci_cache] fn=[name_of_fxn] network=[eth|bsc|matic|ftm|rin|arb] send=[true|false] delete-branch-after-send=[true|false] ``` - - delete-branch-after-send defaults to true, if you don't want your branch deleted, then set delete-branch-after-send=false -6. After a successful run with send=true, you can track a Gnosis TX back to its PR and original code by going to https://github.com/yearn/strategist-ms/labels and searching for the nonce number and clicking the matching nonce Github label. + - delete-branch-after-send defaults to true. If you don't want your branch deleted, then set delete-branch-after-send=false +6. After a successful run with send=true, you can track a Gnosis TX back to its PR and original code by going to https://github.com/yearn/strategist-ms/labels and searching for the nonce number, then clicking the matching nonce Github label. ![image](https://user-images.githubusercontent.com/7820952/119859130-f1d67600-bec9-11eb-8ac1-3dbc05956210.png) ## Installation -You need Python 3.8 and pip installed +You need [Python 3.8](https://www.python.org/downloads/release/python-389/) and [pip](https://pip.pypa.io/en/stable/installation/) installed Install dependencies @@ -82,19 +86,19 @@ Install dependencies pip install -r requirements-dev.txt ``` -You need also ganache-cli installed (and Node) +You also need [ganache-cli](https://www.npmjs.com/package/ganache-cli) installed, and [Node.js](https://nodejs.org/en/) ``` npm install -g ganache-cli ``` -Run a multisig tx function on ethereum +Run a multisig tx function on Ethereum ``` brownie run main run_example --network eth-main-fork ``` -Run a multisig tx function on ftm +Run a multisig tx function on FTM ``` brownie run main run_example --network ftm-main-fork @@ -105,7 +109,7 @@ brownie run main run_example --network ftm-main-fork This is important if you want fast runs. 1. In run-command.yml, bump compiler_cache_version by 1 (i.e. v0.0.1 to v0.0.2) -2. Check this change into your master/main branch +2. Check this change in your master/main branch 3. Create a PR from master into a random branch. This is important. Master has to be the base branch for this PR. 4. Comment "/run fn=hydrate_compiler_cache" 5. After this command finishes, you will have all vyper and solc compilers in your cache for each subsequent run. From ef5f2f8eac994bcc4e430c2217ff3bd981a29055 Mon Sep 17 00:00:00 2001 From: kx9x Date: Sat, 4 Mar 2023 13:00:05 -0800 Subject: [PATCH 58/83] Update requirements-dev.txt --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 0515dfa..73f9917 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -7,4 +7,4 @@ regex==2021.10.8 tomli==1.2.1 tenacity==8.0.1 psutil==5.8.0 -multisig-ci==0.3.20 +multisig-ci==0.4.6 From 2478b245b039eb0b8fa567865e8495ea38f9a0b8 Mon Sep 17 00:00:00 2001 From: kx9x Date: Sat, 4 Mar 2023 13:00:41 -0800 Subject: [PATCH 59/83] Update README.md --- README.md | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/README.md b/README.md index 99001bd..a46baac 100644 --- a/README.md +++ b/README.md @@ -103,13 +103,3 @@ Run a multisig tx function on FTM ``` brownie run main run_example --network ftm-main-fork ``` - -## Hydrating the compiler cache - -This is important if you want fast runs. - -1. In run-command.yml, bump compiler_cache_version by 1 (i.e. v0.0.1 to v0.0.2) -2. Check this change in your master/main branch -3. Create a PR from master into a random branch. This is important. Master has to be the base branch for this PR. -4. Comment "/run fn=hydrate_compiler_cache" -5. After this command finishes, you will have all vyper and solc compilers in your cache for each subsequent run. From 1a28ea12cc53c9dc8d72b3b9621dcf94ee2ed49d Mon Sep 17 00:00:00 2001 From: kx9x Date: Wed, 15 Mar 2023 08:43:55 -0700 Subject: [PATCH 60/83] Update network-config.yaml --- network-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network-config.yaml b/network-config.yaml index 0dae35b..2972f1d 100644 --- a/network-config.yaml +++ b/network-config.yaml @@ -30,7 +30,7 @@ live: - name: Rinkeby networks: - chainid: 4 - host: https://rinkeby.infura.io/v3/b795a81f7b664a4494b10fa8d0244776 + host: https://rinkeby.infura.io/v3/$WEB3_INFURA_PROJECT_ID id: rin-main name: Mainnet - name: Arbitrum One From 1b1d3632cd96e64c7422fcd4b63e72327695bc9c Mon Sep 17 00:00:00 2001 From: kx9x Date: Thu, 18 May 2023 12:04:45 -0700 Subject: [PATCH 61/83] Update run-command.yml --- .github/workflows/run-command.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-command.yml b/.github/workflows/run-command.yml index 99bac5b..acb1a43 100644 --- a/.github/workflows/run-command.yml +++ b/.github/workflows/run-command.yml @@ -32,7 +32,7 @@ on: jobs: dispatchCommand: - uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.2.26 + uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.5.1 with: ref: ${{ github.event.inputs.ref }} comment-id: ${{ github.event.inputs.comment-id }} From 60137787b33da25a301f8e08cac2487d98cde3bd Mon Sep 17 00:00:00 2001 From: kx9x Date: Thu, 18 May 2023 17:58:13 -0700 Subject: [PATCH 62/83] Update run-command.yml --- .github/workflows/run-command.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-command.yml b/.github/workflows/run-command.yml index acb1a43..77fab46 100644 --- a/.github/workflows/run-command.yml +++ b/.github/workflows/run-command.yml @@ -32,7 +32,7 @@ on: jobs: dispatchCommand: - uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.5.1 + uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.5.2 with: ref: ${{ github.event.inputs.ref }} comment-id: ${{ github.event.inputs.comment-id }} From e41c85fa88fc6d62f5f4d399f469ac546dfd4ea7 Mon Sep 17 00:00:00 2001 From: dudesahn Date: Wed, 30 Aug 2023 17:26:31 -0400 Subject: [PATCH 63/83] feat: base sms delegate --- scripts/delegates.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/scripts/delegates.py b/scripts/delegates.py index ab7370c..fd1f2c8 100644 --- a/scripts/delegates.py +++ b/scripts/delegates.py @@ -6,7 +6,7 @@ from eth_account import Account # BASE_URL = "https://safe-transaction.goerli.gnosis.io/api/vi" <- for goerli -BASE_URL = "https://safe-transaction.gnosis.io/api/v1" +BASE_URL = "https://safe-transaction-base.safe.global/api/v1" ## Modify values here # 1. Add your safe @@ -37,12 +37,12 @@ def list_delegates(safe: str): def make_payload(safe: str, delegate: str, delegator: Account, label: str = None): message = web3.keccak(text=delegate + str(int(time() // 3600))) signature = delegator.signHash(message).signature.hex() - return {"safe": safe, "delegate": delegate, "signature": signature, "label": label} + return {"safe": safe, "delegate": delegate, "delegator": delegator.address, "signature": signature, "label": label} def add_delegate(safe: str, delegate: str, delegator: Account, label: str = None): payload = make_payload(safe, delegate, delegator, label) - response = requests.post(f"{BASE_URL}/safes/{safe}/delegates/", json=payload) + response = requests.post(f"{BASE_URL}/delegates/", json=payload) color = "green" if response.ok else "red" print(f"{response.status_code}: {response.text}") @@ -60,6 +60,5 @@ def create_and_add_delegate(): def add_delegate_from_existing_address(address): add_delegate(safe, address, delegator, label="Robowoofy") print("Delegate Address: ", address) - print() print("List of Delegates:") print (list_delegates(safe)) From 6c8013eaeac9b91f92ea18afdfc90abffeeb3a6d Mon Sep 17 00:00:00 2001 From: kx9x Date: Sun, 14 Jan 2024 20:22:12 -0800 Subject: [PATCH 64/83] feat: update template to latest robowoofy bits --- .env | 31 ++++-- .github/workflows/run-command.yml | 7 +- .github/workflows/shame-command.yml | 21 ---- .github/workflows/slash-command.yml | 14 ++- .gitignore | 3 +- .python-version | 1 + README.md | 46 ++++++-- network-config.yaml | 159 ++++++++++++++++++++++++---- requirements-dev.txt | 18 ++-- scripts/ahhh_im_noncing.py | 2 +- scripts/main.py | 4 +- scripts/shame.py | 36 ------- 12 files changed, 220 insertions(+), 122 deletions(-) delete mode 100644 .github/workflows/shame-command.yml create mode 100644 .python-version delete mode 100644 scripts/shame.py diff --git a/.env b/.env index 9a4aa0a..ee0226e 100644 --- a/.env +++ b/.env @@ -1,10 +1,21 @@ -WEB3_INFURA_PROJECT_ID= -POLYGON_ALCHEMY_PROJECT_ID= -DELEGATE_ADDRESS= -ETH_SAFE_ADDRESS= -FTM_SAFE_ADDRESS= -POLYGON_SAFE_ADDRESS= -BSC_SAFE_ADDRESS= -RIN_SAFE_ADDRESS= -GOR_SAFE_ADDRESS= -ARB_SAFE_ADDRESS= +# Your Gnosis Safe Delegate Address +DELEGATE_ADDRESS= + +# Infura project id for ETH mainnet, see network-config.yaml +WEB3_INFURA_PROJECT_ID= +# Alchemy project id for Polygon, see network-config.yaml +POLYGON_ALCHEMY_PROJECT_ID= + +# Safe addresses. Please fill for each network you will use. +ETH_SAFE_ADDRESS= +FTM_SAFE_ADDRESS= +POLYGON_SAFE_ADDRESS= +BSC_SAFE_ADDRESS= +GOR_SAFE_ADDRESS= +ARB_SAFE_ADDRESS= +GNOSIS_SAFE_ADDRESS= +OPTI_SAFE_ADDRESS= +BASE_SAFE_ADDRESS= + +# Optional Sentry DSN for crash and performance analytics, sign up at sentry.io. +SENTRY_DSN= \ No newline at end of file diff --git a/.github/workflows/run-command.yml b/.github/workflows/run-command.yml index 77fab46..9ba2ecf 100644 --- a/.github/workflows/run-command.yml +++ b/.github/workflows/run-command.yml @@ -26,13 +26,10 @@ on: delete-branch-after-send: description: 'Set to true to delete the PR branch after running with send=true' default: 'true' - be: - required: false - description: 'backend for gnosis' jobs: dispatchCommand: - uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.5.2 + uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.7.7 with: ref: ${{ github.event.inputs.ref }} comment-id: ${{ github.event.inputs.comment-id }} @@ -49,7 +46,7 @@ jobs: close_pr: 'true' check_reviews: false cached_runner: false - be: ${{ github.event.inputs.be }} + be: gnosis secrets: TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }} FTMSCAN_TOKEN: ${{ secrets.FTMSCAN_TOKEN }} diff --git a/.github/workflows/shame-command.yml b/.github/workflows/shame-command.yml deleted file mode 100644 index d620aca..0000000 --- a/.github/workflows/shame-command.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Shame the signers -on: - workflow_dispatch: - inputs: - comment-id: - description: 'The comment-id of the slash command' - required: true - pull_request_number: - description: 'Set to the pull request number for this command dispatch' - required: false - -jobs: - dispatchCommand: - uses: yearn/yearn-workflows/.github/workflows/shame-workflow.yml@master - with: - ref: ${{ github.event.inputs.ref }} - comment-id: ${{ github.event.inputs.comment-id }} - GITHUB_REPOSITORY: $GITHUB_REPOSITORY - TELEGRAM_CHAT_ID: '' - secrets: - TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }} diff --git a/.github/workflows/slash-command.yml b/.github/workflows/slash-command.yml index e0fe31e..a9ed60d 100644 --- a/.github/workflows/slash-command.yml +++ b/.github/workflows/slash-command.yml @@ -8,7 +8,7 @@ jobs: slashCommandDispatch: runs-on: ubuntu-latest steps: - - uses: actions/github-script@v3 + - uses: actions/github-script@v6.4.1 id: get-pr with: script: | @@ -19,7 +19,7 @@ jobs: } core.info(`Getting PR #${request.pull_number} from ${request.owner}/${request.repo}`) try { - const result = await github.pulls.get(request) + const result = await github.rest.pulls.get(request) return result.data } catch (err) { core.setFailed(`Request failed with error ${err}`) @@ -28,14 +28,12 @@ jobs: - uses: hmarr/debug-action@v2 - name: Slash Command Dispatch - uses: peter-evans/slash-command-dispatch@v2 - id: scd + uses: peter-evans/slash-command-dispatch@v3 with: dispatch-type: workflow token: ${{ secrets.PAT }} commands: | run - shame static-args: | comment-id=${{ github.event.comment.id }} ref=${{ fromJSON(steps.get-pr.outputs.result).head.ref }} @@ -43,11 +41,11 @@ jobs: - name: Edit comment with error message if: failure() || steps.scd.outputs.error-message - uses: peter-evans/create-or-update-comment@v1 + uses: peter-evans/create-or-update-comment@v2.1.1 with: comment-id: ${{ github.event.comment.id }} body: | - > command failed, first check your syntax - > /robowoofy network=[eth|bsc] fn=[valid_brownie_function_name] send=[true|false] delete-branch-after-send=[true|false] + > command failed, check your syntax + > /run network=[eth|base|opti|gc|gor|arb|ftm|matic|bsc] fn=[valid_brownie_function_name] send=[true|false] delete-branch-after-send=[true|false] > If that looks good, make sure you have write access on this repository. > Also, make sure you are not running this from a repository fork. Robowoofy must be ran from branch on the repo. diff --git a/.gitignore b/.gitignore index a374db8..9faaf54 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ __pycache__ build/ reports/ .DS_Store -.venv \ No newline at end of file +.venv +.python_version \ No newline at end of file diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..3236cba --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +template diff --git a/README.md b/README.md index a46baac..ad76c62 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ Follow the process steps below for queuing transactions to your multisig 4. After a successful dry run, get a peer review 5. When peer review is complete, they can indicate it by using GitHub runner bot to queue the transaction in Gnosis. To do this, add the same comment as step #3 but this time with "send=true" ``` - /run file=[main|hydrate_ci_cache] fn=[name_of_fxn] network=[eth|bsc|matic|ftm|rin|arb] send=[true|false] delete-branch-after-send=[true|false] + /run file=[main] fn=[name_of_fxn] network=[eth|bsc|matic|ftm|rin|arb] send=[true|false] delete-branch-after-send=[true|false] ``` - delete-branch-after-send defaults to true. If you don't want your branch deleted, then set delete-branch-after-send=false 6. After a successful run with send=true, you can track a Gnosis TX back to its PR and original code by going to https://github.com/yearn/strategist-ms/labels and searching for the nonce number, then clicking the matching nonce Github label. @@ -78,28 +78,52 @@ Follow the process steps below for queuing transactions to your multisig ## Installation -You need [Python 3.8](https://www.python.org/downloads/release/python-389/) and [pip](https://pip.pypa.io/en/stable/installation/) installed - -Install dependencies +### Run the [pyenv installer](https://github.com/pyenv/pyenv#automatic-installer) ``` -pip install -r requirements-dev.txt +curl https://pyenv.run | bash ``` -You also need [ganache-cli](https://www.npmjs.com/package/ganache-cli) installed, and [Node.js](https://nodejs.org/en/) +### Install python 3.10 +``` +pyenv install 3.10 +``` +### Make a venv ``` -npm install -g ganache-cli +pyenv virtualenv 3.10 ``` -Run a multisig tx function on Ethereum +### Make it automatically activate while in the project folder +``` +pyenv local +``` +### Install deps ``` -brownie run main run_example --network eth-main-fork + pip install -r requirements-dev.txt ``` -Run a multisig tx function on FTM +It's THAT easy! + +### You also need anvil installed +> curl -L https://foundry.paradigm.xyz | bash +> $HOME/.foundry/bin/foundryup +Open a new terminal and make sure Anvil exists +> anvil --help + +### Now install Brownie using [pipx](https://github.com/eth-brownie/brownie#via-pipx) + +``` +python -m pip install --user pipx +python -m pipx ensurepath +pipx install eth-brownie==1.19.2 ``` -brownie run main run_example --network ftm-main-fork + +Open a new terminal. + +Run a multisig tx function on ethereum ``` +brownie run main example -I +``` \ No newline at end of file diff --git a/network-config.yaml b/network-config.yaml index 2972f1d..b7c58d2 100644 --- a/network-config.yaml +++ b/network-config.yaml @@ -1,3 +1,4 @@ +# Note: you are free to use any host or explorer you like, just change them here. live: - name: Ethereum networks: @@ -27,12 +28,6 @@ live: id: ftm-main host: https://rpc.ftm.tools explorer: https://api.ftmscan.com/api -- name: Rinkeby - networks: - - chainid: 4 - host: https://rinkeby.infura.io/v3/$WEB3_INFURA_PROJECT_ID - id: rin-main - name: Mainnet - name: Arbitrum One networks: - chainid: 42161 @@ -48,18 +43,123 @@ live: name: Mainnet multicall2: '0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696' explorer: https://api-goerli.etherscan.io/api +- name: gnosis-chain + networks: + - chainid: 100 + host: https://rpc.gnosischain.com + id: gc-main + name: gnosis-chain + explorer: https://api.gnosisscan.io/api +- name: Optimism + networks: + - chainid: 10 + host: https://rpc.ankr.com/optimism + id: opti-main + name: Mainnet + explorer: https://optimistic.etherscan.io/api +- name: Base + networks: + - chainid: 8453 + host: https://base.llamarpc.com + id: base-main + name: Mainnet + explorer: https://api.basescan.org/api development: +- cmd: anvil + cmd_settings: + accounts: 10 + fork: mainnet + gas_limit: 30000000 + mnemonic: brownie + port: 8545 + host: http://127.0.0.1 + id: eth-main-fork + name: Anvil-CLI (eth-Mainnet Fork) + timeout: 1200 +- cmd: anvil + cmd_settings: + accounts: 10 + fork: bsc-main + gas_limit: 12000000 + mnemonic: brownie + port: 8545 + host: http://127.0.0.1 + id: bsc-main-fork + name: Ganache-CLI (BSC-Mainnet Fork) + timeout: 1200 +- cmd: anvil + cmd_settings: + accounts: 10 + fork: ftm-main + gas_limit: 10000000 + mnemonic: brownie + port: 8545 + host: http://127.0.0.1 + id: ftm-main-fork + name: Anvil-CLI (FTM-Mainnet Fork) + timeout: 1200 +- cmd: anvil + cmd_settings: + accounts: 10 + fork: matic-main + gas_limit: 12000000 + mnemonic: brownie + port: 8545 + host: http://127.0.0.1 + id: matic-main-fork + name: Anvil-CLI (MATIC-Mainnet Fork) + timeout: 1200 +- cmd: anvil + cmd_settings: + accounts: 10 + fork: gor-main + gas_limit: 12000000 + mnemonic: brownie + port: 8545 + host: http://127.0.0.1 + id: gor-main-fork + name: Anvil-CLI (Goreli-Mainnet Fork) +- cmd: anvil + cmd_settings: + accounts: 10 + fork: gc-main + gas_limit: 12000000 + mnemonic: brownie + port: 8545 + host: http://127.0.0.1 + id: gc-main-fork + name: Anvil-CLI (gnosis-chain Fork) +- cmd: anvil + cmd_settings: + accounts: 10 + fork: opti-main + gas_limit: 12000000 + mnemonic: brownie + port: 8545 + host: http://127.0.0.1 + id: opti-main-fork + name: Anvil-CLI (Optimism-Mainnet Fork) +- cmd: anvil + cmd_settings: + accounts: 10 + fork: base-main + gas_limit: 12000000 + mnemonic: brownie + port: 8545 + host: http://127.0.0.1 + id: base-main-fork + name: Anvil-CLI (Base-Mainnet Fork) - cmd: ganache-cli cmd_settings: accounts: 10 evm_version: istanbul fork: mainnet - gas_limit: 12000000 + gas_limit: 30000000 mnemonic: brownie port: 8545 host: http://127.0.0.1 - id: eth-main-fork + id: eth-ganache-main-fork name: Ganache-CLI (eth-Mainnet Fork) timeout: 1200 - cmd: ganache-cli @@ -71,7 +171,7 @@ development: mnemonic: brownie port: 8545 host: http://127.0.0.1 - id: bsc-main-fork + id: bsc-ganache-main-fork name: Ganache-CLI (BSC-Mainnet Fork) timeout: 1200 - cmd: ganache-cli @@ -79,11 +179,11 @@ development: accounts: 10 evm_version: istanbul fork: ftm-main - gas_limit: 8500000 + gas_limit: 10000000 mnemonic: brownie port: 8545 host: http://127.0.0.1 - id: ftm-main-fork + id: ftm-ganache-main-fork name: Ganache-CLI (FTM-Mainnet Fork) timeout: 1200 - cmd: ganache-cli @@ -95,21 +195,20 @@ development: mnemonic: brownie port: 8545 host: http://127.0.0.1 - id: matic-main-fork + id: matic-ganache-main-fork name: Ganache-CLI (MATIC-Mainnet Fork) timeout: 1200 - cmd: ganache-cli cmd_settings: accounts: 10 evm_version: istanbul - fork: rin-main + fork: gor-main gas_limit: 12000000 mnemonic: brownie port: 8545 host: http://127.0.0.1 - id: rin-main-fork - name: Ganache-CLI (RINKEYBY-Mainnet Fork) - timeout: 1200 + id: gor-ganache-main-fork + name: Ganache-CLI (Goreli-Mainnet Fork) - cmd: ganache-cli cmd_settings: accounts: 10 @@ -125,10 +224,32 @@ development: cmd_settings: accounts: 10 evm_version: istanbul - fork: gor-main + fork: gc-main gas_limit: 12000000 mnemonic: brownie port: 8545 host: http://127.0.0.1 - id: gor-main-fork - name: Ganache-CLI (Goreli-Mainnet Fork) + id: gc-ganache-main-fork + name: Ganache-CLI (gnosis-chain Fork) +- cmd: ganache-cli + cmd_settings: + accounts: 10 + evm_version: istanbul + fork: opti-main + gas_limit: 12000000 + mnemonic: brownie + port: 8545 + host: http://127.0.0.1 + id: opti-ganache-main-fork + name: Ganache-CLI (Optimism-Mainnet Fork) +- cmd: ganache-cli + cmd_settings: + accounts: 10 + evm_version: istanbul + fork: base-main + gas_limit: 12000000 + mnemonic: brownie + port: 8545 + host: http://127.0.0.1 + id: base-ganache-main-fork + name: Ganache-CLI (Base-Mainnet Fork) diff --git a/requirements-dev.txt b/requirements-dev.txt index 73f9917..93ff46e 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,10 +1,12 @@ -black==21.9b0 -eth-brownie==1.17 -gnosis-py==3.6.0 -ape-safe==0.5.0 -click==8.0.3 +cython<3.0 +pyyaml>=5.4.1,<6 +eth-brownie==1.19.2 +black==22.10.0 +click==8.1.3 regex==2021.10.8 -tomli==1.2.1 +tomli==2.0.1 tenacity==8.0.1 -psutil==5.8.0 -multisig-ci==0.4.6 +psutil>=5.9.2 +multisig-ci==0.8.9 +tokenlists==0.1.1 +sentry-sdk==1.39.1 \ No newline at end of file diff --git a/scripts/ahhh_im_noncing.py b/scripts/ahhh_im_noncing.py index e0f34c0..d781a15 100644 --- a/scripts/ahhh_im_noncing.py +++ b/scripts/ahhh_im_noncing.py @@ -5,7 +5,7 @@ def pending_nonce_override(self) -> int: """ Subsequent nonce which accounts for pending transactions in the transaction service. """ - url = urljoin(self.base_url, f'/api/v1/safes/{self.address}/multisig-transactions/') + url = urljoin(self.transaction_service.base_url, f'/api/v1/safes/{self.address}/multisig-transactions/') results = requests.get(url).json()['results'] # loop through the TXs return and detect a gap in nonce # if there is a gap, return a nonce so we fill that gap diff --git a/scripts/main.py b/scripts/main.py index 209936c..4cae65a 100644 --- a/scripts/main.py +++ b/scripts/main.py @@ -7,10 +7,10 @@ @sign -def run_example(): +def example(): safe.account.transfer(safe.account, "0 ether") @sign(420) -def run_override_nonce_example(): +def override_nonce_example(): safe.account.transfer(safe.account, "0 ether") diff --git a/scripts/shame.py b/scripts/shame.py deleted file mode 100644 index 15c78dc..0000000 --- a/scripts/shame.py +++ /dev/null @@ -1,36 +0,0 @@ -from brownie import * -from multisig_ci.safes import safe -import requests -from contextlib import redirect_stdout -import os - - -SIGNERS = { - # Map address to name for each signer - #"0xdeadbeefdeadbeefdeadbeefdeadbeef": "Hard Rock Nick", -} - - -def ci_alert(): - home_directory = os.environ.get("HOME") - with open(os.path.join(home_directory, "alert.txt"), "w+") as f: - with redirect_stdout(f): - main() - - -def main(): - url = f"https://safe-transaction.mainnet.gnosis.io/api/v1/safes/{safe}/transactions/" - data = requests.get(url).json() - nonce = safe.retrieve_nonce() - pending = [tx for tx in data["results"][::-1] if not tx["isExecuted"] and tx["nonce"] >= nonce] - - if len(pending) > 4: - print( - "Okay, Okay, Okay. I need the signatures to go up. I can't take this anymore. Everyday I'm checking the signatures and it's dipping. Everyday I check the signatures, bad signatures. I can't take this anymore man. I have over-delegated, by A LOT. It is what it is but I need the signatures to go up. Can signers do something?\n" - ) - - print(f"pls sign https://gnosis-safe.io/app/eth:{safe}/transactions/queue") - for tx in pending: - unsigned = set(SIGNERS) - {x["owner"] for x in tx["confirmations"]} - users = " ".join(f"@{SIGNERS[x]}" for x in unsigned) - print(f'{tx["nonce"]}: {users}') From d673cbc185cecd852c774e2a16a8e249343c6d74 Mon Sep 17 00:00:00 2001 From: kx9x Date: Sun, 14 Jan 2024 21:28:37 -0800 Subject: [PATCH 65/83] fix up readme and scripts --- README.md | 35 ++++++++++++++++++++--------------- scripts/delegates.py | 15 +++++++++------ 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index ad76c62..31aaf83 100644 --- a/README.md +++ b/README.md @@ -13,22 +13,27 @@ NOTE: Please ensure your copy of this repository is private, not public, when yo 2. If you have downloaded this template repository, you must fill in some config values and add some repository secrets. (see below for more details on how to do this) #### Adding a delegate account -Generate a private key for your multisig delegate. Do NOT use this private key for anything else. We recommend you throw it away once you add the secret. Anyone with access to your repo and the actions can take this private key, so don't make any assumptions. - -Be ready to revoke your delegate if you see any suspicious transactions queued to it. - -You must be an owner of the safe to add a delegate to it. - -You can generate a new delegate using the brownie console. Before you start, make sure that you have your safe owner account in brownie: `brownie accounts new multi-sig-delegator` - -Modify scripts/delegates.py with your safe and delegator details. - -To create and add a new delegate, run `brownie run delegates create_and_add_delegate`. Note: adjust base url if you need to use a network other than Ethereum. Also, make a note of the private key that is printed for the delegate, you will need that later. - -To add an existing account as a delegate, run `brownie run delegates add_delegate_from_existing_address
` - -If you want to add a delegate via a UI, you can also use https://gnosis-safe-delegate.vercel.app/. Just create a new throwaway private key for the delegate, you will need it later. +1. Create a new delegate account via brownie + - `brownie accounts generate multi-sig-delegate` + - Get the private key and save it for later: + ``` + brownie console + ``` + ``` + delegate = accounts.load('multi-sig-delegate') + print("Address: ", delegate.address) + print("Private Key: ", delegate.private_key) + ``` + Note: Do NOT use this private key for anything else. We recommend you throw it away once you add the secret. Anyone with access to your repo and the actions can take this private key, so don't make any assumptions. Be ready to revoke your delegate if you see any suspicious transactions queued to it. + +2. Authorize your new delegate on your safe. You must do this via an account that is a safe owner or signer. + - You add delegates via a UI such as https://gnosis-safe-delegate.vercel.app/ + - Alternatively, you can import your safe owner into brownie and run a script to add the delegate: + - run `brownie accounts new multi-sig-delegator` to import your safe owner account + - open [delegates.py](scripts/delegates.py) and add in your safe address for the `safe` variable and also change the + `brownie run delegates add_delegate_from_existing_address --network -main`. Replace `` with the short name for a network, e.g. eth, opti, ftm, arb, gor, etc. + ### Secrets Add these repository secrets. Go to https://github.com/{org}/{repo}/settings/secrets/actions diff --git a/scripts/delegates.py b/scripts/delegates.py index fd1f2c8..05fbc6b 100644 --- a/scripts/delegates.py +++ b/scripts/delegates.py @@ -4,19 +4,22 @@ from brownie import * from brownie.network.account import LocalAccount from eth_account import Account +from brownie_safe import TransactionServiceBackport, EthereumNetworkBackport +from gnosis.eth import EthereumClient, EthereumNetwork -# BASE_URL = "https://safe-transaction.goerli.gnosis.io/api/vi" <- for goerli -BASE_URL = "https://safe-transaction-base.safe.global/api/v1" +ethereum_client = EthereumClient(web3.provider.endpoint_uri) +transaction_service = TransactionServiceBackport(ethereum_client.get_network(), ethereum_client, None) +BASE_URL = transaction_service.base_url + "/api/v1/" +print("BASE_URL is ", BASE_URL, "\n") +assert BASE_URL ## Modify values here # 1. Add your safe -safe = "" ## TODO: Replace with your safe address - +safe = input(f"Please enter your safe address for network {ethereum_client.get_network()}:\n") # 2. Add your delegator. This account needs to be a owner of the safe _delegator = accounts.load('multi-sig-delegator') ## TODO: Load your account - # Use the Account from eth_account to make signing hashs easier delegator = Account.from_key(_delegator.private_key) @@ -43,7 +46,6 @@ def make_payload(safe: str, delegate: str, delegator: Account, label: str = None def add_delegate(safe: str, delegate: str, delegator: Account, label: str = None): payload = make_payload(safe, delegate, delegator, label) response = requests.post(f"{BASE_URL}/delegates/", json=payload) - color = "green" if response.ok else "red" print(f"{response.status_code}: {response.text}") @@ -62,3 +64,4 @@ def add_delegate_from_existing_address(address): print("Delegate Address: ", address) print("List of Delegates:") print (list_delegates(safe)) + From 00ccd988205455605b91726ce7dd7dc862326594 Mon Sep 17 00:00:00 2001 From: kx9x Date: Sun, 14 Jan 2024 21:43:22 -0800 Subject: [PATCH 66/83] fix readme --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 31aaf83..2a0bd96 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,9 @@ Allows for teams to be notified in Telegram when a new transaction is queued for ## Bootstrapping NOTE: Please ensure your copy of this repository is private, not public, when you use this template! Super important! You don't want randoms queuing TXs to your Gnosis Safe. -1. Also fork [yearn-workflows](https://github.com/yearn/yearn-workflows/fork), this should be public and you don't need to change it. You just need a fork of this because Github runners can only read workflows within the same organization/account. -2. If you have downloaded this template repository, you must fill in some config values and add some repository secrets. (see below for more details on how to do this) +1. Set your workflow permissions to "Read and write permissions" under https://github.com///settings/actions +2. Also fork [yearn-workflows](https://github.com/yearn/yearn-workflows/fork), this should be public and you don't need to change it. You just need a fork of this because Github runners can only read workflows within the same organization/account. +3. If you have downloaded this template repository, you must fill in some config values and add some repository secrets. (see below for more details on how to do this) #### Adding a delegate account From ce2af6596f7803791785211ed1130e9961fda15c Mon Sep 17 00:00:00 2001 From: kx9x Date: Sun, 14 Jan 2024 22:45:39 -0800 Subject: [PATCH 67/83] Update README.md --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2a0bd96..ca3ec99 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Allows for teams to be notified in Telegram when a new transaction is queued for ## Bootstrapping NOTE: Please ensure your copy of this repository is private, not public, when you use this template! Super important! You don't want randoms queuing TXs to your Gnosis Safe. -1. Set your workflow permissions to "Read and write permissions" under https://github.com///settings/actions +1. Set your workflow permissions to "Read and write permissions" under https://github.com/{org}/{repo}/settings/actions. Note: replace {org} and {repo} with your information. 2. Also fork [yearn-workflows](https://github.com/yearn/yearn-workflows/fork), this should be public and you don't need to change it. You just need a fork of this because Github runners can only read workflows within the same organization/account. 3. If you have downloaded this template repository, you must fill in some config values and add some repository secrets. (see below for more details on how to do this) @@ -30,13 +30,14 @@ NOTE: Please ensure your copy of this repository is private, not public, when yo 2. Authorize your new delegate on your safe. You must do this via an account that is a safe owner or signer. - You add delegates via a UI such as https://gnosis-safe-delegate.vercel.app/ - - Alternatively, you can import your safe owner into brownie and run a script to add the delegate: + - Alternatively, if the UI doesn't work, you can import your safe owner into brownie and run a script to add the delegate: + - Follow the steps under [Installation](##Installation) to setup this repo for running scripts locally - run `brownie accounts new multi-sig-delegator` to import your safe owner account - open [delegates.py](scripts/delegates.py) and add in your safe address for the `safe` variable and also change the `brownie run delegates add_delegate_from_existing_address --network -main`. Replace `` with the short name for a network, e.g. eth, opti, ftm, arb, gor, etc. ### Secrets -Add these repository secrets. Go to https://github.com/{org}/{repo}/settings/secrets/actions +Add these repository secrets. Go to https://github.com/{org}/{repo}/settings/secrets/actions. Note: replace {org} and {repo} with your information. 1. `PAT` - generate a personal access token. Go to https://github.com/settings/tokens/new and click repo for scopes. Make sure to reset this secret when the PAT expires. 2. `{NETWORK}SCAN_TOKEN` - Define multiple secrets where {NETWORK} can be ETHER, FTM, SNOW, BSC, ARBI, or POLYGON. You can generate these tokens by making an account at the respective sites (e.g. etherscan.io, ftmscan.com, etc, etc). If you don't need a token for a given network, then either set the secret to something random or edit run-command.yml to pass in '' for the token you don't need. @@ -132,4 +133,4 @@ Open a new terminal. Run a multisig tx function on ethereum ``` brownie run main example -I -``` \ No newline at end of file +``` From 9fced2dd541a3d6f174a90844bfbda4e5c4c1bcb Mon Sep 17 00:00:00 2001 From: kx9x Date: Sun, 14 Jan 2024 22:45:48 -0800 Subject: [PATCH 68/83] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ca3ec99..502c554 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ NOTE: Please ensure your copy of this repository is private, not public, when yo 2. Authorize your new delegate on your safe. You must do this via an account that is a safe owner or signer. - You add delegates via a UI such as https://gnosis-safe-delegate.vercel.app/ - Alternatively, if the UI doesn't work, you can import your safe owner into brownie and run a script to add the delegate: - - Follow the steps under [Installation](##Installation) to setup this repo for running scripts locally + - Follow the steps under [Installation](#Installation) to setup this repo for running scripts locally - run `brownie accounts new multi-sig-delegator` to import your safe owner account - open [delegates.py](scripts/delegates.py) and add in your safe address for the `safe` variable and also change the `brownie run delegates add_delegate_from_existing_address --network -main`. Replace `` with the short name for a network, e.g. eth, opti, ftm, arb, gor, etc. From 16995f64c5c337ac55e78b51737b89b3074f089d Mon Sep 17 00:00:00 2001 From: kx9x Date: Sun, 14 Jan 2024 22:47:13 -0800 Subject: [PATCH 69/83] Update README.md --- README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/README.md b/README.md index 502c554..8279c9f 100644 --- a/README.md +++ b/README.md @@ -51,10 +51,7 @@ Add these repository secrets. Go to https://github.com/{org}/{repo}/settings/sec Alternatively, you can message @username_to_id_bot on Telegram to find a chat id. -1. Fill in everything in the .env file. Leave placeholder values for any safes on networks you don't need. - -Optional: -Fill in scripts/shame.py with a mapping of addresses to signer names for the /shame command. +1. Fill in values in the .env file. For any safes on networks you don't need, feel free to leave those blank. Some fields are marked optional. ## Usage Follow the process steps below for queuing transactions to your multisig From f3f125d2c450a485c6ec0507211b3e430c5ec0b7 Mon Sep 17 00:00:00 2001 From: kx9x Date: Sun, 14 Jan 2024 22:49:44 -0800 Subject: [PATCH 70/83] Update README.md --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8279c9f..39bdc49 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,12 @@ Allows for teams to be notified in Telegram when a new transaction is queued for ## Bootstrapping NOTE: Please ensure your copy of this repository is private, not public, when you use this template! Super important! You don't want randoms queuing TXs to your Gnosis Safe. -1. Set your workflow permissions to "Read and write permissions" under https://github.com/{org}/{repo}/settings/actions. Note: replace {org} and {repo} with your information. -2. Also fork [yearn-workflows](https://github.com/yearn/yearn-workflows/fork), this should be public and you don't need to change it. You just need a fork of this because Github runners can only read workflows within the same organization/account. -3. If you have downloaded this template repository, you must fill in some config values and add some repository secrets. (see below for more details on how to do this) +1. Set your workflow permissions to `Read and write permissions` and your actions permissions to `Allow all actions and reusable workflows` under https://github.com/{org}/{repo}/settings/actions. Note: replace {org} and {repo} with your information. +![image](https://github.com/yearn/yearn-multisig-actions/assets/7820952/2a945da1-31be-497b-817f-0149356eaa49) +![image](https://github.com/yearn/yearn-multisig-actions/assets/7820952/67292dc2-dc02-49d7-80fa-083b6d869552) + +3. Also fork [yearn-workflows](https://github.com/yearn/yearn-workflows/fork), this should be public and you don't need to change it. You just need a fork of this because Github runners can only read workflows within the same organization/account. +4. If you have downloaded this template repository, you must fill in some config values and add some repository secrets. (see below for more details on how to do this) #### Adding a delegate account From 34c47f11de143b0440b1e7532409467442b348be Mon Sep 17 00:00:00 2001 From: kx9x Date: Mon, 15 Jan 2024 09:58:16 -0800 Subject: [PATCH 71/83] Update run-command.yml --- .github/workflows/run-command.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-command.yml b/.github/workflows/run-command.yml index 9ba2ecf..5ecc262 100644 --- a/.github/workflows/run-command.yml +++ b/.github/workflows/run-command.yml @@ -29,7 +29,7 @@ on: jobs: dispatchCommand: - uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.7.7 + uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.9.1 with: ref: ${{ github.event.inputs.ref }} comment-id: ${{ github.event.inputs.comment-id }} From b7ebb50f9e3de581a4e9688b54d8d00dc521cc2d Mon Sep 17 00:00:00 2001 From: kx9x Date: Mon, 15 Jan 2024 10:01:01 -0800 Subject: [PATCH 72/83] Update requirements-dev.txt --- requirements-dev.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 93ff46e..54b85f5 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -7,6 +7,6 @@ regex==2021.10.8 tomli==2.0.1 tenacity==8.0.1 psutil>=5.9.2 -multisig-ci==0.8.9 +multisig-ci==0.8.13 tokenlists==0.1.1 -sentry-sdk==1.39.1 \ No newline at end of file +sentry-sdk==1.39.1 From 3a30ab5e1a810b156d392ddbc7ea0a93ef77b138 Mon Sep 17 00:00:00 2001 From: kx9x Date: Mon, 15 Jan 2024 11:00:35 -0800 Subject: [PATCH 73/83] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 39bdc49..54c864d 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ NOTE: Please ensure your copy of this repository is private, not public, when yo ### Secrets Add these repository secrets. Go to https://github.com/{org}/{repo}/settings/secrets/actions. Note: replace {org} and {repo} with your information. -1. `PAT` - generate a personal access token. Go to https://github.com/settings/tokens/new and click repo for scopes. Make sure to reset this secret when the PAT expires. +1. `PAT` - generate a personal access token. Go to https://github.com/settings/tokens/new and click repo for scopes. Make sure to reset this secret when the PAT expires. Note: if you are in the Yearn org, ask @kx9x for a PAT from the Robowoofy Github accout instead of using your own. 2. `{NETWORK}SCAN_TOKEN` - Define multiple secrets where {NETWORK} can be ETHER, FTM, SNOW, BSC, ARBI, or POLYGON. You can generate these tokens by making an account at the respective sites (e.g. etherscan.io, ftmscan.com, etc, etc). If you don't need a token for a given network, then either set the secret to something random or edit run-command.yml to pass in '' for the token you don't need. 3. `TELEGRAM_TOKEN` - This is the token for your telegram bot that will send messages to channels. To create a bot go to: https://core.telegram.org/bots. If you are in the yearn org, contact kx9x for the robowoofy token. 4. `PRIVATE_KEY` - Private key for your delegate (get this from the previous step where you added your delegate account) From 5a9988756f7a225eb2927c7dab9ca5a0a1a48a02 Mon Sep 17 00:00:00 2001 From: kx9x Date: Thu, 25 Apr 2024 07:49:50 -0700 Subject: [PATCH 74/83] Update run-command.yml --- .github/workflows/run-command.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-command.yml b/.github/workflows/run-command.yml index 5ecc262..005ed90 100644 --- a/.github/workflows/run-command.yml +++ b/.github/workflows/run-command.yml @@ -29,7 +29,7 @@ on: jobs: dispatchCommand: - uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.9.1 + uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@8e9241742db1558c842567fa4cf08edc65f054e5 with: ref: ${{ github.event.inputs.ref }} comment-id: ${{ github.event.inputs.comment-id }} From 3c2d575942a4204323fe495f1f9b28273b111229 Mon Sep 17 00:00:00 2001 From: kx9x Date: Thu, 25 Apr 2024 07:51:43 -0700 Subject: [PATCH 75/83] Update README.md --- README.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 54c864d..2c1e1ce 100644 --- a/README.md +++ b/README.md @@ -113,12 +113,16 @@ pyenv local It's THAT easy! -### You also need anvil installed -> curl -L https://foundry.paradigm.xyz | bash -> $HOME/.foundry/bin/foundryup +### You also need anvil installed (using a specific version as of 04/25/2024 due to a bug in foundry) +``` + curl -L https://foundry.paradigm.xyz | bash + $HOME/.foundry/bin/foundryup --version nightly-f625d0fa7c51e65b4bf1e8f7931cd1c6e2e285e9 +``` Open a new terminal and make sure Anvil exists -> anvil --help +``` +anvil --help +``` ### Now install Brownie using [pipx](https://github.com/eth-brownie/brownie#via-pipx) From b4c61d5174b01c19026d10c06977ee649b658696 Mon Sep 17 00:00:00 2001 From: kx9x Date: Thu, 25 Apr 2024 07:55:22 -0700 Subject: [PATCH 76/83] fix: robowoofy v0.9.8 to pin foundry version --- .github/workflows/run-command.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-command.yml b/.github/workflows/run-command.yml index 005ed90..ce66cf8 100644 --- a/.github/workflows/run-command.yml +++ b/.github/workflows/run-command.yml @@ -29,7 +29,7 @@ on: jobs: dispatchCommand: - uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@8e9241742db1558c842567fa4cf08edc65f054e5 + uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.9.8 with: ref: ${{ github.event.inputs.ref }} comment-id: ${{ github.event.inputs.comment-id }} From 14081e0d53574c71a582793b4e28929dfafe5cca Mon Sep 17 00:00:00 2001 From: kx9x Date: Sun, 16 Jun 2024 12:47:24 -0700 Subject: [PATCH 77/83] Update run-command.yml --- .github/workflows/run-command.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/run-command.yml b/.github/workflows/run-command.yml index ce66cf8..ddc07c3 100644 --- a/.github/workflows/run-command.yml +++ b/.github/workflows/run-command.yml @@ -29,7 +29,7 @@ on: jobs: dispatchCommand: - uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.9.8 + uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.9.9 with: ref: ${{ github.event.inputs.ref }} comment-id: ${{ github.event.inputs.comment-id }} @@ -48,12 +48,14 @@ jobs: cached_runner: false be: gnosis secrets: - TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }} + BASESCAN_TOKEN: ${{ secrets.BASESCAN_TOKEN }} FTMSCAN_TOKEN: ${{ secrets.FTMSCAN_TOKEN }} ETHERSCAN_TOKEN: ${{ secrets.ETHERSCAN_TOKEN }} POLYGONSCAN_TOKEN: ${{ secrets.POLYGONSCAN_TOKEN }} - BSCSCAN_TOKEN: ${{ secrets.POLYGONSCAN_TOKEN }} + OPTISCAN_TOKEN: ${{ secrets.OPTISCAN_TOKEN }} + BSCSCAN_TOKEN: ${{ secrets.BSCSCAN_TOKEN }} ARBISCAN_TOKEN: ${{ secrets.ARBISCAN_TOKEN }} SNOWTRACE_TOKEN: ${{ secrets.SNOWTRACE_TOKEN }} PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }} PAT: ${{ secrets.PAT }} + TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }} From a4ab38d2de550fcf99062ca431f54fdfea90b9d6 Mon Sep 17 00:00:00 2001 From: kx9x Date: Sun, 16 Jun 2024 12:48:44 -0700 Subject: [PATCH 78/83] Update network-config.yaml --- network-config.yaml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/network-config.yaml b/network-config.yaml index b7c58d2..448d40a 100644 --- a/network-config.yaml +++ b/network-config.yaml @@ -150,6 +150,17 @@ development: host: http://127.0.0.1 id: base-main-fork name: Anvil-CLI (Base-Mainnet Fork) +- cmd: anvil + cmd_settings: + accounts: 10 + evm_version: istanbul + fork: arb-main + gas_limit: 12000000 + mnemonic: brownie + port: 8545 + host: http://127.0.0.1 + id: arb-main-fork + name: Ganache-CLI (ARBITRUMONE-Mainnet Fork) - cmd: ganache-cli cmd_settings: accounts: 10 @@ -218,7 +229,7 @@ development: mnemonic: brownie port: 8545 host: http://127.0.0.1 - id: arb-main-fork + id: arb-ganache-main-fork name: Ganache-CLI (ARBITRUMONE-Mainnet Fork) - cmd: ganache-cli cmd_settings: From da0a829b19aae2c9ca47facba1aaa3034c253e23 Mon Sep 17 00:00:00 2001 From: kx9x Date: Sun, 16 Jun 2024 14:01:11 -0700 Subject: [PATCH 79/83] fix for base --- scripts/delegates.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/delegates.py b/scripts/delegates.py index 05fbc6b..3923d14 100644 --- a/scripts/delegates.py +++ b/scripts/delegates.py @@ -7,8 +7,14 @@ from brownie_safe import TransactionServiceBackport, EthereumNetworkBackport from gnosis.eth import EthereumClient, EthereumNetwork +BASE_CHAIN_ID = 8453 + +if network.chain.id == BASE_CHAIN_ID: + base_url = "https://safe-transaction-base.safe.global" + ethereum_client = EthereumClient(web3.provider.endpoint_uri) -transaction_service = TransactionServiceBackport(ethereum_client.get_network(), ethereum_client, None) +transaction_service = TransactionServiceBackport(ethereum_client.get_network(), ethereum_client, base_url) + BASE_URL = transaction_service.base_url + "/api/v1/" print("BASE_URL is ", BASE_URL, "\n") assert BASE_URL From 5d1c2400bbe7b283d5fb55701d1ab8eba41702bd Mon Sep 17 00:00:00 2001 From: kx9x Date: Sun, 16 Jun 2024 17:04:18 -0700 Subject: [PATCH 80/83] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2c1e1ce..5e2f4e3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# yearn-multisig-actions +I'm# yearn-multisig-actions Template repository for automating delegate transactions to [Gnosis Safe](https://gnosis-safe.io/app/) multisig wallets through Github Actions @@ -113,10 +113,10 @@ pyenv local It's THAT easy! -### You also need anvil installed (using a specific version as of 04/25/2024 due to a bug in foundry) +### You also need anvil installed ``` curl -L https://foundry.paradigm.xyz | bash - $HOME/.foundry/bin/foundryup --version nightly-f625d0fa7c51e65b4bf1e8f7931cd1c6e2e285e9 + $HOME/.foundry/bin/foundryup ``` Open a new terminal and make sure Anvil exists From 3e609a503775052f25e6355dc86c612604601931 Mon Sep 17 00:00:00 2001 From: kx9x Date: Wed, 19 Jun 2024 14:51:55 -0700 Subject: [PATCH 81/83] fix: upgrade safe brownie --- .github/workflows/run-command.yml | 2 +- .github/workflows/slash-command.yml | 2 +- .gitignore | 3 +- README.md | 4 +- network-config.yaml | 61 ++++------------------------- requirements-dev.txt | 12 +++--- 6 files changed, 20 insertions(+), 64 deletions(-) diff --git a/.github/workflows/run-command.yml b/.github/workflows/run-command.yml index ddc07c3..e52f450 100644 --- a/.github/workflows/run-command.yml +++ b/.github/workflows/run-command.yml @@ -29,7 +29,7 @@ on: jobs: dispatchCommand: - uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.9.9 + uses: yearn/yearn-workflows/.github/workflows/roboanimals-workflow.yml@v0.10.0 with: ref: ${{ github.event.inputs.ref }} comment-id: ${{ github.event.inputs.comment-id }} diff --git a/.github/workflows/slash-command.yml b/.github/workflows/slash-command.yml index a9ed60d..dd05046 100644 --- a/.github/workflows/slash-command.yml +++ b/.github/workflows/slash-command.yml @@ -46,6 +46,6 @@ jobs: comment-id: ${{ github.event.comment.id }} body: | > command failed, check your syntax - > /run network=[eth|base|opti|gc|gor|arb|ftm|matic|bsc] fn=[valid_brownie_function_name] send=[true|false] delete-branch-after-send=[true|false] + > /run network=[eth|base|opti|gc|arb|ftm|matic|bsc] fn=[valid_brownie_function_name] send=[true|false] delete-branch-after-send=[true|false] > If that looks good, make sure you have write access on this repository. > Also, make sure you are not running this from a repository fork. Robowoofy must be ran from branch on the repo. diff --git a/.gitignore b/.gitignore index 9faaf54..1ae3fb1 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ build/ reports/ .DS_Store .venv -.python_version \ No newline at end of file +.python_version +settings.json \ No newline at end of file diff --git a/README.md b/README.md index 5e2f4e3..095789a 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ NOTE: Please ensure your copy of this repository is private, not public, when yo - Follow the steps under [Installation](#Installation) to setup this repo for running scripts locally - run `brownie accounts new multi-sig-delegator` to import your safe owner account - open [delegates.py](scripts/delegates.py) and add in your safe address for the `safe` variable and also change the - `brownie run delegates add_delegate_from_existing_address --network -main`. Replace `` with the short name for a network, e.g. eth, opti, ftm, arb, gor, etc. + `brownie run delegates add_delegate_from_existing_address --network -main`. Replace `` with the short name for a network, e.g. eth, opti, ftm, arb, etc. ### Secrets Add these repository secrets. Go to https://github.com/{org}/{repo}/settings/secrets/actions. Note: replace {org} and {repo} with your information. @@ -129,7 +129,7 @@ anvil --help ``` python -m pip install --user pipx python -m pipx ensurepath -pipx install eth-brownie==1.19.2 +pipx install eth-brownie==1.20.5 ``` Open a new terminal. diff --git a/network-config.yaml b/network-config.yaml index 448d40a..bf6c782 100644 --- a/network-config.yaml +++ b/network-config.yaml @@ -35,14 +35,6 @@ live: id: arb-main name: Mainnet explorer: https://api.arbiscan.io/api -- name: Goerli - networks: - - chainid: 5 - host: https://goerli.infura.io/v3/$WEB3_INFURA_PROJECT_ID - id: gor-main - name: Mainnet - multicall2: '0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696' - explorer: https://api-goerli.etherscan.io/api - name: gnosis-chain networks: - chainid: 100 @@ -66,97 +58,79 @@ live: explorer: https://api.basescan.org/api development: -- cmd: anvil +- cmd: anvil --steps-tracing --block-base-fee-per-gas 0 --gas-price 0 cmd_settings: accounts: 10 fork: mainnet gas_limit: 30000000 - mnemonic: brownie port: 8545 host: http://127.0.0.1 id: eth-main-fork name: Anvil-CLI (eth-Mainnet Fork) timeout: 1200 -- cmd: anvil +- cmd: anvil --steps-tracing --block-base-fee-per-gas 0 --gas-price 0 cmd_settings: accounts: 10 fork: bsc-main gas_limit: 12000000 - mnemonic: brownie port: 8545 host: http://127.0.0.1 id: bsc-main-fork name: Ganache-CLI (BSC-Mainnet Fork) timeout: 1200 -- cmd: anvil +- cmd: anvil --steps-tracing --block-base-fee-per-gas 0 --gas-price 0 cmd_settings: accounts: 10 fork: ftm-main gas_limit: 10000000 - mnemonic: brownie port: 8545 host: http://127.0.0.1 id: ftm-main-fork name: Anvil-CLI (FTM-Mainnet Fork) timeout: 1200 -- cmd: anvil +- cmd: anvil --steps-tracing --block-base-fee-per-gas 0 --gas-price 0 cmd_settings: accounts: 10 fork: matic-main gas_limit: 12000000 - mnemonic: brownie port: 8545 host: http://127.0.0.1 id: matic-main-fork name: Anvil-CLI (MATIC-Mainnet Fork) timeout: 1200 -- cmd: anvil - cmd_settings: - accounts: 10 - fork: gor-main - gas_limit: 12000000 - mnemonic: brownie - port: 8545 - host: http://127.0.0.1 - id: gor-main-fork - name: Anvil-CLI (Goreli-Mainnet Fork) -- cmd: anvil +- cmd: anvil --steps-tracing --block-base-fee-per-gas 0 --gas-price 0 cmd_settings: accounts: 10 fork: gc-main gas_limit: 12000000 - mnemonic: brownie port: 8545 host: http://127.0.0.1 id: gc-main-fork name: Anvil-CLI (gnosis-chain Fork) -- cmd: anvil +- cmd: anvil --steps-tracing --block-base-fee-per-gas 0 --gas-price 0 cmd_settings: accounts: 10 fork: opti-main gas_limit: 12000000 - mnemonic: brownie port: 8545 host: http://127.0.0.1 id: opti-main-fork name: Anvil-CLI (Optimism-Mainnet Fork) -- cmd: anvil +- cmd: anvil --steps-tracing --block-base-fee-per-gas 0 --gas-price 0 cmd_settings: accounts: 10 fork: base-main gas_limit: 12000000 - mnemonic: brownie port: 8545 host: http://127.0.0.1 id: base-main-fork name: Anvil-CLI (Base-Mainnet Fork) -- cmd: anvil +- cmd: anvil --steps-tracing --block-base-fee-per-gas 0 --gas-price 0 cmd_settings: accounts: 10 evm_version: istanbul fork: arb-main gas_limit: 12000000 - mnemonic: brownie port: 8545 host: http://127.0.0.1 id: arb-main-fork @@ -167,7 +141,6 @@ development: evm_version: istanbul fork: mainnet gas_limit: 30000000 - mnemonic: brownie port: 8545 host: http://127.0.0.1 id: eth-ganache-main-fork @@ -179,7 +152,6 @@ development: evm_version: istanbul fork: bsc-main gas_limit: 12000000 - mnemonic: brownie port: 8545 host: http://127.0.0.1 id: bsc-ganache-main-fork @@ -191,7 +163,6 @@ development: evm_version: istanbul fork: ftm-main gas_limit: 10000000 - mnemonic: brownie port: 8545 host: http://127.0.0.1 id: ftm-ganache-main-fork @@ -203,30 +174,17 @@ development: evm_version: istanbul fork: matic-main gas_limit: 12000000 - mnemonic: brownie port: 8545 host: http://127.0.0.1 id: matic-ganache-main-fork name: Ganache-CLI (MATIC-Mainnet Fork) timeout: 1200 -- cmd: ganache-cli - cmd_settings: - accounts: 10 - evm_version: istanbul - fork: gor-main - gas_limit: 12000000 - mnemonic: brownie - port: 8545 - host: http://127.0.0.1 - id: gor-ganache-main-fork - name: Ganache-CLI (Goreli-Mainnet Fork) - cmd: ganache-cli cmd_settings: accounts: 10 evm_version: istanbul fork: arb-main gas_limit: 12000000 - mnemonic: brownie port: 8545 host: http://127.0.0.1 id: arb-ganache-main-fork @@ -237,7 +195,6 @@ development: evm_version: istanbul fork: gc-main gas_limit: 12000000 - mnemonic: brownie port: 8545 host: http://127.0.0.1 id: gc-ganache-main-fork @@ -248,7 +205,6 @@ development: evm_version: istanbul fork: opti-main gas_limit: 12000000 - mnemonic: brownie port: 8545 host: http://127.0.0.1 id: opti-ganache-main-fork @@ -259,7 +215,6 @@ development: evm_version: istanbul fork: base-main gas_limit: 12000000 - mnemonic: brownie port: 8545 host: http://127.0.0.1 id: base-ganache-main-fork diff --git a/requirements-dev.txt b/requirements-dev.txt index 54b85f5..6a8088f 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,12 +1,12 @@ cython<3.0 pyyaml>=5.4.1,<6 -eth-brownie==1.19.2 -black==22.10.0 -click==8.1.3 -regex==2021.10.8 +eth-brownie==1.20.5 +black==24.2.0 +click==8.1.7 +regex==2023.12.25 tomli==2.0.1 tenacity==8.0.1 psutil>=5.9.2 -multisig-ci==0.8.13 -tokenlists==0.1.1 +multisig-ci==0.8.22 +tokenlists==0.1.7 sentry-sdk==1.39.1 From b23d5cd26d040cc15ee689a02db1726d8fec6b6a Mon Sep 17 00:00:00 2001 From: kx9x Date: Wed, 19 Jun 2024 15:09:58 -0700 Subject: [PATCH 82/83] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 095789a..c9f9be6 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ Follow the process steps below for queuing transactions to your multisig ``` /run file=[main|hydrate_ci_cache] fn=[name_of_fxn] network=[eth|bsc|matic|ftm|rin|arb] ``` - Note: remove the [ ] symbols, e.g. /run fn=run_example network=matic + Note: remove the [ ] symbols, e.g. /run fn=example network=matic The file param defaults to main, so you can usually omit it - The GitHub action runner will respond with: From 56a4284e942054df3363ce09de73118728f3caff Mon Sep 17 00:00:00 2001 From: kx9x Date: Sun, 26 Jan 2025 19:18:25 -0800 Subject: [PATCH 83/83] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c9f9be6..4c2cb2a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -I'm# yearn-multisig-actions +yearn-multisig-actions Template repository for automating delegate transactions to [Gnosis Safe](https://gnosis-safe.io/app/) multisig wallets through Github Actions