{"id":42296397,"url":"https://github.com/celer-network/sgn-v2-contracts","last_synced_at":"2026-01-27T10:13:01.365Z","repository":{"id":36963861,"uuid":"394789281","full_name":"celer-network/sgn-v2-contracts","owner":"celer-network","description":"Smart Contracts for Celer State Guardian Network (SGN) V2 and cBridge V2","archived":false,"fork":false,"pushed_at":"2025-09-14T14:38:22.000Z","size":11326,"stargazers_count":139,"open_issues_count":10,"forks_count":97,"subscribers_count":19,"default_branch":"main","last_synced_at":"2025-09-14T16:29:22.202Z","etag":null,"topics":["blockchain","crosschain","ethereum","layer-2"],"latest_commit_sha":null,"homepage":"","language":"Solidity","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/celer-network.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":"audit/CertiK_sgn_cbridge.pdf","citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-08-10T21:50:26.000Z","updated_at":"2025-07-04T22:11:28.000Z","dependencies_parsed_at":"2024-05-22T13:50:08.357Z","dependency_job_id":"6d54338e-1273-4bea-9a11-259055c1796d","html_url":"https://github.com/celer-network/sgn-v2-contracts","commit_stats":{"total_commits":381,"total_committers":13,"mean_commits":"29.307692307692307","dds":0.5905511811023623,"last_synced_commit":"9ce8ffe13389415a53e2c38838da1b99689d40f0"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/celer-network/sgn-v2-contracts","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/celer-network%2Fsgn-v2-contracts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/celer-network%2Fsgn-v2-contracts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/celer-network%2Fsgn-v2-contracts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/celer-network%2Fsgn-v2-contracts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/celer-network","download_url":"https://codeload.github.com/celer-network/sgn-v2-contracts/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/celer-network%2Fsgn-v2-contracts/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28811553,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-27T07:41:26.337Z","status":"ssl_error","status_checked_at":"2026-01-27T07:41:08.776Z","response_time":168,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blockchain","crosschain","ethereum","layer-2"],"created_at":"2026-01-27T10:13:01.290Z","updated_at":"2026-01-27T10:13:01.355Z","avatar_url":"https://github.com/celer-network.png","language":"Solidity","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SGN Contracts\n\nContracts for the Celer State Guardian Network (SGN) V2.\n\n### Run unit tests\n\n```sh\nyarn test\n```\n\n### Benchmark gas cost\n\n```sh\nyarn report-gas:benchmark\nyarn report-gas:summary\n```\n\nCheck `reports/gas_usage`.\n\n### Update contract sizes\n\n```sh\nyarn size-contracts\n```\n\nCheck `reports/contract_sizes.txt`.\n\n## Deployments\n\n### Deployment Management\n\nContract deployments are tracked by hardhat through the files under ./deployments directory on deployment branches.\n\nTo deploy newest contracts to mainnet, staging, or testnet chains:\n\n1. `git checkout mainnet-deployment|staging-deployment|testnet-deployment`, correspondingly\n2. `git merge main` into the deployment branch\n3. deploy the contracts\n4. push the deployments file changes\n\nIf any contracts (e.g. libraries) are used for both mainnet and staging, follow the step above to deploy them on staging chains first, then cherry-pick the commit containing ONLY the deployment changes of these shared contracts to `mainnet-deployment`. Please be cautious with file changes when doing such operation.\n\nRules:\n\n1. ./deployments should NOT exist on main branch\n2. only merge main into the deployment branches\n3. only change the ./deployments directory on deployment branches so that there will always be no conflicts when merge main\n\n### Deploy contracts\n\n1. `cp .env.template .env`, then ensure all environment variables are set in `.env`.\n\n2. Replace `INFURA-PROJECT-ID` suffix of the network endpoint in `.env`, that you're going to use.\n\n3. Add private key of your account that would be used, in `.env`. Refer to `hardhat.config.ts` for env param key.\n\n4. Deploy SGN and Staking contracts:\n\n```sh\nhardhat deploy --network \u003cnetwork\u003e --tags SGNStaking\n```\n\nDeploy Bridge contract:\n\n```sh\nhardhat deploy --network \u003cnetwork\u003e  --tags Bridge\n```\n\nDeploy OriginalTokenVault contract:\n\nMake sure to set ORIGINAL_TOKEN_VAULT_SIGS_VERIFIER in .env to the Bridge address when deploying.\nSuch as:\nORIGINAL_TOKEN_VAULT_SIGS_VERIFIER=0x67E5E3E54B2E4433CeDB484eCF4ef0f35Fe3Fb22\n\nWhere 0x67E5E3E54B2E4433CeDB484eCF4ef0f35Fe3Fb22 is the Bridge contract address\n\n```sh\nhardhat deploy --network \u003cnetwork\u003e  --tags OriginalTokenVault\n```\n\nDeploy PeggedTokenBridge contract:\n\nMake sure to set ORIGINAL_TOKEN_VAULT_SIGS_VERIFIER in .env to the Bridge address when deploying.\nSuch as:\n\nPEGGED_TOKEN_BRIDGE_SIGS_VERIFIER=0x67E5E3E54B2E4433CeDB484eCF4ef0f35Fe3Fb22\n\nWhere 0x67E5E3E54B2E4433CeDB484eCF4ef0f35Fe3Fb22 is the Bridge contract address\n\n```sh\nhardhat deploy --network \u003cnetwork\u003e  --tags PeggedTokenBridge\n```\n\nDeploy OriginalTokenVaultV2 contract:\n\nMake sure to set ORIGINAL_TOKEN_VAULT_SIGS_VERIFIER in .env to the Bridge address when deploying.\nSuch as:\n\nORIGINAL_TOKEN_VAULT_SIGS_VERIFIER=0x67E5E3E54B2E4433CeDB484eCF4ef0f35Fe3Fb22\n\nWhere 0x67E5E3E54B2E4433CeDB484eCF4ef0f35Fe3Fb22 is the Bridge contract address\n\n```sh\nhardhat deploy --network \u003cnetwork\u003e  --tags OriginalTokenVaultV2\n```\n\nDeploy PeggedTokenBridgeV2 contract:\n\nMake sure to set ORIGINAL_TOKEN_VAULT_SIGS_VERIFIER in .env to the Bridge address when deploying.\nSuch as:\n\nPEGGED_TOKEN_BRIDGE_SIGS_VERIFIER=0x67E5E3E54B2E4433CeDB484eCF4ef0f35Fe3Fb22\n\nWhere 0x67E5E3E54B2E4433CeDB484eCF4ef0f35Fe3Fb22 is the Bridge contract address\n\n```sh\nhardhat deploy --network \u003cnetwork\u003e  --tags PeggedTokenBridgeV2\n```\n\n### Verify contracts on explorers\n\n#### On Etherscan variants via hardhat etherscan-verify\n\nThis is the recommended way for most mainnet Etherscan variants.\n\nMake sure the `ETHERSCAN_API_KEY` is set correctly in `.env`.\n\n```sh\nhardhat etherscan-verify --network \u003cnetwork\u003e --license \"GPL-3.0\" --force-license\n```\n\n#### On Etherscan variants via solt\n\nThis is useful since most testnet Etherscan variants don't offer verification via the API.\n\n1. Generate the standard JSON input files:\n\n```sh\nsource scripts/solt.sh\nrun_solt_write\n```\n\n2. Then try:\n\n```sh\nsolt verify --license 5 --network \u003cnetwork\u003e solc-input-\u003ccontract\u003e.json \u003cdeployed address\u003e \u003ccontract name\u003e\n```\n\n3. If the second step fails, go to Etherscan and manually verify using the standard JSON input files.\n\n#### On Blockscout variants via sourcify\n\nThis is used if the Blockscout variant requires \"Sources and Metadata JSON\".\n\n```sh\nhardhat sourcify --network \u003cnetwork\u003e\n```\n\n#### On Blockscout variants via flattened source files\n\nThis is used if the Blockscout variant requires a single source file, or in general as a last resort.\n\n1. Flatten the source files:\n\n```sh\nhardhat flatten \u003cpath-to-contract\u003e \u003e flattened.sol\n```\n\n2. Edit `flattened.sol`. Remove the duplicate `SPDX-License-Identifier` lines, keeping a single copy of\n\n```\n// SPDX-License-Identifier: GPL-3.0-only\n```\n\nand submit to Blockscout.\n\nSometimes you also need to remove the duplicate `pragma solidity` lines.\n\n## Upgradable contract via the proxy pattern\n\n### How it works\n\nproxy contract holds state and delegatecall all calls to actual impl contract. When upgrade, a new impl contract is deployed, and proxy is updated to point to the new contract. below from [openzeppelin doc](https://docs.openzeppelin.com/upgrades-plugins/1.x/proxies#upgrading-via-the-proxy-pattern)\n\n```\nUser ---- tx ---\u003e Proxy ----------\u003e Implementation_v0\n                     |\n                      ------------\u003e Implementation_v1\n                     |\n                      ------------\u003e Implementation_v2\n```\n\n### Add upgradable contract\n\nTo minimize code fork, we add a new contract that inherits existing contract, eg. `contract TokenUpgradable is Token`. Next we need to ensure that all states set in Token contract constructor (and its parent contracts) must be settable via a separate normal func like `init`. This will allow Proxy contract to delegeteCall init and set proper values in Proxy's state, not the impl contract state. See MintSwapCanonicalTokenUpgradable.sol for example. We also need to either shadow Ownable._owner because when proxy delegateCall, in proxy state, Ownable._owner is not set and there is no other way to set it. Or use our own Ownable.sol which has internal func initOwner\n\n### Add deploy scripts\n\nadd a new ts file for deploy, in deploy options, add proxy section, make sure the methodName and args match actual upgradable contract\n\n```ts\nproxy: {\n    proxyContract: \"OptimizedTransparentProxy\",\n      execute: {\n        // only called when proxy is deployed, it'll call Token contract.init\n        // with proper args\n        init: {\n          methodName: 'init',\n          args: [\n            process.env.MINT_SWAP_CANONICAL_TOKEN_NAME,\n            process.env.MINT_SWAP_CANONICAL_TOKEN_SYMBOL]\n        }\n      }\n}\n```\n\nsee deploy/pegged/tokens/008_mint_swap_canonical_token_upgradable.ts for example\n\n### Deploy and upgrade\n\nhardhat deploy plugin tries to be smart and deploy ProxyAdmin only once for each chain, deploy impl contract then proxy contract\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fceler-network%2Fsgn-v2-contracts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fceler-network%2Fsgn-v2-contracts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fceler-network%2Fsgn-v2-contracts/lists"}