Skip to content

Commit

Permalink
feat: post-audit updates
Browse files Browse the repository at this point in the history
  • Loading branch information
sam-goldman committed Dec 5, 2023
1 parent 2396808 commit 6981e3e
Show file tree
Hide file tree
Showing 150 changed files with 3,295 additions and 6,871 deletions.
8 changes: 8 additions & 0 deletions .changeset/bright-seals-exist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@sphinx-labs/contracts': minor
'@sphinx-labs/plugins': minor
'@sphinx-labs/core': minor
'@sphinx-labs/demo': minor
---

Post audit updates
1 change: 1 addition & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ jobs:
- run:
name: Test
command: yarn test:coverage
no_output_timeout: 20m
working_directory: packages/<<parameters.package_name>>

depcheck:
Expand Down
3 changes: 0 additions & 3 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,5 @@ contracts:
core:
- any: ['packages/core/**/*']

executor:
- any: ['packages/executor/**/*']

plugins:
- any: ['packages/plugins/**/*']
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@
"eslint.nodePath": "./node_modules/eslint/bin/",
"eslint.format.enable": true,
"editorconfig.generateAuto": false,
"files.trimTrailingWhitespace": true
"files.trimTrailingWhitespace": true,
}
41 changes: 32 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,42 @@

Sphinx is a protocol and Foundry plugin that automates the smart contract deployment process.

TODO(md-end): add a 'security'/'audit' section in the main readme

TODO(md):
coming soon:
- support for arbitrary networks
- view the contents of a deployment
- use sphinx with an existing gnosis safe
coming soon to the DevOps platform:
- deployment artifacts
- payments in usdc

TODO(md): document the erc20-style failure that m4rio pointed out

TODO(md): document which gnosis safe versions we support. mention that 1.3.0 is currently the canonical gnosis safe version.

TODO(md-end): c/f SphinxModuleProxy.t.sol in the specs and update line numbers.

TODO(md-end): c/f: the `setUp` function in *.md. the referenced logic is no longer in the setUp function.

TODO(md): document how we handle failures.

## Key features:

* **Gasless deployments**: You don't need to worry about securing a funded private key or getting native gas tokens on any chain. We'll handle the fees and bill you in fiat or USDC after your deployment is completed.
* **Gasless deployments**: You don't need to worry about securing a funded private key or getting native gas tokens on any chain. We'll bill you in fiat after your deployment is finished.

* **One-Click Multichain Deployments**: Approve deployments across 11 supported networks by signing a single meta transaction. Sphinx's backend will trustlessly execute the deployment on each network in parallel and then verify your smart contracts on Etherscan.
* **One-Click Multichain Deployments**: Approve deployments across 11 supported networks by signing a single meta transaction. Sphinx's backend will execute the deployment on each network in parallel and then verify your smart contracts on Etherscan.

* **Deployments in CI**: Initiating deployments from a CI process has obvious benefits, such as reproducibility and consistency, but it hasn't been practical until now. With Sphinx, you can propose deployments from your CI process and then approve them in our UI (all gaslessly, of course). If you'd rather not use a CI process, you can propose deployments from your local machine.

