Details of the release process for updating smart contracts on the Celo platform.
Details of the release process for updating smart contracts on the Celo platform.
This release process is a work in progress. Many infrastructure components required to execute it are not in place, and the process itself is subject to change.
Each deployed Celo core smart contract is versioned independently, according to semantic versioning, as described at semver.org, with the following modifications:
STORAGE version when you make incompatible storage layout changes
MAJOR version when you make incompatible ABI changes
MINOR version when you add functionality in a backwards compatible manner, and
PATCH version when you make backwards compatible bug fixes.
Changes to core smart contracts are made via on-chain Governance, approximately four times a year. When a release is made, all smart contracts from the release branch that differ from the deployed smart contracts are released, and included in the same governance proposal. Each release is identified by a unique monotonically increasing version number N, with 1 being the first release.
Every deployed Celo core contract has its current version number as a constant which is publicly accessible via the getVersionNumber() function, which returns the storage, major, minor, and patch versions. The version number is encoded in the Solidity source and updated as part of code changes.Celo Core Contracts deployed to a live network without the getVersionNumber() function, such as the original set of core contracts, are to be considered version 1.1.0.0.
Mixin contracts and libraries are considered part of the contracts that consume them. When a mixin or library has changed, all contracts that consume them should be considered to have changed as well, and thus the contracts should have their version numbers incremented and should be re-deployed as part of the next smart contract release.
Whenever Celo Core Contracts need to be re-initialized, their initialization arguments should be checked into version control under packages/protocol/releaseData/initializationData/release${N}.json.
Github branches/tags and Github releases are used to coordinate past and ongoing releases. Ongoing smart contract development is done on the master branch (even after release branches are cut). Every smart contract release has a designated release branch, e.g. release/core-contracts/${N} in the celo-monorepo.
A new release branch is created release/core-contracts/${N} with the contracts to be audited.
The latest commit on the release branch is tagged with core-contracts.v${N}.pre-audit.
On Github, a pre-release Github release should be created pointing at the latest tag on the release branch.
On master branch, .github/workflows/celo-monorepo.yml should be edited so that the variable RELEASE_TAG points to the tag core-contracts.v${N}.pre-audit so that all future changes to master are versioned against the new release.
Ongoing audit responses/fixes should continue to go into release/celo-core-contracts/${N}.
There are several scripts provided (under packages/protocol in celo-org/celo-monorepo and via celocli). The release owners’ own reference is RELEASE_PROCESS_FOUNDRY.md, which maps each retired Truffle command to its Foundry replacement. These are for use in the release process and with contract upgrade governance proposals to give participating stakeholders increased confidence.
For these to run, you may need to set up the celo-monorepo: follow the Getting Started steps and install the Node version pinned in .nvmrc (managed with nvm). A successful yarn install and yarn build in the protocol package signal a completed setup. The release scripts also shell out to Foundry (forge, cast) and jq, so install those too.
Using these tools, a contract release candidate can be built, deployed, and proposed for upgrade automatically on a specified network. Subsequently, stakeholders can verify the release candidate against a governance upgrade proposal’s contents on the network.Typical script options:
By default, the scripts expect a celo-blockchain RPC at port 8545 locally. With -f you can specify the scripts to use a hosted forno node
By default, scripts will output verbose logs under /tmp/celo-${script-name}.log. You can change the location of the log output with -l file.log
release:verify-deployed:foundry is a script that allows you to assess whether the bytecode on the given network matches the source code of a particular commit. It will run through the Celo Core Contracts and verify that the contracts’ bytecodes as specified in the Registry match. Here, we will want to sanity-check that our network is running the previous release’s audited commit.
# Run from `packages/protocol` in the celo-monorepoN=18 # the release being preparedPREVIOUS_RELEASE="core-contracts.v$((N-1))"NETWORK="celo-sepolia" # "anvil", "celo-sepolia" or "mainnet"# A -f boolean flag can be provided to use a forno full node to connect to the provided networkyarn release:verify-deployed:foundry -n $NETWORK -b $PREVIOUS_RELEASE -f
A $NETWORK-$PREVIOUS_RELEASE-libraries.json file is written to disk describing linked library addresses. release:make:foundry requires it.
This script performs some automatic checks to ensure that the smart contract versions in the source code have been set correctly with respect to the latest release. It is run as part of CI and helps ensure that backwards incompatibilities are not accidentally introduced by requiring that devs manually update version numbers whenever smart contract changes are made.Specifically, it compiles the latest and candidate releases and compares smart contracts:
Storage layout, to detect storage version changes
ABI, to detect major and minor version changes
Bytecode, to detect patch version changes
Finally, it checks release candidate smart contract version numbers and requires that they have been updated appropriately since the latest release by following semantic versioning as defined in the Versioning section above.The following exceptions apply:
If the STORAGE version has changed, it does not perform backward compatibility checks
If the MAJOR version has changed, it checks storage layout compatibility but not ABI compatibility
Critically, this ensures that proxied contracts do not experience storage
collisions between implementation versions. See this
article
by OpenZeppelin for a good overview of this problem and why it’s important to
check for it.The script generates a detailed report on version changes in JSON format, written to report-$PREVIOUS_RELEASE-$RELEASE_CANDIDATE.json.
# Run from `packages/protocol` in the celo-monorepoN=18PREVIOUS_RELEASE="core-contracts.v$((N-1))"RELEASE_CANDIDATE="core-contracts.v${N}"yarn release:check-versions:foundry -a $PREVIOUS_RELEASE -b $RELEASE_CANDIDATE
This should be used in tandem with release:verify-deployed:foundry -b $PREVIOUS_RELEASE -n $NETWORK to ensure the compatibility checks compare the release candidate to what is actually active on the network.
Use the following script to build and deploy a candidate release. This takes as input the corresponding backward compatibility report and canonical library address mapping to deploy changed contracts to the specified network. The Foundry script has no dry-run; pass -u with a local anvil fork’s RPC URL to rehearse it.
STORAGE updates are adopted by deploying a new proxy/implementation pair. This script writes a JSON contract upgrade governance proposal to proposal-$NETWORK-$RELEASE_CANDIDATE.json.
# Run from `packages/protocol` in the celo-monorepoN=18NETWORK="celo-sepolia" # "anvil", "celo-sepolia" or "mainnet"PREVIOUS_RELEASE="core-contracts.v$((N-1))"RELEASE_CANDIDATE="core-contracts.v${N}"PRIVATE_KEY="0x..." # deployer key for $NETWORKyarn release:make:foundry -b $RELEASE_CANDIDATE -n $NETWORK -r "report-$PREVIOUS_RELEASE-$RELEASE_CANDIDATE.json" -i "releaseData/initializationData/release${N}.json" -l "$NETWORK-$PREVIOUS_RELEASE-libraries.json" -k "$PRIVATE_KEY"
-k "$PRIVATE_KEY" puts the deployer key on the command line, where it is readable by other processes on the machine (for example via /proc on Linux) and is written to your shell history. Run it from a dedicated deploy machine, and clear the key from the environment and history afterwards.
The proposal encodes STORAGE updates by repointing the Registry to the new proxy. Storage compatible upgrades are encoded by repointing the existing proxy’s implementation.
Submit the autogenerated upgrade proposal to the Governance contract for review by voters, outputting a unique identifier.
# resultant proposal ID should be communicated publiclyN=18NETWORK="celo-sepolia" # "anvil", "celo-sepolia" or "mainnet"RELEASE_CANDIDATE="core-contracts.v${N}"YOUR_ADDRESS="0x..." # proposer account; must hold the depositcelocli governance:propose --deposit 100e18 --from $YOUR_ADDRESS --jsonTransactions "proposal-$NETWORK-$RELEASE_CANDIDATE.json" --descriptionURL https://github.com/celo-org/governance/blob/main/CGPs/cgp-0055.md
This script serves the same purpose as release:verify-deployed:foundry but for a not-yet
accepted contract upgrade (in the form of the upgrade_proposal.json you fetched in the step prior). It gives you the confidence that the branch specified in the -b flag in (same as release:check-versions:foundry) will be the resulting network state of the proposal if executed. It does so by going over all Celo Core Contracts and determining updates to the Registry pointers, proxy or implementation contracts and verifying their implied bytecode against the compiled source code.Additionally, include initialization_data.json from the CGP if any of the contracts have to be initialized.
# Run from `packages/protocol` in the celo-monorepoN=18RELEASE_CANDIDATE="core-contracts.v${N}"NETWORK="celo-sepolia" # "anvil", "celo-sepolia" or "mainnet"# A -f boolean flag can be provided to use a forno full node to connect to the provided networkyarn release:verify-deployed:foundry -p "upgrade_proposal.json" -b $RELEASE_CANDIDATE -n $NETWORK -f -i initialization_data.json
After a release executes via Governance, you can use release:verify-deployed:foundry again to check that the resulting network state does indeed reflect the tagged release candidate:
# Run from `packages/protocol` in the celo-monorepoN=18RELEASE="core-contracts.v${N}"NETWORK="celo-sepolia" # "anvil", "celo-sepolia" or "mainnet"yarn release:verify-deployed:foundry -n $NETWORK -b $RELEASE -f
After a successful release execution on a testnet, the resulting network state should be spot-checked to ensure that no regressions have been caused by the release. Flows to test include:
A ceiling on the gas consumption for all common operations should be defined and enforced by automated checks run on every commit.For troubleshooting please see Readme.md of protocol package.
Automated checks should ensure that any new commit to master does not introduce a breaking change to storage layout, ABI, or other common backward compatibility issues unless the STORAGE or MAJOR version numbers are incremented.Backwards compatibility tests will also be run before every release to confirm that no breaking changes exist between the pending release and deployed smart contracts.
If patches need to be applied before the next scheduled smart contract release, they should be cherry-picked to a new release branch, branched from the latest deployed release branch.
Deploying a new contract release should occur with the following process. On-chain governance proposals should be submitted on Tuesdays for consistency and predictability.
Date
Action
T
Create a Github issue tracking all these checklist items as an audit
log
Let the community know about the upcoming release proposal by posting
details to the Governance category on https://forum.celo.org and cross
post in the
Discord #governance channel.
See the ‘Communication guidelines’ section below for information on what
your post should contain.
T+2w
Confirm all contracts working as intended on an Anvil testnet.
Run the smart contract release scriptin order to to deploy the contracts to Celo Sepolia as well as submit a
governance proposal.
Update your forum post with the Celo Sepolia PROPOSAL_ID,
updated timings (if any changes), and notify the community in the
Discord #governance channel.
T+3w
Confirm all contracts working as intended on Celo Sepolia.
Confirm audit is complete and make the release notes and forum post
contain a link to it.
On Tuesday: Run the smart contract release scriptin order to to deploy the contracts to Mainnet as well as submit a
governance proposal.
Update the corresponding governance proposal with the updated on-chain
PROPOSAL_ID and mark CGP status as “PROPOSED”.
Update your forum post with the Mainnet PROPOSAL_ID,
updated timings (if any changes), and notify the community in the
Discord #governance channel.
At this point all stakeholders are encouraged to
verify the proposed contracts
deployed match the contracts from the release branch.
Currently the governance process should take approximately 1 week:
24 hours for the dequeue process, 24 hours for the approval
process, and 5 days for the referendum process. After which, the
proposal is either declined or is ready to be executed within 3
days.
For updated timeframes, use the celocli:
celocli network:parameters
T+5w
If the proposal passed:
Confirm all contracts working as intended on Mainnet.
Update your forum post with the Mainnet governance outcome (
Passed or Rejected) and notify the
community in the Discord #governance channel.
Change corresponding CGP status to EXECUTED.
Merge the release branch into master with a merge
commit
If the proposal failed:
Change corresponding CGP status to EXPIRED.
If the contents of the release (i.e. source Git commit) change at any point after the release has been tagged in Git, the process should increment the release identifier, and process should start again from the beginning. If the changes are small or do not introduce new code (e.g. reverting a contract to a previous version) the audit step may be accelerated.
Communicating the upcoming governance proposal to the community is critical and may help getting it approved.Each smart contract release governance proposal should be accompanied by a Governance category forum post that contains the following information:
Name of proposer (individual contributor or organization).
Background information.
Link to the release on Github.
Link to the audit report(s).
Anticipated timings for the Celo Sepolia testnet and Mainnet.
Make sure to keep the post up to date. All updates (excluding fixing typos) should be communicated to the community in the Discord#governance channel.
{"docsConfig":{"theme":"aspen","$schema":"https://mintlify.com/docs.json","name":"Celo Docs","description":"Learn to develop on the Ethereum L2 built for the real world. Access guides, APIs, and tools for fast, affordable blockchain applications","colors":{"primary":"#000000","light":"#fcff52","dark":"#000000"},"logo":{"light":"https://mintcdn.com/celo-64ac69bd/0WkPc8r8miw6rJ0o/images/CeloDocs_LogoLight.svg?fit=max\u0026auto=format\u0026n=0WkPc8r8miw6rJ0o\u0026q=85\u0026s=9d6c38002bd204ed66ca9db0782aecf9","dark":"https://mintcdn.com/celo-64ac69bd/0WkPc8r8miw6rJ0o/images/CeloDocs_LogoDark.svg?fit=max\u0026auto=format\u0026n=0WkPc8r8miw6rJ0o\u0026q=85\u0026s=020f629b1f5797de98cb1aed37d8a3a7"},"favicon":"https://mintcdn.com/celo-64ac69bd/0WkPc8r8miw6rJ0o/images/CeloDocs_Favicon_64px.png?fit=max\u0026auto=format\u0026n=0WkPc8r8miw6rJ0o\u0026q=85\u0026s=7ba4295bda57bbba69fb5e4d52e86db9","appearance":{"default":"dark"},"background":{"color":{"light":"#FCF6F1","dark":"#0b0d10"}},"navbar":{"links":[{"href":"https://discord.com/invite/celo","label":"Community"},{"href":"https://celo.org","label":"Celo.org"}],"primary":{"type":"button","label":"GitHub","href":"https://github.com/celo-org"}},"footer":{"links":[{"header":"Community","items":[{"label":"Forum","href":"https://forum.celo.org/"},{"label":"Contributors","href":"/contribute"}]},{"header":"Socials","items":[{"label":"Youtube","href":"https://www.youtube.com/@CeloOrg"},{"label":"Discord","href":"https://discord.com/invite/celo"},{"label":"X","href":"https://x.com/Celo"},{"label":"Events","href":"https://luma.com/user/usr-QJkvU5EML2BJeYc"},{"label":"Celo Developers newsletter","href":"https://celo-devs.beehiiv.com/subscribe"}]}]},"seo":{"organization":{"name":"Celo","url":"https://celo.org","logo":"https://docs.celo.org/logo/celo_light.png","sameAs":["https://github.com/celo-org","https://x.com/Celo","https://www.youtube.com/@CeloOrg","https://discord.com/invite/celo","https://forum.celo.org/","https://l2beat.com/scaling/projects/celo"]}},"fonts":{"heading":{"family":"system-ui"},"body":{"family":"system-ui"}},"integrations":{"ga4":{"measurementId":"G-0CXEKQ81V2"}},"banner":{"content":"🤖 **Agents on Open Rails** | Celo’s global hackathon — $5,000 in prizes, kicks off Oct 6. [Join the hackathon](https://www.loops.house/agents-on-open-rails)","dismissible":true},"contextual":{"options":["copy","view","mcp","chatgpt","claude","cursor","vscode",{"title":"Edit on GitHub","description":"Open the docs repository to edit a page and raise a pull request","icon":"github","href":"https://github.com/celo-org/docs"}],"display":"header"},"styling":{"latex":false},"navigation":{"global":{"anchors":[{"anchor":"Docs for AI","icon":"robot","href":"/build/agents/use-docs-with-ai"},{"anchor":"Organization","icon":"globe","href":"https://celo.org/"},{"anchor":"Support","icon":"bullhorn","href":"https://discord.com/invite/celo"},{"anchor":"Forum","icon":"newspaper","href":"https://forum.celo.org/"},{"anchor":"Faucet","icon":"faucet","href":"https://faucet.celo.org/celo-sepolia"},{"anchor":"FAQs","icon":"square-question","href":"https://docs.celo.org/operate/operators/faq"}]},"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"celo-64ac69bd","hasAudioNarration":false,"actualSubdomain":"celo-64ac69bd","customDomains":["docs.celo.org"],"gitSource":{"type":"github","owner":"celo-org","repo":"docs","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"entitlements":{"AI_CHAT":{"status":"DISABLED"}},"buildId":"6af20dff81dc2bd14370d520","clientVersion":"0.0.4094","searchFilterCounts":[{"language":"default","tag":"Build","count":130},{"language":"default","tag":"Tools","count":85},{"language":"default","tag":"Learn","count":44},{"language":"default","tag":"Libraries \u0026 SDKs","count":40},{"language":"default","tag":"Operate","count":39},{"language":"default","tag":"CLI","count":21},{"language":"default","tag":"Agents","count":18},{"language":"default","tag":"Contribute","count":15},{"language":"default","tag":"Guides","count":12},{"language":"default","tag":"Wallets","count":11}]},"assistantConfig":{"enableAskAiButton":true,"enableAskAiSearchBar":true,"deflection":{"enabled":true,"email":"community@celo.org"}},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"comment-mode","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[{"filePath":"style.css","content":".colored_text a{color:inherit!important}ol ol{list-style-type:lower-roman!important}"}],"page":{"pagePath":"contribute/release-process/smart-contracts","slug":"/contribute/release-process/smart-contracts","pageMetadata":{"title":"Smart Contracts Release Process","sidebarTitle":"Smart Contracts","description":"Details of the release process for updating smart contracts on the Celo platform.","href":"/contribute/release-process/smart-contracts"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Details of the release process for updating smart contracts on the Celo platform.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,hr:`hr`,li:`li`,ol:`ol`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsx(_components.p,{children:`Details of the release process for updating smart contracts on the Celo platform.`}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Warning,{children:_jsx(_components.p,{children:`This release process is a work in progress. Many infrastructure components required to execute it are not in place, and the process itself is subject to change.`})}),`\n`,_jsx(Heading,{level:`2`,id:`versioning`,children:`Versioning`}),`\n`,_jsxs(_components.p,{children:[`Each deployed Celo core smart contract is versioned independently, according to semantic versioning, as described at `,_jsx(_components.a,{href:`https://semver.org`,children:`semver.org`}),`, with the following modifications:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`STORAGE version when you make incompatible storage layout changes`}),`\n`,_jsx(_components.li,{children:`MAJOR version when you make incompatible ABI changes`}),`\n`,_jsx(_components.li,{children:`MINOR version when you add functionality in a backwards compatible manner, and`}),`\n`,_jsx(_components.li,{children:`PATCH version when you make backwards compatible bug fixes.`}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Changes to core smart contracts are made via on-chain Governance, approximately four times a year. When a release is made, `,_jsx(_components.strong,{children:`all`}),` smart contracts from the release branch that differ from the deployed smart contracts are released, and included in the `,_jsx(_components.strong,{children:`same`}),` governance proposal. Each release is identified by a unique monotonically increasing version number `,_jsx(_components.code,{children:`N`}),`, with `,_jsx(_components.code,{children:`1`}),` being the first release.`]}),`\n`,_jsx(Heading,{level:`3`,id:`core-contracts`,children:`Core Contracts`}),`\n`,_jsxs(_components.p,{children:[`Every deployed Celo core contract has its current version number as a constant which is publicly accessible via the `,_jsx(_components.code,{children:`getVersionNumber()`}),` function, which returns the storage, major, minor, and patch versions. The version number is encoded in the Solidity source and updated as part of code changes.`]}),`\n`,_jsxs(_components.p,{children:[`Celo Core Contracts deployed to a live network without the `,_jsx(_components.code,{children:`getVersionNumber()`}),` function, such as the original set of core contracts, are to be considered version `,_jsx(_components.code,{children:`1.1.0.0`}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`mixins-and-libraries`,children:`Mixins and libraries`}),`\n`,_jsx(_components.p,{children:`Mixin contracts and libraries are considered part of the contracts that consume them. When a mixin or library has changed, all contracts that consume them should be considered to have changed as well, and thus the contracts should have their version numbers incremented and should be re-deployed as part of the next smart contract release.`}),`\n`,_jsx(Heading,{level:`3`,id:`initialize-data`,children:`Initialize Data`}),`\n`,_jsxs(_components.p,{children:[`Whenever Celo Core Contracts need to be re-initialized, their initialization arguments should be checked into version control under `,_jsx(_components.code,{children:\"packages/protocol/releaseData/initializationData/release${N}.json\"}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`release-management-in-git/github`,children:`Release management in Git/Github`}),`\n`,_jsxs(_components.p,{children:[`Github branches/tags and Github releases are used to coordinate past and ongoing releases. Ongoing smart contract development is done on the `,_jsx(_components.code,{children:`master`}),` branch (even after release branches are cut). Every smart contract release has a designated release branch, e.g. `,_jsx(_components.code,{children:\"release/core-contracts/${N}\"}),` in the celo-monorepo.`]}),`\n`,_jsx(Heading,{level:`4`,id:`when-a-new-release-branch-is-cut`,children:`When a new release branch is cut:`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`A new release branch is created `,_jsx(_components.code,{children:\"release/core-contracts/${N}\"}),` with the contracts to be audited.`]}),`\n`,_jsxs(_components.li,{children:[`The latest commit on the release branch is tagged with `,_jsx(_components.code,{children:\"core-contracts.v${N}.pre-audit\"}),`.`]}),`\n`,_jsx(_components.li,{children:`On Github, a pre-release Github release should be created pointing at the latest tag on the release branch.`}),`\n`,_jsxs(_components.li,{children:[`On master branch, `,_jsx(_components.code,{children:`.github/workflows/celo-monorepo.yml`}),` should be edited so that the variable `,_jsx(_components.code,{children:`RELEASE_TAG`}),` points to the tag `,_jsx(_components.code,{children:\"core-contracts.v${N}.pre-audit\"}),` so that all future changes to master are versioned against the new release.`]}),`\n`,_jsxs(_components.li,{children:[`Ongoing audit responses/fixes should continue to go into `,_jsx(_components.code,{children:\"release/celo-core-contracts/${N}\"}),`.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`4`,id:`after-a-completed-release-process`,children:`After a completed release process:`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`The release branch should be merged into `,_jsx(_components.code,{children:`master`}),` with a merge commit (instead of the usual squash merge strategy).`]}),`\n`,_jsxs(_components.li,{children:[`On master branch, `,_jsx(_components.code,{children:`.github/workflows/celo-monorepo.yml`}),` should be edited so that the variable `,_jsx(_components.code,{children:`RELEASE_TAG`}),` points to the tag `,_jsx(_components.code,{children:\"core-contracts.v${N}\"})]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`release-process`,children:`Release Process`}),`\n`,_jsxs(_components.p,{children:[`There are several scripts provided (under `,_jsx(_components.code,{children:`packages/protocol`}),` in `,_jsx(_components.a,{href:`https://github.com/celo-org/celo-monorepo`,children:`celo-org/celo-monorepo`}),` and via `,_jsx(_components.a,{href:`/cli/`,children:`celocli`}),`). The release owners’ own reference is `,_jsx(_components.a,{href:`https://github.com/celo-org/celo-monorepo/blob/master/packages/protocol/RELEASE_PROCESS_FOUNDRY.md`,children:_jsx(_components.code,{children:`RELEASE_PROCESS_FOUNDRY.md`})}),`, which maps each retired Truffle command to its Foundry replacement. These are for use in the release process and with contract upgrade governance proposals to give participating stakeholders increased confidence.`]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[`For these to run, you may need to set up the celo-monorepo: follow the `,_jsx(_components.a,{href:`https://github.com/celo-org/celo-monorepo/blob/045aa0061/README.md#-getting-started`,children:`Getting Started`}),` steps and install the Node version pinned in `,_jsx(_components.a,{href:`https://github.com/celo-org/celo-monorepo/blob/045aa0061/.nvmrc`,children:_jsx(_components.code,{children:`.nvmrc`})}),` (managed with `,_jsx(_components.code,{children:`nvm`}),`). A successful `,_jsx(_components.code,{children:`yarn install`}),` and `,_jsx(_components.code,{children:`yarn build`}),` in the protocol package signal a completed setup. The release scripts also shell out to `,_jsx(_components.a,{href:`https://getfoundry.sh`,children:`Foundry`}),` (`,_jsx(_components.code,{children:`forge`}),`, `,_jsx(_components.code,{children:`cast`}),`) and `,_jsx(_components.code,{children:`jq`}),`, so install those too.`]})}),`\n`,_jsx(_components.p,{children:`Using these tools, a contract release candidate can be built, deployed, and proposed for upgrade automatically on a specified network. Subsequently, stakeholders can verify the release candidate against a governance upgrade proposal’s contents on the network.`}),`\n`,_jsx(_components.p,{children:`Typical script options:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`By default, the scripts expect a celo-blockchain RPC at port 8545 locally. With `,_jsx(_components.code,{children:`-f`}),` you can specify the scripts to use a hosted forno node`]}),`\n`,_jsxs(_components.li,{children:[`By default, scripts will output verbose logs under `,_jsx(_components.code,{children:\"/tmp/celo-${script-name}.log\"}),`. You can change the location of the log output with `,_jsx(_components.code,{children:`-l file.log`})]}),`\n`]}),`\n`,_jsx(Heading,{level:`3`,id:`view-the-tagged-releases-for-each-network`,children:`View the tagged releases for each network`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`yarn`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` tags:view`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`3`,id:`verify-the-previous-release-on-the-network`,children:`Verify the previous Release on the Network`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`release:verify-deployed:foundry`}),` is a script that allows you to assess whether the bytecode on the given network matches the source code of a particular commit. It will run through the Celo Core Contracts and verify that the contracts’ bytecodes as specified in the `,_jsx(_components.code,{children:`Registry`}),` match. Here, we will want to sanity-check that our network is running the previous release’s audited commit.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`6`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`6`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:\"# Run from `packages/protocol` in the celo-monorepo\"})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`N`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`18`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # the release being prepared`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`PREVIOUS_RELEASE`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"core-contracts.v$((`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`N-1`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`))\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`NETWORK`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"celo-sepolia\"`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # \"anvil\", \"celo-sepolia\" or \"mainnet\"`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# A -f boolean flag can be provided to use a forno full node to connect to the provided network`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`yarn`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` release:verify-deployed:foundry`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -n`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $NETWORK`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -b`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $PREVIOUS_RELEASE`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -f`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`A `,_jsx(_components.code,{children:`$NETWORK-$PREVIOUS_RELEASE-libraries.json`}),` file is written to disk describing linked library addresses. `,_jsx(_components.code,{children:`release:make:foundry`}),` requires it.`]}),`\n`,_jsx(Heading,{level:`3`,id:`check-backward-compatibility`,children:`Check Backward Compatibility`}),`\n`,_jsx(_components.p,{children:`This script performs some automatic checks to ensure that the smart contract versions in the source code have been set correctly with respect to the latest release. It is run as part of CI and helps ensure that backwards incompatibilities are not accidentally introduced by requiring that devs manually update version numbers whenever smart contract changes are made.`}),`\n`,_jsx(_components.p,{children:`Specifically, it compiles the latest and candidate releases and compares smart contracts:`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsx(_components.li,{children:`Storage layout, to detect storage version changes`}),`\n`,_jsx(_components.li,{children:`ABI, to detect major and minor version changes`}),`\n`,_jsx(_components.li,{children:`Bytecode, to detect patch version changes`}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Finally, it checks release candidate smart contract version numbers and requires that they have been updated appropriately since the latest release by following semantic versioning as defined in the `,_jsx(_components.a,{href:`#versioning`,children:`Versioning section`}),` above.`]}),`\n`,_jsx(_components.p,{children:`The following exceptions apply:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`If the STORAGE version has changed, it does not perform backward compatibility checks`}),`\n`,_jsx(_components.li,{children:`If the MAJOR version has changed, it checks storage layout compatibility but not ABI compatibility`}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Critically, this ensures that proxied contracts do not experience storage\ncollisions between implementation versions. See `,_jsx(_components.a,{href:`https://docs.openzeppelin.com/upgrades-plugins/proxies#storage-collisions-between-implementation-versions`,children:`this\narticle`}),`\nby OpenZeppelin for a good overview of this problem and why it’s important to\ncheck for it.`]}),`\n`,_jsxs(_components.p,{children:[`The script generates a detailed report on version changes in JSON format, written to `,_jsx(_components.code,{children:`report-$PREVIOUS_RELEASE-$RELEASE_CANDIDATE.json`}),`.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`5`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`5`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:\"# Run from `packages/protocol` in the celo-monorepo\"})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`N`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`18`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`PREVIOUS_RELEASE`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"core-contracts.v$((`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`N-1`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`))\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`RELEASE_CANDIDATE`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:'\"core-contracts.v${'}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`N`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`}\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`yarn`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` release:check-versions:foundry`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -a`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $PREVIOUS_RELEASE`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -b`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $RELEASE_CANDIDATE`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`This should be used in tandem with `,_jsx(_components.code,{children:`release:verify-deployed:foundry -b $PREVIOUS_RELEASE -n $NETWORK`}),` to ensure the compatibility checks compare the release candidate to what is actually active on the network.`]}),`\n`,_jsx(Heading,{level:`3`,id:`deploy-the-release-candidate`,children:`Deploy the release candidate`}),`\n`,_jsxs(_components.p,{children:[`Use the following script to build and deploy a candidate release. This takes as input the corresponding backward compatibility report and canonical library address mapping to deploy `,_jsx(_components.strong,{children:`changed`}),` contracts to the specified network. The Foundry script has no dry-run; pass `,_jsx(_components.code,{children:`-u`}),` with a local anvil fork’s RPC URL to rehearse it.\nSTORAGE updates are adopted by deploying a new proxy/implementation pair. This script writes a JSON contract upgrade governance proposal to `,_jsx(_components.code,{children:`proposal-$NETWORK-$RELEASE_CANDIDATE.json`}),`.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`7`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`7`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:\"# Run from `packages/protocol` in the celo-monorepo\"})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`N`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`18`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`NETWORK`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"celo-sepolia\"`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # \"anvil\", \"celo-sepolia\" or \"mainnet\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`PREVIOUS_RELEASE`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"core-contracts.v$((`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`N-1`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`))\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`RELEASE_CANDIDATE`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:'\"core-contracts.v${'}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`N`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`}\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`PRIVATE_KEY`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"0x...\"`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # deployer key for $NETWORK`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`yarn`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` release:make:foundry`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -b`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $RELEASE_CANDIDATE`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -n`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $NETWORK`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -r`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"report-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`$PREVIOUS_RELEASE`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`$RELEASE_CANDIDATE`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`.json\"`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -i`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:' \"releaseData/initializationData/release${'}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`N`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`}.json\"`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -l`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`$NETWORK`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`$PREVIOUS_RELEASE`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`-libraries.json\"`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -k`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`$PRIVATE_KEY`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"`})]}),`\n`]})})}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[_jsx(_components.code,{children:`-k \"$PRIVATE_KEY\"`}),` puts the deployer key on the command line, where it is readable by other processes on the machine (for example via `,_jsx(_components.code,{children:`/proc`}),` on Linux) and is written to your shell history. Run it from a dedicated deploy machine, and clear the key from the environment and history afterwards.`]})}),`\n`,_jsx(_components.p,{children:`The proposal encodes STORAGE updates by repointing the Registry to the new proxy. Storage compatible upgrades are encoded by repointing the existing proxy’s implementation.`}),`\n`,_jsx(Heading,{level:`3`,id:`submit-upgrade-proposal`,children:`Submit Upgrade Proposal`}),`\n`,_jsx(_components.p,{children:`Submit the autogenerated upgrade proposal to the Governance contract for review by voters, outputting a unique identifier.`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`6`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`6`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# resultant proposal ID should be communicated publicly`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`N`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`18`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`NETWORK`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"celo-sepolia\"`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # \"anvil\", \"celo-sepolia\" or \"mainnet\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`RELEASE_CANDIDATE`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:'\"core-contracts.v${'}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`N`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`}\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`YOUR_ADDRESS`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"0x...\"`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # proposer account; must hold the deposit`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`celocli`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` governance:propose`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --deposit`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 100e18`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --from`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $YOUR_ADDRESS`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --jsonTransactions`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"proposal-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`$NETWORK`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`$RELEASE_CANDIDATE`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`.json\"`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --descriptionURL`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` https://github.com/celo-org/governance/blob/main/CGPs/cgp-0055.md`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`3`,id:`fetch-upgrade-proposal`,children:`Fetch Upgrade Proposal`}),`\n`,_jsx(_components.p,{children:`Fetch the upgrade proposal and output the JSON encoded proposal contents.`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Make sure you run at least celocli 0.0.60`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`celocli`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` governance:show`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --proposalID`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`proposalI`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`d`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --jsonTransactions`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"upgrade_proposal.json\"`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`3`,id:`verify-proposed-release-candidate`,children:`Verify Proposed Release Candidate`}),`\n`,_jsxs(_components.p,{children:[`This script serves the same purpose as `,_jsx(_components.code,{children:`release:verify-deployed:foundry`}),` but for a not-yet\naccepted contract upgrade (in the form of the `,_jsx(_components.code,{children:`upgrade_proposal.json`}),` you fetched in the step prior). It gives you the confidence that the branch specified in the `,_jsx(_components.code,{children:`-b`}),` flag in (same as `,_jsx(_components.code,{children:`release:check-versions:foundry`}),`) will be the resulting network state of the proposal if executed. It does so by going over all Celo Core Contracts and determining updates to the Registry pointers, proxy or implementation contracts and verifying their implied bytecode against the compiled source code.`]}),`\n`,_jsxs(_components.p,{children:[`Additionally, include `,_jsx(_components.code,{children:`initialization_data.json`}),` from the CGP if any of the contracts have to be initialized.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`6`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`6`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:\"# Run from `packages/protocol` in the celo-monorepo\"})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`N`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`18`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`RELEASE_CANDIDATE`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:'\"core-contracts.v${'}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`N`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`}\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`NETWORK`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"celo-sepolia\"`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # \"anvil\", \"celo-sepolia\" or \"mainnet\"`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# A -f boolean flag can be provided to use a forno full node to connect to the provided network`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`yarn`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` release:verify-deployed:foundry`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -p`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"upgrade_proposal.json\"`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -b`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $RELEASE_CANDIDATE`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -n`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $NETWORK`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -f`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -i`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` initialization_data.json`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`3`,id:`verify-executed-release`,children:`Verify Executed Release`}),`\n`,_jsxs(_components.p,{children:[`After a release executes via Governance, you can use `,_jsx(_components.code,{children:`release:verify-deployed:foundry`}),` again to check that the resulting network state does indeed reflect the tagged release candidate:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`5`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`5`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:\"# Run from `packages/protocol` in the celo-monorepo\"})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`N`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`18`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`RELEASE`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:'\"core-contracts.v${'}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`N`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`}\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`NETWORK`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"celo-sepolia\"`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # \"anvil\", \"celo-sepolia\" or \"mainnet\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`yarn`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` release:verify-deployed:foundry`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -n`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $NETWORK`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -b`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $RELEASE`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -f`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`2`,id:`testing`,children:`Testing`}),`\n`,_jsx(_components.p,{children:`All releases should be evaluated according to the following tests.`}),`\n`,_jsx(Heading,{level:`3`,id:`unit-tests`,children:`Unit tests`}),`\n`,_jsx(_components.p,{children:`All changes since the last release should be covered by unit tests. Unit test coverage should be enforced by automated checks run on every commit.`}),`\n`,_jsx(Heading,{level:`3`,id:`manual-checklist`,children:`Manual Checklist`}),`\n`,_jsx(_components.p,{children:`After a successful release execution on a testnet, the resulting network state should be spot-checked to ensure that no regressions have been caused by the release. Flows to test include:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`Do a USDm and CELO transfer`,`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`celocli`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` transfer:dollars`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --from`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`add`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`r`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --value`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`numbe`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`r`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --to`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`add`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`r`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`celocli`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` transfer:celo`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --from`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`add`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`r`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --value`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`numbe`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`r`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --to`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`add`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`r`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`})]}),`\n`]})})}),`\n`]}),`\n`,_jsxs(_components.li,{children:[`Register a Celo account`,`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`celocli`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` account:register`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --from`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`add`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`r`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --name`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`test-nam`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`e`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`})]}),`\n`]})})}),`\n`]}),`\n`,_jsxs(_components.li,{children:[`Report an Oracle rate`,`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`celocli`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` oracle:report`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --from`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`add`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`r`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --value`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`nu`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`m`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`})]}),`\n`]})})}),`\n`]}),`\n`,_jsxs(_components.li,{children:[`Do a CP-DOTO exchange`,`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`celocli`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` exchange:celo`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --value`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`numbe`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`r`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --from`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`add`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`r`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`celocli`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` exchange:dollars`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --value`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`numbe`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`r`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --from`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`add`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`r`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`})]}),`\n`]})})}),`\n`]}),`\n`,_jsx(_components.li,{children:`Complete a round of attestation`}),`\n`,_jsx(_components.li,{children:`Redeem from Escrow`}),`\n`,_jsxs(_components.li,{children:[`Register a Validator`,`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`celocli`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` validator:register`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --blsKey`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`hexStrin`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`g`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --blsSignature`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`hexStrin`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`g`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --ecdsaKey`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`hexStrin`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`g`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --from`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`add`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`r`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`})]}),`\n`]})})}),`\n`]}),`\n`,_jsx(_components.li,{children:`Vote for a Validator`}),`\n`,_jsxs(_components.li,{children:[`Run a mock election`,`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`celocli`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` election:run`})]}),`\n`]})})}),`\n`]}),`\n`,_jsx(_components.li,{children:`Get a validator slashed for downtime and ejected from the validator set`}),`\n`,_jsxs(_components.li,{children:[`Propose a governance proposal and get it executed`,`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`celocli`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` governance:propose`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --jsonTransactions`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`jsonFil`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`e`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --deposit`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`numbe`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`r`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --from`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`add`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`r`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --descriptionURL`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` https://gist.github.com/yorhodes/46430eacb8ed2f73f7bf79bef9d58a33`})]}),`\n`]})})}),`\n`]}),`\n`]}),`\n`,_jsx(Heading,{level:`3`,id:`automated-environment-tests`,children:`Automated environment tests`}),`\n`,_jsxs(_components.p,{children:[`Stakeholders can use the `,_jsx(_components.code,{children:`env-tests`}),` package in `,_jsx(_components.code,{children:`celo-monorepo`}),` to run an automated test suite against the network`]}),`\n`,_jsx(Heading,{level:`3`,id:`verify-smart-contracts`,children:`Verify smart contracts`}),`\n`,_jsxs(_components.p,{children:[`Verification of smart contracts should be done both on `,_jsx(_components.a,{href:`https://celoscan.io/`,children:`https://celoscan.io/`}),` and `,_jsx(_components.a,{href:`https://celo.blockscout.com/`,children:`https://celo.blockscout.com/`}),`.`]}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/developer/verify/celoscan`,children:`Update your Smart Contract on celoscan`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/developer/verify/blockscout`,children:`Update your Smart Contract on Blockscout`})}),`\n`]}),`\n`,_jsx(Heading,{level:`3`,id:`performance`,children:`Performance`}),`\n`,_jsx(_components.p,{children:`A ceiling on the gas consumption for all common operations should be defined and enforced by automated checks run on every commit.`}),`\n`,_jsx(_components.p,{children:`For troubleshooting please see Readme.md of protocol package.`}),`\n`,_jsx(Heading,{level:`3`,id:`backwards-compatibility`,children:`Backwards compatibility`}),`\n`,_jsxs(_components.p,{children:[`Automated checks should ensure that any new commit to `,_jsx(_components.code,{children:`master`}),` does not introduce a breaking change to storage layout, ABI, or other common backward compatibility issues unless the STORAGE or MAJOR version numbers are incremented.`]}),`\n`,_jsx(_components.p,{children:`Backwards compatibility tests will also be run before every release to confirm that no breaking changes exist between the pending release and deployed smart contracts.`}),`\n`,_jsx(Heading,{level:`3`,id:`audits`,children:`Audits`}),`\n`,_jsx(_components.p,{children:`All changes since the last release should be audited by a reputable third party auditor.`}),`\n`,_jsx(Heading,{level:`3`,id:`emergency-patches`,children:`Emergency patches`}),`\n`,_jsx(_components.p,{children:`If patches need to be applied before the next scheduled smart contract release, they should be cherry-picked to a new release branch, branched from the latest deployed release branch.`}),`\n`,_jsx(Heading,{level:`2`,id:`promotion-process`,children:`Promotion process`}),`\n`,_jsx(_components.p,{children:`Deploying a new contract release should occur with the following process. On-chain governance proposals should be submitted on Tuesdays for consistency and predictability.`}),`\n`,_jsxs(`table`,{children:[_jsxs(`tr`,{children:[_jsx(`td`,{children:`Date`}),_jsx(`td`,{children:`Action`})]}),_jsxs(`tr`,{children:[_jsx(`td`,{children:`T`}),_jsx(`td`,{children:_jsxs(`ol`,{children:[_jsx(`li`,{children:_jsx(_components.p,{children:`Create a Github issue tracking all these checklist items as an audit\nlog`})}),_jsx(`li`,{children:_jsxs(_components.p,{children:[`Implement the`,` `,`\n`,_jsx(`a`,{href:`#when-a-new-release-branch-is-cut`,children:`git management steps`}),` `,`\nfor when a new release branch is cut.`]})}),_jsx(`li`,{children:_jsx(_components.p,{children:`Submit the release branch to a reputable third party auditor for review.`})}),_jsx(`li`,{children:`Begin drafting release notes.`})]})})]}),_jsxs(`tr`,{children:[_jsx(`td`,{children:`T+1w`}),_jsx(`td`,{children:_jsxs(`ol`,{children:[_jsx(`li`,{children:`Receive report from auditors.`}),_jsx(`li`,{children:`Add audit summary to the final draft of the release notes.`}),_jsxs(`li`,{children:[_jsx(_components.p,{children:`If all issues in the audit report have straightforward fixes:`}),_jsxs(`ol`,{children:[_jsxs(`li`,{children:[` `,_jsxs(_components.p,{children:[`Submit a governance proposal draft using this `,_jsx(_components.a,{href:`https://github.com/celo-org/governance/blob/main/CGPs/cgp-template.md`,children:`format: `})]})]}),_jsxs(`li`,{children:[` `,_jsx(_components.p,{children:`Add any initialization data to the CGP that should be included as\npart of the proposal`})]}),_jsxs(`li`,{children:[` `,_jsxs(_components.p,{children:[`Announce forthcoming smart contract release on:\n`,_jsx(_components.a,{href:`https://forum.celo.org/c/governance`,children:`https://forum.celo.org/c/governance`})]})]})]})]}),_jsx(`li`,{children:`Commit audit fixes to the release branch`}),_jsx(`li`,{children:`Submit audit fixes to auditors for review.`}),_jsxs(`li`,{children:[_jsxs(_components.p,{children:[`Tag the first release candidate commit according to the`,` `]}),_jsx(`a`,{href:`#release-management-in-git/github`,children:_jsx(_components.p,{children:`git release management instructions`})}),_jsx(_components.p,{children:`.`})]}),_jsx(`li`,{children:_jsxs(_components.p,{children:[`Let the community know about the upcoming release proposal by posting\ndetails to the Governance category on `,_jsx(_components.a,{href:`https://forum.celo.org`,children:`https://forum.celo.org`}),` and cross\npost in the`,` `,`\n`,_jsxs(`a`,{href:`https://discord.com/channels/600834479145353243/704805825373274134`,children:[`Discord `,_jsx(`code`,{children:`#governance`}),` channel.`]}),`\nSee the ‘Communication guidelines’ section below for information on what\nyour post should contain.`]})})]})})]}),_jsxs(`tr`,{children:[_jsx(`td`,{children:`T+2w`}),_jsx(`td`,{children:_jsxs(`ol`,{children:[_jsx(`li`,{children:`Confirm all contracts working as intended on an Anvil testnet.`}),_jsxs(`li`,{children:[_jsxs(_components.p,{children:[`Run the`,` `]}),_jsx(`a`,{href:`#release-process`,children:_jsx(_components.p,{children:`smart contract release script`})}),` `,_jsx(_components.p,{children:`in order to to deploy the contracts to Celo Sepolia as well as submit a\ngovernance proposal.`})]}),_jsx(`li`,{children:_jsxs(_components.p,{children:[`Update your forum post with the Celo Sepolia `,_jsx(`code`,{children:`PROPOSAL_ID`}),`,\nupdated timings (if any changes), and notify the community in the\nDiscord `,_jsx(`code`,{children:`#governance`}),` channel.`]})})]})})]}),_jsxs(`tr`,{children:[_jsx(`td`,{children:`T+3w`}),_jsx(`td`,{children:_jsxs(`ol`,{children:[_jsx(`li`,{children:`Confirm all contracts working as intended on Celo Sepolia.`}),_jsx(`li`,{children:_jsx(_components.p,{children:`Confirm audit is complete and make the release notes and forum post\ncontain a link to it.`})}),_jsxs(`li`,{children:[_jsxs(_components.p,{children:[`On Tuesday: Run the`,` `]}),_jsx(`a`,{href:`#deploy-the-release-candidate`,children:_jsx(_components.p,{children:`smart contract release script`})}),` `,_jsx(_components.p,{children:`in order to to deploy the contracts to Mainnet as well as submit a\ngovernance proposal.`})]}),_jsx(`li`,{children:_jsxs(_components.p,{children:[`Update the corresponding governance proposal with the updated on-chain`,` `,`\n`,_jsx(`code`,{children:`PROPOSAL_ID`}),` and mark CGP status as “PROPOSED”.`]})}),_jsx(`li`,{children:_jsxs(_components.p,{children:[`Update your forum post with the Mainnet `,_jsx(`code`,{children:`PROPOSAL_ID`}),`,\nupdated timings (if any changes), and notify the community in the\nDiscord `,_jsx(`code`,{children:`#governance`}),` channel.`]})}),_jsx(`li`,{children:_jsxs(_components.p,{children:[`At this point all stakeholders are encouraged to`,` `,`\n`,_jsx(`a`,{href:`#verify-proposed-release-candidate`,children:`verify`}),` the proposed contracts\ndeployed match the contracts from the release branch.`]})}),_jsxs(`li`,{children:[_jsxs(_components.p,{children:[`Monitor the progress of the proposal through the`,` `,`\n`,_jsx(_components.a,{href:`/learn/protocol/governance/overview`,children:`governance process.`})]}),_jsxs(`ul`,{children:[_jsx(`li`,{children:_jsx(_components.p,{children:`Currently the governance process should take approximately 1 week:\n24 hours for the dequeue process, 24 hours for the approval\nprocess, and 5 days for the referendum process. After which, the\nproposal is either declined or is ready to be executed within 3\ndays.`})}),_jsx(`li`,{children:_jsxs(_components.p,{children:[`For updated timeframes, use the celocli:`,` `,`\n`,_jsx(`code`,{children:`celocli network:parameters`})]})})]})]})]})})]}),_jsxs(`tr`,{children:[_jsx(`td`,{children:`T+5w`}),_jsx(`td`,{children:_jsx(`ol`,{children:_jsxs(`li`,{children:[_jsx(_components.p,{children:`If the proposal passed:`}),_jsxs(`ol`,{children:[_jsx(`li`,{children:`Confirm all contracts working as intended on Mainnet.`}),_jsx(`li`,{children:_jsxs(_components.p,{children:[`Update your forum post with the Mainnet governance outcome (\n`,_jsx(`code`,{children:`Passed`}),` or `,_jsx(`code`,{children:`Rejected`}),`) and notify the\ncommunity in the Discord `,_jsx(`code`,{children:`#governance`}),` channel.`]})}),_jsx(`li`,{children:`Change corresponding CGP status to EXECUTED.`}),_jsx(`li`,{children:_jsxs(_components.p,{children:[`Merge the release branch into `,_jsx(`code`,{children:`master`}),` with a merge\ncommit`]})})]}),_jsxs(`li`,{children:[_jsx(_components.p,{children:`If the proposal failed:`}),_jsx(`ol`,{children:_jsx(`li`,{children:`Change corresponding CGP status to EXPIRED.`})})]})]})})})]})]}),`\n`,_jsx(_components.p,{children:`If the contents of the release (i.e. source Git commit) change at any point after the release has been tagged in Git, the process should increment the release identifier, and process should start again from the beginning. If the changes are small or do not introduce new code (e.g. reverting a contract to a previous version) the audit step may be accelerated.`}),`\n`,_jsx(Heading,{level:`3`,id:`communication-guidelines`,children:`Communication guidelines`}),`\n`,_jsx(_components.p,{children:`Communicating the upcoming governance proposal to the community is critical and may help getting it approved.`}),`\n`,_jsxs(_components.p,{children:[`Each smart contract release governance proposal should be accompanied by a `,_jsx(_components.a,{href:`https://forum.celo.org/c/governance/`,children:`Governance category`}),` forum post that contains the following information:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`Name of proposer (individual contributor or organization).`}),`\n`,_jsx(_components.li,{children:`Background information.`}),`\n`,_jsx(_components.li,{children:`Link to the release on Github.`}),`\n`,_jsx(_components.li,{children:`Link to the audit report(s).`}),`\n`,_jsx(_components.li,{children:`Anticipated timings for the Celo Sepolia testnet and Mainnet.`}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Make sure to keep the post up to date. All updates (excluding fixing typos) should be communicated to the community in the `,_jsx(_components.a,{href:`http://chat.celo.org/`,children:`Discord`}),` `,_jsx(_components.code,{children:`#governance`}),` channel.`]}),`\n`,_jsx(Heading,{level:`3`,id:`emergency-patches-2`,children:`Emergency patches`}),`\n`,_jsx(Warning,{children:_jsx(_components.p,{children:`Work in progress`})}),`\n`,_jsx(Heading,{level:`2`,id:`vulnerability-disclosure`,children:`Vulnerability Disclosure`}),`\n`,_jsxs(_components.p,{children:[`Vulnerabilities in smart contract releases should be disclosed according to the `,_jsx(_components.a,{href:`https://github.com/celo-org/celo-blockchain/blob/master/SECURITY.md`,children:`security policy`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`dependencies`,children:`Dependencies`}),`\n`,_jsx(_components.p,{children:`None`}),`\n`,_jsx(Heading,{level:`2`,id:`dependents`,children:`Dependents`}),`\n`,_jsx(Warning,{children:_jsx(_components.p,{children:`Work in progress`})})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Smart Contracts Release Process","sidebarTitle":"Smart Contracts","description":"Details of the release process for updating smart contracts on the Celo platform.","href":"/contribute/release-process/smart-contracts"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Versioning","slug":"versioning","depth":2,"children":[{"title":"Core Contracts","slug":"core-contracts","depth":3,"children":[]},{"title":"Mixins and libraries","slug":"mixins-and-libraries","depth":3,"children":[]},{"title":"Initialize Data","slug":"initialize-data","depth":3,"children":[]},{"title":"Release management in Git/Github","slug":"release-management-in-git/github","depth":3,"children":[]},{"title":"When a new release branch is cut:","slug":"when-a-new-release-branch-is-cut","depth":4,"children":[]},{"title":"After a completed release process:","slug":"after-a-completed-release-process","depth":4,"children":[]}]},{"title":"Release Process","slug":"release-process","depth":2,"children":[{"title":"View the tagged releases for each network","slug":"view-the-tagged-releases-for-each-network","depth":3,"children":[]},{"title":"Verify the previous Release on the Network","slug":"verify-the-previous-release-on-the-network","depth":3,"children":[]},{"title":"Check Backward Compatibility","slug":"check-backward-compatibility","depth":3,"children":[]},{"title":"Deploy the release candidate","slug":"deploy-the-release-candidate","depth":3,"children":[]},{"title":"Submit Upgrade Proposal","slug":"submit-upgrade-proposal","depth":3,"children":[]},{"title":"Fetch Upgrade Proposal","slug":"fetch-upgrade-proposal","depth":3,"children":[]},{"title":"Verify Proposed Release Candidate","slug":"verify-proposed-release-candidate","depth":3,"children":[]},{"title":"Verify Executed Release","slug":"verify-executed-release","depth":3,"children":[]}]},{"title":"Testing","slug":"testing","depth":2,"children":[{"title":"Unit tests","slug":"unit-tests","depth":3,"children":[]},{"title":"Manual Checklist","slug":"manual-checklist","depth":3,"children":[]},{"title":"Automated environment tests","slug":"automated-environment-tests","depth":3,"children":[]},{"title":"Verify smart contracts","slug":"verify-smart-contracts","depth":3,"children":[]},{"title":"Performance","slug":"performance","depth":3,"children":[]},{"title":"Backwards compatibility","slug":"backwards-compatibility","depth":3,"children":[]},{"title":"Audits","slug":"audits","depth":3,"children":[]},{"title":"Emergency patches","slug":"emergency-patches","depth":3,"children":[]}]},{"title":"Promotion process","slug":"promotion-process","depth":2,"children":[{"title":"Communication guidelines","slug":"communication-guidelines","depth":3,"children":[]},{"title":"Emergency patches","slug":"emergency-patches-2","depth":3,"children":[]}]},{"title":"Vulnerability Disclosure","slug":"vulnerability-disclosure","depth":2,"children":[]},{"title":"Dependencies","slug":"dependencies","depth":2,"children":[]},{"title":"Dependents","slug":"dependents","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":["/_mintlify/custom/celo-64ac69bd/2f1ae726193f7358/assistant.js"],"subdomain":"celo-64ac69bd","siteName":"Celo Docs","title":"Smart Contracts Release Process - Celo Docs","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-21T08:29:37.818Z","originalFileLocation":"contribute/release-process/smart-contracts.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"dark\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Details of the release process for updating smart contracts on the Celo platform.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Celo Docs\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/celo-64ac69bd/AG5c0rSidebGFnjH/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/celo-64ac69bd/AG5c0rSidebGFnjH/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/celo-64ac69bd/AG5c0rSidebGFnjH/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/celo-64ac69bd/AG5c0rSidebGFnjH/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/celo-64ac69bd/AG5c0rSidebGFnjH/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/celo-64ac69bd/AG5c0rSidebGFnjH/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/celo-64ac69bd/AG5c0rSidebGFnjH/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/celo-64ac69bd/AG5c0rSidebGFnjH/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/celo-64ac69bd/AG5c0rSidebGFnjH/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Smart Contracts Release Process - Celo Docs\">\u003cmeta data-mint-head property=\"og:description\" content=\"Details of the release process for updating smart contracts on the Celo platform.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Celo Docs\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.celo.org/contribute/release-process/smart-contracts\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://celo-64ac69bd.mintlify.site/_mintlify/api/og/v2?division=Release+Process\u0026amp;title=Smart+Contracts+Release+Process\u0026amp;description=Details+of+the+release+process+for+updating+smart+contracts+on+the+Celo+platform.\u0026amp;theme=e3f075b12817492e86bf13c1\u0026amp;signature=aaa6cc69a482c7c8d04519ee752f22c83bc447114c9f14177d6b2ca5bc7549ef\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Smart Contracts Release Process - Celo Docs\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Details of the release process for updating smart contracts on the Celo platform.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://celo-64ac69bd.mintlify.site/_mintlify/api/og/v2?division=Release+Process\u0026amp;title=Smart+Contracts+Release+Process\u0026amp;description=Details+of+the+release+process+for+updating+smart+contracts+on+the+Celo+platform.\u0026amp;theme=e3f075b12817492e86bf13c1\u0026amp;signature=aaa6cc69a482c7c8d04519ee752f22c83bc447114c9f14177d6b2ca5bc7549ef\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/celo-64ac69bd/AG5c0rSidebGFnjH/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Celo Docs\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#000000\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.celo.org/contribute/release-process/smart-contracts\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/contribute/release-process/smart-contracts.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://celo.org/#organization\",\"name\":\"Celo\",\"url\":\"https://celo.org\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://docs.celo.org/logo/celo_light.png\"},\"sameAs\":[\"https://github.com/celo-org\",\"https://x.com/Celo\",\"https://www.youtube.com/@CeloOrg\",\"https://discord.com/invite/celo\",\"https://forum.celo.org/\",\"https://l2beat.com/scaling/projects/celo\"]},{\"@type\":\"WebSite\",\"@id\":\"https://docs.celo.org#website\",\"name\":\"Celo Docs\",\"url\":\"https://docs.celo.org\",\"publisher\":{\"@id\":\"https://celo.org/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.celo.org/contribute/release-process/smart-contracts#webpage\",\"url\":\"https://docs.celo.org/contribute/release-process/smart-contracts\",\"name\":\"Smart Contracts Release Process\",\"description\":\"Details of the release process for updating smart contracts on the Celo platform.\",\"dateModified\":\"2026-10-21T08:29:37.818Z\",\"isPartOf\":{\"@id\":\"https://docs.celo.org#website\"},\"breadcrumb\":{\"@id\":\"https://docs.celo.org/contribute/release-process/smart-contracts#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.celo.org/contribute/release-process/smart-contracts#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Release Process\",\"item\":\"https://docs.celo.org/contribute/release-process/index\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Smart Contracts Release Process\",\"item\":\"https://docs.celo.org/contribute/release-process/smart-contracts\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.celo.org/contribute/release-process/smart-contracts#article\",\"headline\":\"Smart Contracts Release Process\",\"name\":\"Smart Contracts Release Process\",\"description\":\"Details of the release process for updating smart contracts on the Celo platform.\",\"url\":\"https://docs.celo.org/contribute/release-process/smart-contracts\",\"mainEntityOfPage\":{\"@id\":\"https://docs.celo.org/contribute/release-process/smart-contracts#webpage\"},\"dateModified\":\"2026-10-21T08:29:37.818Z\",\"publisher\":{\"@id\":\"https://celo.org/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.celo.org#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Celo Docs\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Celo Docs","nav":{"global":{"anchors":[{"anchor":"Docs for AI","icon":"robot","href":"/build/agents/use-docs-with-ai"},{"anchor":"Organization","icon":"globe","href":"https://celo.org/"},{"anchor":"Support","icon":"bullhorn","href":"https://discord.com/invite/celo"},{"anchor":"Forum","icon":"newspaper","href":"https://forum.celo.org/"},{"anchor":"Faucet","icon":"faucet","href":"https://faucet.celo.org/celo-sepolia"},{"anchor":"FAQs","icon":"square-question","href":"https://docs.celo.org/operate/operators/faq"}]},"tabs":[{"tab":"Learn","pages":[{"title":"Learn","href":"/learn/celo"}]},{"tab":"Build","pages":[{"title":"Build","href":"/build"}]},{"tab":"Contribute","groups":[{"group":"Overview","pages":[{"title":"Contribute to Celo","sidebarTitle":"Overview","href":"/contribute"},{"title":"Builders","href":"/contribute/builders"}]},{"group":"Contributors","pages":[{"title":"Celo Contributor Overview","sidebarTitle":"Overview","href":"/contribute/contributors/overview"},{"title":"Code Contributors","sidebarTitle":"Code Contributors","href":"/contribute/contributors/code-contributors"},{"title":"Community Improvement Proposals","sidebarTitle":"CIP Contributors","href":"/contribute/contributors/cip-contributors"},{"title":"Documentation Contributors","href":"/contribute/contributors/documentation-contributors"}]},{"group":"Community RPC Nodes","pages":[{"title":"How it works","href":"/contribute/community-rpc-nodes/how-it-works"},{"title":"Registering a Community RPC provider","sidebarTitle":"Register as a Community RPC Node","href":"/contribute/community-rpc-nodes/registering-as-rpc-node"},{"title":"Operating a Community RPC Node","href":"/contribute/community-rpc-nodes/community-rpc-node"},{"title":"Community RPC Provider Penalties","sidebarTitle":"Penalties","href":"/contribute/community-rpc-nodes/penalties"},{"title":"Community RPC Provider FAQ","href":"/contribute/community-rpc-nodes/validator-rpc-faq"}]},{"group":"Release Process","pages":[{"title":"Release Process","sidebarTitle":"Overview","description":"Overview of the release process for updates to the Celo platform.","href":"/contribute/release-process/index"},{"title":"Smart Contracts Release Process","sidebarTitle":"Smart Contracts","href":"/contribute/release-process/smart-contracts"},{"title":"Blockchain Client Release Process","sidebarTitle":"Blockchain Client","description":"Details of the release process for updating the blockchain client on the Celo platform.","href":"/contribute/release-process/blockchain-client"},{"title":"Release Process for CeloCLI and ContractKit","sidebarTitle":"CeloCLI and ContractKit","href":"/contribute/release-process/base-cli-contractkit-dappkit-utils"}]}]},{"tab":"Operate","pages":[{"title":"Operate","href":"/operate"}]}]},"basePath":"","title":"Smart Contracts Release Process - Celo Docs","buildId":"dpl_42LwxxU1kGN114H4XzwGYXa9ZDah","deploymentId":"dpl_42LwxxU1kGN114H4XzwGYXa9ZDah","dynamics":["10e4515597"],"chunks":["BannerMarkdown-DV-WToSZ.js","dist-CBUH0-zX.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","clsx-CR-RHrVC.js","html-void-elements-mCSPHezU.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js"]}