{"id":18422443,"url":"https://github.com/sri-csl/smart-contract-explorer","last_synced_at":"2025-08-11T05:16:33.547Z","repository":{"id":157475081,"uuid":"191860050","full_name":"SRI-CSL/smart-contract-explorer","owner":"SRI-CSL","description":null,"archived":false,"fork":false,"pushed_at":"2023-04-27T15:33:46.000Z","size":767,"stargazers_count":0,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-13T14:44:37.627Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/SRI-CSL.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-06-14T02:02:14.000Z","updated_at":"2023-04-27T15:35:59.000Z","dependencies_parsed_at":null,"dependency_job_id":"dab4d342-2ac4-4500-820e-a35c6c7ad724","html_url":"https://github.com/SRI-CSL/smart-contract-explorer","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/SRI-CSL/smart-contract-explorer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SRI-CSL%2Fsmart-contract-explorer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SRI-CSL%2Fsmart-contract-explorer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SRI-CSL%2Fsmart-contract-explorer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SRI-CSL%2Fsmart-contract-explorer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SRI-CSL","download_url":"https://codeload.github.com/SRI-CSL/smart-contract-explorer/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SRI-CSL%2Fsmart-contract-explorer/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269833252,"owners_count":24482413,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-11T02:00:10.019Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":[],"created_at":"2024-11-06T04:30:02.071Z","updated_at":"2025-08-11T05:16:33.341Z","avatar_url":"https://github.com/SRI-CSL.png","language":"Solidity","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Smart Contract Explorer\n\nExploring behaviors of Solidity smart contracts.\n\n## Requirements\n\n* [solc-verify](https://github.com/SRI-CSL/solidity)\n* [Node.js](https://nodejs.org/en/)\n* [Ocaml](https://ocaml.org)\n* [OCaml Package Manager](https://opam.ocaml.org)\n\nWhile `solc-verify` must currently be built from source, the remainder are available from various package managers, e.g., from [Homebrew](https://brew.sh):\n```\n$ brew install node opam\n$ opam init\n```\n\n## Setup\n\n```\n$ git clone git@github.com:SRI-CSL/smart-contract-explorer.git\n$ git submodule init\n$ git submodule update\n$ npm link\n```\nand optionally:\n```\n$ npm run test\n```\n\n## Usage\n\n```bash\n$ sc-simulation --help\n```\n```\nusage: sc-simulation --source \u003cfilename\u003e --target \u003cfilename\u003e\n\nOptions:\n  --version     Show version number                                    [boolean]\n  --verbose     output verbosity                      [boolean] [default: false]\n  --output      output directory     [string] [default: \".sc-simulation.ignore\"]\n  --source      source smart contract                        [string] [required]\n  --target      target smart contract                        [string] [required]\n  --states      number of states to explore                [number] [default: 5]\n  --relation    append to the simulation relation                       [string]\n  --examples    generate examples for synthesis        [boolean] [default: true]\n  --synthesize  synthesize the simulation relation     [boolean] [default: true]\n  --verify      verify the simulation contract         [boolean] [default: true]\n  --help        Show help                                              [boolean]\n```\n\n### Generating examples for synthesis\n\n```bash\n$ sc-simulation --source resources/contracts/Token/ERC20-molochventures/ERC20.impl.sol  --target resources/contracts/Token/ERC20-openzeppelin/ERC20.spec.sol --no-synthesize --no-verify \u0026\u0026 cat .sc-simulation.ignore/SimulationExamples.sol\n```\n```\nsc-simulation version 0.0.1\n\n---\nGenerating examples\n---\nWarning: did not generate accessor for mapping: _allowed\nWarning: did not generate accessor for mapping: allowances\n```\n```solidity\npragma solidity ^0.5.0;\n\nimport \"/Users/mje/Code/smart-contract-explorer/.sc-simulation.ignore/ERC20.impl.exemplified.sol\";\nimport \"/Users/mje/Code/smart-contract-explorer/.sc-simulation.ignore/ERC20.spec.exemplified.sol\";\n\ncontract SimulationExamples {\n    Token impl;\n    ERC20 spec;\n\n    function positiveExample0() public {\n        impl = (new Token)();\n        spec = (new ERC20)();\n    }\n\n    function positiveExample1() public {\n        impl = (new Token)();\n        impl.transfer(0xab7A7Cb3E460a4ec0B73e07dA54F4173d9bB0c09, 0);\n        spec = (new ERC20)();\n        spec.transfer(0xab7A7Cb3E460a4ec0B73e07dA54F4173d9bB0c09, 0);\n    }\n\n    function positiveExample2() public {\n        impl = (new Token)();\n        impl.transfer(0x6999c8a988a86C52297D9351235644e5768c28e6, 0);\n        spec = (new ERC20)();\n        spec.transfer(0x6999c8a988a86C52297D9351235644e5768c28e6, 0);\n    }\n\n    function negativeExample0() public {\n        impl = (new Token)();\n        spec = (new ERC20)();\n        spec.transfer(0x6999c8a988a86C52297D9351235644e5768c28e6, 1);\n    }\n\n    function negativeExample1() public {\n        impl = (new Token)();\n        impl.transfer(0xab7A7Cb3E460a4ec0B73e07dA54F4173d9bB0c09, 0);\n        spec = (new ERC20)();\n        spec.transfer(0x6999c8a988a86C52297D9351235644e5768c28e6, 1);\n    }\n\n    function negativeExample2() public {\n        impl = (new Token)();\n        impl.transfer(0xab7A7Cb3E460a4ec0B73e07dA54F4173d9bB0c09, 1);\n        spec = (new ERC20)();\n        spec.transfer(0x6999c8a988a86C52297D9351235644e5768c28e6, 1);\n    }\n\n    function negativeExample3() public {\n        impl = (new Token)();\n        impl.transfer(0xab7A7Cb3E460a4ec0B73e07dA54F4173d9bB0c09, 2);\n        spec = (new ERC20)();\n        spec.transfer(0x6999c8a988a86C52297D9351235644e5768c28e6, 1);\n    }\n\n    function negativeExample4() public {\n        impl = (new Token)();\n        impl.transfer(0x6999c8a988a86C52297D9351235644e5768c28e6, 0);\n        spec = (new ERC20)();\n        spec.transfer(0x6999c8a988a86C52297D9351235644e5768c28e6, 1);\n    }\n\n    function negativeExample5() public {\n        impl = (new Token)();\n        impl.transfer(0x6999c8a988a86C52297D9351235644e5768c28e6, 1);\n        spec = (new ERC20)();\n        spec.transfer(0x6999c8a988a86C52297D9351235644e5768c28e6, 1);\n    }\n\n    function impl$_balances() public view returns (bytes32) {\n        return keccak256(abi.encode(\n            impl._balances(0xab7A7Cb3E460a4ec0B73e07dA54F4173d9bB0c09),\n            impl._balances(0x6999c8a988a86C52297D9351235644e5768c28e6)\n        ));\n    }\n\n    function impl$_allowed() public view returns (bytes32) {\n        return keccak256(abi.encode(\n            impl._allowed(0xab7A7Cb3E460a4ec0B73e07dA54F4173d9bB0c09, 0xab7A7Cb3E460a4ec0B73e07dA54F4173d9bB0c09),\n            impl._allowed(0xab7A7Cb3E460a4ec0B73e07dA54F4173d9bB0c09, 0x6999c8a988a86C52297D9351235644e5768c28e6),\n            impl._allowed(0x6999c8a988a86C52297D9351235644e5768c28e6, 0xab7A7Cb3E460a4ec0B73e07dA54F4173d9bB0c09),\n            impl._allowed(0x6999c8a988a86C52297D9351235644e5768c28e6, 0x6999c8a988a86C52297D9351235644e5768c28e6)\n        ));\n    }\n\n    function impl$_totalSupply() public view returns (uint) {\n        impl._totalSupply();\n    }\n\n    function spec$balances() public view returns (bytes32) {\n        return keccak256(abi.encode(\n            spec.balances(0xab7A7Cb3E460a4ec0B73e07dA54F4173d9bB0c09),\n            spec.balances(0x6999c8a988a86C52297D9351235644e5768c28e6)\n        ));\n    }\n\n    function spec$allowances() public view returns (bytes32) {\n        return keccak256(abi.encode(\n            spec.allowances(0xab7A7Cb3E460a4ec0B73e07dA54F4173d9bB0c09, 0xab7A7Cb3E460a4ec0B73e07dA54F4173d9bB0c09),\n            spec.allowances(0xab7A7Cb3E460a4ec0B73e07dA54F4173d9bB0c09, 0x6999c8a988a86C52297D9351235644e5768c28e6),\n            spec.allowances(0x6999c8a988a86C52297D9351235644e5768c28e6, 0xab7A7Cb3E460a4ec0B73e07dA54F4173d9bB0c09),\n            spec.allowances(0x6999c8a988a86C52297D9351235644e5768c28e6, 0x6999c8a988a86C52297D9351235644e5768c28e6)\n        ));\n    }\n\n    function spec$minters() public view returns (bytes32) {\n        return keccak256(abi.encode(\n            spec.minters(0xab7A7Cb3E460a4ec0B73e07dA54F4173d9bB0c09),\n            spec.minters(0x6999c8a988a86C52297D9351235644e5768c28e6)\n        ));\n    }\n\n    function spec$burners() public view returns (bytes32) {\n        return keccak256(abi.encode(\n            spec.burners(0xab7A7Cb3E460a4ec0B73e07dA54F4173d9bB0c09),\n            spec.burners(0x6999c8a988a86C52297D9351235644e5768c28e6)\n        ));\n    }\n}\n```\n\n### Synthesizing simulation relations\n\n```bash\n$ sc-simulation --source resources/contracts/Token/BasicToken-impl/BasicToken.impl.sol  --target resources/contracts/Token/BasicToken-spec/BasicToken.spec.sol --no-verify\n```\n```\nsc-simulation version 0.0.1\n\n---\nGenerating examples\n---\nWarning: did not generate accessor for mapping: allowances\nWarning: did not generate accessor for mapping: allowances\n\n---\nSynthesizing simulation relation\n---\n\n---\nComputed simulation relation:\n\n   spec$balances == impl$balances\n\n---\n```\n\n### Verifying simulation relations\n\n```bash\n$ DEBUG=*:evaluate sc-simulation --source resources/contracts/Token/ERC20-molochventures/ERC20.impl.sol  --target resources/contracts/Token/ERC20-openzeppelin/ERC20.spec.sol --no-synthesize \u0026\u0026 cat .sc-simulation.ignore/SimulationCheck.sol\n```\n```\nKeccak bindings are not compiled. Pure JS implementation will be used.\n\nsc-simulation version 0.0.1\n\n---\nGenerating examples\n---\nWarning: did not generate accessor for mapping: _allowed\nWarning: did not generate accessor for mapping: allowances\n\n---\nChecking simulation relation\n---\n\n---\nVerified simulation relation\n---\n```\n```solidity\npragma solidity ^0.5.0;\n\nimport \"/Users/mje/Code/smart-contract-explorer/.sc-simulation.ignore/ERC20.impl.internalized.sol\";\nimport \"/Users/mje/Code/smart-contract-explorer/.sc-simulation.ignore/ERC20.spec.internalized.sol\";\n\n/**\n * @notice invariant __verifier_eq(Token._balances, ERC20.balances)\n * @notice invariant __verifier_eq(Token._allowed, ERC20.allowances)\n */\ncontract SimulationCheck is Token, ERC20 {\n\n    /**\n     * @notice postcondition impl_ret_0 == spec_ret_0\n     */\n    function check$balance(address account) public view returns (uint256 impl_ret_0, uint256 spec_ret_0) {\n        impl_ret_0 = Token.balance(account);\n        spec_ret_0 = ERC20.balance(account);\n        return (impl_ret_0, spec_ret_0);\n    }\n\n    /**\n     * @notice postcondition impl_ret_0 == spec_ret_0\n     */\n    function check$allowance(address owner, address beneficiary) public view returns (uint256 impl_ret_0, uint256 spec_ret_0) {\n        impl_ret_0 = Token.allowance(owner, beneficiary);\n        spec_ret_0 = ERC20.allowance(owner, beneficiary);\n        return (impl_ret_0, spec_ret_0);\n    }\n\n    /**\n     * @notice modifies Token._balances[msg.sender]\n     * @notice modifies Token._balances[to]\n     * @notice modifies ERC20.balances[msg.sender]\n     * @notice modifies ERC20.balances[to]\n     * @notice precondition to != address(0)\n     * @notice precondition to != msg.sender\n     * @notice precondition ERC20.balances[to] + val \u003e= ERC20.balances[to]\n     * @notice precondition ERC20.balances[msg.sender] - val \u003e= 0\n     */\n    function check$transfer(address to, uint256 val) public {\n        Token.transfer(to, val);\n        ERC20.transfer(to, val);\n    }\n\n    /**\n     * @notice modifies Token._allowed[msg.sender]\n     * @notice modifies ERC20.allowances[msg.sender]\n     * @notice precondition to != address(0)\n     */\n    function check$approve(address to, uint256 val) public {\n        Token.approve(to, val);\n        ERC20.approve(to, val);\n    }\n\n    /**\n     * @notice modifies Token._balances[to]\n     * @notice modifies Token._balances[from]\n     * @notice modifies Token._allowed[from]\n     * @notice modifies ERC20.balances[to]\n     * @notice modifies ERC20.balances[from]\n     * @notice modifies ERC20.allowances[from]\n     * @notice precondition to != address(0)\n     * @notice precondition to != from\n     * @notice precondition ERC20.allowances[from][msg.sender] - val \u003e= 0\n     * @notice precondition ERC20.balances[to] + val \u003e= ERC20.balances[to]\n     * @notice precondition ERC20.balances[from] - val \u003e= 0\n     */\n    function check$transferFrom(address from, address to, uint256 val) public {\n        Token.transferFrom(from, to, val);\n        ERC20.transferFrom(from, to, val);\n    }\n\n    /**\n     * @notice modifies Token._allowed[msg.sender]\n     * @notice modifies ERC20.allowances[msg.sender]\n     * @notice precondition spender != address(0)\n     * @notice precondition ERC20.allowances[msg.sender][spender] + val \u003e= ERC20.allowances[msg.sender][spender]\n     */\n    function check$increaseAllowance(address spender, uint256 val) public {\n        Token.increaseAllowance(spender, val);\n        ERC20.increaseAllowance(spender, val);\n    }\n\n    /**\n     * @notice modifies Token._allowed[msg.sender]\n     * @notice modifies ERC20.allowances[msg.sender]\n     * @notice precondition spender != address(0)\n     * @notice precondition ERC20.allowances[msg.sender][spender] - val \u003e= 0\n     */\n    function check$decreaseAllowance(address spender, uint256 val) public {\n        Token.decreaseAllowance(spender, val);\n        ERC20.decreaseAllowance(spender, val);\n    }\n\n    /**\n     * @notice modifies Token._balances[to]\n     * @notice modifies Token._totalSupply\n     * @notice modifies ERC20.balances[to]\n     * @notice precondition to != address(0)\n     * @notice precondition ERC20.minters[msg.sender]\n     * @notice precondition ERC20.balances[to] + val \u003e= ERC20.balances[to]\n     */\n    function check$mint(address to, uint256 val) public {\n        Token.mint(to, val);\n        ERC20.mint(to, val);\n    }\n\n    /**\n     * @notice modifies Token._balances[from]\n     * @notice modifies Token._totalSupply\n     * @notice modifies ERC20.balances[from]\n     * @notice precondition from != address(0)\n     * @notice precondition ERC20.burners[msg.sender]\n     * @notice precondition ERC20.balances[from] - val \u003e= 0\n     */\n    function check$burn(address from, uint256 val) public {\n        Token.burn(from, val);\n        ERC20.burn(from, val);\n    }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsri-csl%2Fsmart-contract-explorer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsri-csl%2Fsmart-contract-explorer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsri-csl%2Fsmart-contract-explorer/lists"}