Synthetixio / synthetix

Synthetix Solidity smart contracts
https://synthetix.io/
MIT License
1.2k stars 594 forks source link

Deployment needs to track historical sources and addresses #440

Open jjgonecrypto opened 4 years ago

jjgonecrypto commented 4 years ago

There are a number of reasons we might want this:

To track older contracts that are static with newer source code A number of our source contracts have changed to keep them inline with the latest developments and yet they haven't been redeployed (usually because we can't - such as for eternal state contracts). E.g. SynthetixEscrow (nee HavvenEscrow) and SynthetixState. We'd like to have a way of knowing accurately which source solidity file is for which contract.

This will: a) help us better simulate testing locally as we can simulate an upgrade b) ensure our documentation is correct - https://docs.synthetix.io/addresses/ should show Solidity source and JSON ABIs for the aforementioned SynthetixState and HavvenEscrow rather than their newer sources as they do now which is inaccurate c) help us document which contracts were modified in each deployment

To improve developer tooling on historical activities A number of ABI changes have occurred to key user functions and events in Synthetix.sol. For instance, SynthExchange has migrated from bytes4 to bytes32 in Sirius (v2.10) with SIP-16. This means you cannot simply use the existing Synthetix ABI to filter on those older events in the EVM - you need the old ABIs for these.

This will: a) help those building analytics tools to accurately query older Synthetix contract state b) help us manage this same problem with our subgraphs - see https://github.com/Synthetixio/synthetix-subgraph/blob/upgrading-graph-cli/subgraphs/synthetix.yaml

To improve our release automation Adding a version list file for each deployment target (mainnet, kovan, etc) along with the blocks introduced, SIPs added and entire list of contract targets.

This will: a) help us show in our documentation which contracts were added and which removed in each deployment b) help us automate official GitHub releases with links to SIPs addressed

jjgonecrypto commented 4 years ago

Here's what I'm thinking inside each publish/deployed/[environment] instead of a single deployment.json

publish/deployed/mainnet/versions.json

{
    "history": ["v2.20.0", "v2.19.6"],
    "versions": {
        "v2.20.0": {
            "name": "Betelgeuse",
            "timestamp": "....",
            "block": 12321,
            "targets": ["entire list of all contract names goes here - necessary to know what is removed, if any"], 
            "sips": ["sip-40", "sip-41", "sip-42"]
        },
        "v2.19.6": {
            "name": "Achernar",
            "timestamp": "....",
            "block": 12321,
                         "targets": ["entire list of all contract names goes here - necessary to know what is removed, if any"], 
            "sips": ["sip-37", "sip-38"]
        }
    }
}
  1. By having the block number and timestamp, we could allow features like "get the Synthetix contract at this block/timestamp", which is pretty useful during analytics
  2. The targets list is important - it's every key currently in deployment.json#targets. By including it in each version we can see if something was removed between versions - such as a synth.
  3. By including the SIPs, we can automate GitHub releases.

publish/deployed/mainnet/targets/Depot.json

{
    "name": "Depot",
    "versions": {
        "v2.19.6": {
            "address": "0xE1f64079aDa6Ef07b03982Ca34f1dD7152AA3b86",
            "source": "Depot",
            "link": "https://etherscan.io/address/0xE1f64079aDa6Ef07b03982Ca34f1dD7152AA3b86",
            "timestamp": "2020-02-20T06:26:34.000Z",
            "txn": "https://etherscan.io/tx/0x7246da8ec30f70ac783498a5b79408cc5ae049ea71bc6bf393557cf3e2c9a8ad"
        },
        "v2.0.0": {
            "address": "0x172E09691DfBbC035E37c73B62095caa16Ee2388",
            "source": "Depot",
            "link": "https://etherscan.io/address/0x172E09691DfBbC035E37c73B62095caa16Ee2388"
        }
    },
    "network": "mainnet"
}
  1. From the above we can determine that Depot was upgraded in v2.19.6 and we can go to the below to find the source
  2. It's imperative however that the version v2.19.6 be an actual tag and that the source file Depot.sol exists under contracts for that tag.

publish/deployed/mainnet/sources/Depot.json

{
    "name": "Depot",
    "versions": {
        "v2.19.6": {
            "bytecode": "60....00",
            "abi": [],
                         "code": "...flattened code goes in here..."
        },
        "v2.0.0": {
            "bytecode": "60....00",
            "abi": [],
                         "code": "...flattened code goes in here..."
        }
    }
}
  1. The flattened code is added for each source - this also makes it much easier to test the contract as we don't have to checkout old tags and find linked sources

The requirements would be:

  1. Each change has a version number associated with it. Before a deploy a new version needs to be added to the appropriate versions.json file and that should be given as an argument to publish deploy. The trick will be making sure this version stays consistent, even if we need a patch release during the actual release. For example, let's say we go to deploy v2.13.0 and after deploy but before release we note that we need a v2.13.1. We need to run a deploy again for v2.13.1 but it needs to overwrite the version v2.13.0 with this new `v2.13.1.
  2. That each version maps to a tag name in the repo. This is key for us to be able to correlate sourcees.
  3. That the source field in each target json maps to the name of the source contract at that version tag.
jjgonecrypto commented 4 years ago

@jacko125 @hav-noms for input on ^^^