This package provides a set of tools and scripts to help with the development of Solidity smart contracts:
This package is still under development and should be used with caution. It is not recommended to use it in a production environment.
Forge docs are automatically deployed here.
In order to use this package, it needs to be installed as a dependency in your project. It is recommended to install it as a dev dependency.
npm install --save-dev @synapsecns/solidity-devops
# Or, if you are using yarn
yarn add --dev @synapsecns/solidity-devops
Following files are necessary to be present in the root of your project:
.env
: storage for the sensitive configuration variables.devops.json
: configuration file for the devops package.foundry.toml
: configuration file for Foundry..env
Note: This file must be added to .gitignore
to avoid sharing sensitive information.
See the example .env file. Following structure is required:
Wallets
: defines the deployer wallets used for running the scripts. Assuming the chad
is the name of the wallet, the following values are required:
CHAD_ADDRESS
: the address of the account to use for signingCHAD_TYPE
: the type of the wallet:
keystore
: use the encrypted keystore file.
CHAD_JSON
: the keystore file pathledger
or trezor
: use the hardware wallet.
pk
: use the plaintext private key. STRONGLY DISCOURAGED for production usage, meant for local devnet purposes.
CHAD_PK
: the private key to the wallet in 0x format.Chains
: defines the list of chains where the scripts will run. Assuming the chain
is the name of the chain, the following values are required:
CHAIN_RPC
: the RPC endpoint of the chainCHAIN_VERIFIER
: verifier for the smart contracts. Possible values:
etherscan
blockscout
sourcify
CHAIN_VERIFIER_URL
: the Verifier API endpoint (required if verifier is not sourcify)
CHAIN_VERIFIER_KEY
: the Verifier API key (required if verifier is not sourcify)
devops.json
See the example devops.json file. Following values are required:
chains
: list of chain-specific options for forge script
command.
forge script --help
.--auto-gas-1559
: will fetch the current base fee and priority fee from the chain’s RPC node, and use following values for submitting the transactions:
maxPriorityFee = priorityFee
maxGasPrice = 2 * baseFee + priorityFee
--auto-gas-legacy
: will fetch the current gas price from the chain’s RPC node, and use it for submitting the transactions.
Note: these options are introduced as foundry script hardcodes the 3 Gwei priority fee, which is not ideal for all the chains.
deployConfigs
: path to the directory that contains the deployment configuration files. These configuration files are expected to be either chain-specific or global:
deployConfigsDir/{chainName}/{contractName}.dc.json
.deployConfigsDir/global/{contractName}.json
.deployConfigsDir/global/{environment}/{contractName}.json
.deployments
: path to the directory that contains the deployment artifact files. These files are automatically generated by fsr
and alike commands.forgeArtifacts
: path to the directory that forge
uses to store the artifacts for the compiled contracts.
out
value in the foundry.toml
file.freshDeployments
: path to the directory that contains the fresh deployment artifact files. These files are generated during the local run of the forge script
command.
.gitignore
to avoid unnecessary changes in the repository.deployments
directory by fsr
and alike commands.
Note: we opted to use this approach, as the local run of the
forge script
is always done before the actual broadcast of the deployment transactions. Therefore, the end results might not match the local run, if there was an unexpected on-chain revert, or if transactions were not included in the block. A separate job is automatically run to check all the new artifacts and move them to thedeployments
directory, if the on-chain deployment was successful.
foundry.toml
See the example foundry.toml file. Following values are required:
fs_permissions
:
{ access = "read", path = "./" }
to allow reading files from the repository root{ access = "read-write", path = "<freshDeployments>" }
to allow reading/writing fresh deployment artifactsrpc_endpoints
:
arbitrum = "${ARBITRUM_RPC}"
etherscan
:
arbitrum = { key = "${ARBITRUM_VERIFIER_KEY}", url = "${ARBITRUM_VERIFIER_URL}" }
See the Foundry Book for more information.
SynapseScript
class (or SynapseScript06
if you’re using Solidity 0.6 compiler).
forge-std
’s Script
class, so you can use all the methods from it.Deploy{ContractName}.s.sol
.Configure{ContractName}.s.sol
.Your main point of entry for running the scripts should be the npx fsr
command.
Note:
fsr
is a shorthand forforge script run
.
# npx fsr <path-to-script> <chain-name> <wallet-name> [<options>]
# To simulate the script without broadcasting, using wallet named "chad"
npx fsr script/DeployBasicContract.s.sol eth_sepolia chad
# To broadcast the script using wallet named "chad"
# NOTE: there is no need to add --verify option, as it is automatically added for the broadcasted scripts.
npx fsr script/DeployBasicContract.s.sol eth_sepolia chad --broadcast
This command is responsible for the following:
.chainid
file, if they don’t exist.forge script
command.
run()
method of the script.--verify
option is added if the script is broadcasted.You can also utilize the npx fsr-str
command to provide a single string argument for the running script:
run(string memory arg)
method of the script, passing the provided string argument.# npx fsr-str <path-to-script> <chain-name> <wallet-name> <string-arg> [<options>]
# To simulate the script without broadcasting, using wallet named "chad"
npx fsr-str script/DeployBasicContract.s.sol eth_sepolia chad "AAAAAAAA"
# To broadcast the script using wallet named "chad"
# NOTE: there is no need to add --verify option, as it is automatically added for the broadcasted scripts.
npx fsr-str script/DeployBasicContract.s.sol eth_sepolia chad "AAAAAAAA" --broadcast
If for whatever reason the deployment script was interrupted, you can use npx sd
command to save the deployment artifacts.
Note:
sd
is a shorthand forsave deployment
.
# npx sd <chain-name> <contract-alias>
npx sd eth_sepolia BasicContract
# Or, if the contract alias is used
npx sd eth_sepolia BasicContract.Alias
You can verify the contracts with the saved deployment artifacts using the npx fvc
command.
Note:
fvc
is a shorthand forforge verify contract
.
# npx fvc <chain-name> <contract-alias>
npx fvc eth_sepolia BasicContract
# Or, if the contract alias is used
npx fvc eth_sepolia BasicContract.Alias
You can verify the proxy’s implementation in Etherscan-alike explorers using the npx vp
command.
Note:
vp
is a shorthand forverify proxy
.
# npx vp <chain-name> <contract-alias>
npx vp eth_sepolia BasicContract
# Or, if the contract alias is used
npx vp eth_sepolia TransparentUpgradeableProxy.BasicContract