- **Powered by Gnosis Safe**: The Sphinx protocol is a [Gnosis Safe Module](https://docs.safe.global/safe-smart-account/modules) designed for deployments. With the Sphinx Module, your Gnosis Safe owners can approve deployments across an arbitrary number of chains by signing a single meta transaction.
- **Powered by Gnosis Safe**: The Sphinx protocol is a [Gnosis Safe Module](https://docs.safe.global/safe-smart-account/modules) designed for deployments. With the Sphinx Module, your Gnosis Safe owners can approve deployments across an arbitrary number of chains by signing a single meta transaction. Sphinx will deploy a Gnosis Safe on your behalf at a consistent address with `CREATE2`.

- **Secure `CREATE3` Deployments**: You can use your multisig as your permissioned `CREATE3` deployer instead of relying on a single private key to get consistent contract addresses across networks.
- **Completely Trustless**: It's impossible for Sphinx to execute anything that your Gnosis Safe owners have not explicitly approved. Our system has been audited by Spearbit; see our audit report [here](TODO(md)).

* **Compatible with Forge Scripts**: You can integrate Sphinx with minimal changes to your existing Forge scripts.
TODO: practically speaking, how can a user do a create3 deployment like this? if it's not reasonable for a user to figure it out themselves, either make a guide or remove this bullet point.

- **Secure `CREATE3` Deployments**: You can use your multisig as your permissioned `CREATE3` deployer instead of relying on a single private key to get consistent contract addresses across networks.

* **Compatible with Forge Scripts**: You can integrate Sphinx with minimal changes to your existing Forge scripts.

Expand All @@ -34,18 +57,18 @@ Sphinx is currently invite-only. [Request access on our website.](https://sphinx

- [Writing Deployment Scripts](https://github.com/sphinx-labs/sphinx/blob/main/docs/writing-scripts.md)
- [Configuration Options](https://github.com/sphinx-labs/sphinx/blob/main/docs/configuration-options.md)
- [Overview of the Sphinx DevOps Platform](https://github.com/sphinx-labs/sphinx/blob/main/docs/ops-overview.md)
- [Using Sphinx in CI](https://github.com/sphinx-labs/sphinx/blob/main/docs/ci-proposals.md)
- [FAQ](https://github.com/sphinx-labs/sphinx/blob/main/docs/faq.md)
- [Using Sphinx in a CI Process](https://github.com/sphinx-labs/sphinx/blob/main/docs/ci-proposals.md)
- [Deploying on Anvil](TODO(md))
- [How Sphinx Works](TODO(md))
- [Troubleshooting Guide](https://github.com/sphinx-labs/sphinx/blob/main/docs/troubleshooting-guide.md)

### Specifications

- [Introduction](https://github.com/sphinx-labs/sphinx/blob/develop/specs/introduction.md)
- [Sphinx Merkle Tree](https://github.com/sphinx-labs/sphinx/blob/develop/specs/merkle-tree.md)
- [`SphinxModuleProxy` Contract](https://github.com/sphinx-labs/sphinx/blob/develop/specs/sphinx-module-proxy.md)
- [`SphinxModuleProxyFactory` Contract](https://github.com/sphinx-labs/sphinx/blob/develop/specs/sphinx-module-proxy-factory.md)
- [`ManagedService` Contract](https://github.com/sphinx-labs/sphinx/blob/develop/specs/managed-service.md)
- [Sphinx Merkle Tree](https://github.com/sphinx-labs/sphinx/blob/develop/specs/merkle-tree.md)

## Current limitations

Expand Down
19 changes: 7 additions & 12 deletions docs/ci-proposals.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This guide will show you how to integrate proposals into your CI process. We'll

We'll use GitHub Actions as the CI platform in this guide. You can still follow this guide if you're using a different CI platform, but the exact configuration may be slightly different.

> Important: Sphinx will propose all transactions that are broadcasted by Foundry. By default, this is **not idempotent**. This means that if you open a PR after completing a deployment, Sphinx will attempt to re-propose any transactions from your script that can be broadcasted again. In most cases, this is not desirable behavior. To resolve this, we highly recommend adjusting your deployment script so that it's idempotent.
> Important: Sphinx will propose all transactions that are broadcasted by Foundry. By default, this is **not idempotent**. This means that if you open a PR after completing a deployment, Sphinx will attempt to re-propose any transactions from your script that can be broadcasted again. In most cases, this is not desirable behavior. To resolve this, we highly recommend making your deployment script idempotent.
## Table of Contents

Expand All @@ -24,9 +24,9 @@ We'll use GitHub Actions as the CI platform in this guide. You can still follow

The Sphinx DevOps Platform is currently invite-only, so you need an invite link to follow along with this guide. You can [request access on our website](https://sphinx.dev) if you haven't already.

Make sure that you've already completed the [Sphinx DevOps Platform guide](https://github.com/sphinx-labs/sphinx/blob/main/docs/ops-getting-started.md) for the project you're going to deploy in this guide.
Make sure that you've already completed the [Sphinx DevOps Platform guide](https://github.com/sphinx-labs/sphinx/blob/main/docs/ops-getting-started.md).

Also, make sure that your `foundry.toml` has an `rpc_endpoints` section that contains an RPC endpoint for each network you want to support in your project.
Also, make sure that your `foundry.toml` has an `rpc_endpoints` section that contains an RPC endpoint for each network you want to deploy on.

## 2. Create a new branch

Expand Down Expand Up @@ -59,12 +59,9 @@ First, we'll create a workflow that dry runs the proposal whenever a pull reques

Copy and paste the following into your `sphinx.dry-run.yml` file:

// TODO(md) - remove all references to `PROPOSER_PRIVATE_KEY`

```
name: Sphinx Dry Run
env:
PROPOSER_PRIVATE_KEY: ${{ secrets.PROPOSER_PRIVATE_KEY }}
SPHINX_API_KEY: ${{ secrets.SPHINX_API_KEY }}
# Put any node provider API keys or URLs here. For example:
# ALCHEMY_API_KEY: ${{ secrets.ALCHEMY_API_KEY }}
Expand All @@ -84,7 +81,7 @@ jobs:
- name: Install Dependencies
run: yarn --frozen-lockfile
- name: Dry Run
run: npx sphinx propose <path/to/your-script.s.sol> --dry-run --testnets
run: npx sphinx propose <path/to/your/script.s.sol> --dry-run --testnets
```

Here is a list of things you may need to change in the template:
Expand All @@ -100,7 +97,6 @@ Copy and paste the following into your `sphinx.deploy.yml` file:
```
name: Sphinx Propose
env:
PROPOSER_PRIVATE_KEY: ${{ secrets.PROPOSER_PRIVATE_KEY }}
SPHINX_API_KEY: ${{ secrets.SPHINX_API_KEY }}
# Put any node provider API keys or URLs here. For example:
# ALCHEMY_API_KEY: ${{ secrets.ALCHEMY_API_KEY }}
Expand All @@ -123,7 +119,7 @@ jobs:
- name: Install Dependencies
run: yarn --frozen-lockfile
- name: Propose
run: npx sphinx propose <path/to/your-script.s.sol> --confirm --testnets
run: npx sphinx propose <path/to/your/script.s.sol> --confirm --testnets
```

Here is a list of things you may need to change in the template:
Expand All @@ -137,15 +133,14 @@ Here is a list of things you may need to change in the template:
You'll need to add a few variables as secrets in your CI process. If you're not sure how to add secrets, [see here for a guide by GitHub on storing secrets in GitHub Actions](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions).

Here is the list of secrets to add:
- `PROPOSER_PRIVATE_KEY`: The private key of one of the proposer addresses, which are located inside your deployment script in the `sphinxConfig.proposers` array. We recommend that you use a dedicated EOA for your proposer that does not store any funds and is not used for any other purpose besides proposing.
- `SPHINX_API_KEY`: You can find this in the Sphinx UI after registering your organization.
- RPC node provider API keys for all target networks. Node providers like Alchemy generally use one API key across all networks that they support.

## 8. Test your integration

Push your branch to GitHub, open a PR, and merge it after the dry run succeeds. You can then go to https://www.sphinx.dev and you'll find your new deployment there.
Push your branch to GitHub, open a PR, and merge it after the dry run succeeds. Then, you go to the [Sphinx UI](https://www.sphinx.dev) to approve your deployment.

## 9. Production Deployments
In this guide, we've configured the CI process to deploy against test networks. If you want to go straight to production, you can do so by switching the `--testnets` flag with the `--mainnets` flag in both templates.

In practice, you may want something different depending on your workflow. For a more robust setup, we recommend using a `develop` branch and triggering testnet deployments when merging to that branch. We recommend using a separate workflow that triggers deployments on production networks when you merge to `main`.
In practice, you may want something different depending on your workflow. For a more robust setup, we recommend using a `develop` branch and triggering testnet deployments when merging to that branch. We recommend using a separate workflow that triggers deployments on production networks when you merge from your `develop` branch to `main`.
22 changes: 22 additions & 0 deletions docs/cli-deployments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Deploying on Anvil

Sphinx has its own CLI command for broadcasting deployments onto Anvil. You can run it with this command, replacing `<path/to/your/script.s.sol>` with the path to your deployment script:

```
npx sphinx deploy <path/to/your/script.s.sol> --network anvil
```

The following steps will occur when you run this command:

1. The command will simulate the deployment by invoking the script's `run()` function on a fork of the specified network. It will collect the transactions in the `run()` function.
2. The collected transactions will be displayed in a preview, which you'll be prompted to confirm. You can skip the preview by including a `--confirm` flag when you run the command.
3. Your transactions will be broadcasted on Anvil through your Gnosis Safe.
4. Deployment artifacts will be written to the file path: `./deployments/anvil-<chain_id>/<ContractName>.json`.

> Tip: Before you run the command, make sure you've added Anvil to the `rpc_endpoints` section in your
> `foundry.toml`. For example:
> ```toml
> [rpc_endpoints]
> anvil = "http://127.0.0.1:8545"
> ```
71 changes: 13 additions & 58 deletions docs/cli-existing-project.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,14 @@ This guide will show you how to integrate Sphinx's Foundry CLI plugin into an ex

## Table of Contents

1. [Prerequisites](#1-prerequisites)
2. [Update Foundry](#2-update-foundry)
3. [Install Sphinx](#3-install-sphinx)
4. [Update `.gitignore`](#4-update-gitignore)
5. [Update `foundry.toml`](#5-update-foundrytoml)
6. [Initialize a project](#6-initialize-a-project)
7. [Add remappings](#7-add-remappings)
8. [Test the deployment](#8-test-the-deployment)
9. [Broadcast a deployment on Anvil (optional)](#9-broadcast-a-deployment-on-anvil-optional)
10. [Next steps](#10-next-steps)
TODO(md-end)

## 1. Prerequisites

The following must be installed on your machine:
- [Foundry](https://book.getfoundry.sh/getting-started/installation)
- [Yarn](https://classic.yarnpkg.com/lang/en/docs/install/), [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm), or [pnpm](https://pnpm.io/installation)
- [Node Version >=16.16.0](https://nodejs.org/en/download)
- [Node Version >=16.16.0](https://nodejs.org/en/download). (Run `node -v` to see your current version).

You must also have a basic understanding of how to use Foundry and Forge scripts. Here are the relevant guides in the Foundry docs:
* [Getting Started with Foundry](https://book.getfoundry.sh/getting-started/first-steps)
Expand Down Expand Up @@ -73,69 +64,33 @@ fs_permissions = [{ access = "read-write", path = "./"}]

## 6. Initialize a project

Next, we'll create a sample project using the init command.
Using Yarn or npm:

### yarn or npm
```
npx sphinx init
```

### pnpm
Using pnpm:

```
pnpm sphinx init --pnpm
```

This created a few files:
- `HelloSphinx.sol`: A sample contract to deploy. This file is written to your existing contract folder, which defaults to `src/`.
- `HelloSphinx.s.sol`: A sample deployment script. This file is written to your existing script folder, which defaults to `script/`.
- `HelloSphinx.t.sol`: A sample test file. This file is written to your existing test folder, which defaults to `test/`.

## 7. Add remappings
This command outputs a set of remappings that you'll need to add to your `foundry.toml` or `remappings.txt` file. If you don't already have a `remappings.txt` file or a `remappings` section in your `foundry.toml`, we recommend adding a `remappings.txt` file in the root of your repository.

You probably already have remappings either in your `foundry.toml` or `remappings.txt` file. If you don't, we recommend adding a `remappings.txt` file in the root of your repository.

The previous command should have output a set of recommended remappings based on your installation method. You'll want to copy and paste those into either your remapping field in your `foundry.toml`, or your `remappings.txt` file.
This command also created a few files:
- `HelloSphinx.sol`: A sample contract to deploy. This file is written to your existing contract folder, which defaults to `src/`.
- `HelloSphinx.s.sol`: A sample Sphinx deployment script. This file is written to your existing script folder, which defaults to `script/`.
- `HelloSphinx.t.sol`: A sample test file for the deployment. This file is written to your existing test folder, which defaults to `test/`.

## 8. Test the deployment
## 7. Test the deployment

Run the test in `HelloSphinx.t.sol`:
Test the deployment by running:
```
forge test --match-contract HelloSphinxTest
```

## 9. Broadcast a deployment on Anvil (optional)

Sphinx has its own CLI task for broadcasting deployments onto stand-alone networks. Its main purpose is to deploy contracts on Anvil, but you can use it on live networks too.

First, add Anvil to your `rpc_endpoints` in your `foundry.toml`:
```
[rpc_endpoints]
anvil = "http://127.0.0.1:8545"
```

Start an Anvil node:
```
anvil
```

Add a private key to your .env file. We'll use the first valid one on Anvil:
```
PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
```

Then, navigate to a new terminal window. Broadcast the deployment with the following command, replacing `<script/path/>` with the path to your deployment script.

```
npx sphinx deploy <script/path>/HelloSphinx.s.sol --network anvil
```

You'll be shown a preview of your deployment and prompted to confirm. Any transactions that are broadcasted by Foundry will be included in the deployment.

Sphinx will automatically generate deployment artifacts, which are in the same format as [hardhat-deploy](https://github.com/wighawag/hardhat-deploy). When the deployment completes, you'll find the deployment artifacts written to `./deployments/anvil-31337.json`.

If you'd like to use this command to deploy on a live network, you can verify your contracts on block explorers using the `--verify` flag.

## 10. Next steps
## 8. Next steps

If you'd like to try out the DevOps platform, see the [Sphinx DevOps Platform guide](https://github.com/sphinx-labs/sphinx/blob/main/docs/ops-getting-started.md).

Expand Down
Loading

0 comments on commit 6981e3e

Please sign in to comment.