├── .gitattributes ├── .gitignore ├── COPYRIGHT ├── Jenkinsfile ├── LICENSE ├── README.md ├── autotest.sh ├── contracts ├── ENStools │ ├── ENSReverseRegistration.sol │ ├── IENS.sol │ └── IReverseRegistrar.sol ├── ERC1154 │ └── IERC1154.sol ├── ERC1271 │ └── IERC1271.sol ├── ERC1538 │ ├── ERC1538Core.sol │ ├── ERC1538Module.sol │ ├── ERC1538Modules │ │ ├── ERC1538Query.sol │ │ ├── ERC1538Update.sol │ │ └── ERC1538UpdateV2.sol │ ├── ERC1538Proxy │ │ ├── ERC1538Proxy.sol │ │ └── ERC1538ProxyV2.sol │ ├── ERC1538Store.sol │ └── IERC1538.sol ├── ERC1654 │ └── IERC1654.sol ├── ERC2362 │ └── IERC2362.sol ├── ERC725 │ └── IERC725.sol ├── ERC734 │ └── IERC734.sol ├── Factory │ ├── CounterfactualFactory.sol │ └── GenericFactory.sol ├── Libs │ ├── ECDSA.sol │ ├── ECDSALib.sol │ └── SafeMathExtended.sol ├── Migrations.sol ├── TestContract.sol └── Upgradeability │ ├── BaseUpgradeabilityProxy.sol │ ├── InitializableUpgradeabilityProxy.sol │ └── Proxy.sol ├── deployment └── factory.json ├── migrations ├── 1_initial_migration.js └── 2_deploy_contracts.js ├── package.json ├── test ├── ERC1538 │ ├── ERC1538.js │ └── ERC1538v2.js └── Factory │ ├── GenericFactory.js │ └── predict.js └── truffle.js /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sol linguist-language=Solidity 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/__pycache__ 2 | node_modules 3 | makefile 4 | 5 | logs/ 6 | build/ 7 | coverage/ 8 | coverage.json 9 | coverage.log 10 | 11 | package-lock.json 12 | yarn.lock 13 | -------------------------------------------------------------------------------- /COPYRIGHT: -------------------------------------------------------------------------------- 1 | Copyright 2020 IEXEC BLOCKCHAIN TECH 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | node("master") { 2 | stage("Choose Label") { 3 | LABEL = "jenkins-agent-machine-1" 4 | } 5 | } 6 | 7 | pipeline { 8 | 9 | environment { 10 | registry = "nexus.iex.ec" 11 | dockerImage1sec = "" 12 | dockerImage20sec = "" 13 | buildWhenTagContains = "lv" 14 | } 15 | 16 | agent { 17 | node { 18 | label "${LABEL}" 19 | } 20 | } 21 | 22 | stages { 23 | 24 | stage("Truffle tests") { 25 | agent { 26 | docker { 27 | image "node:11" 28 | label "${LABEL}" 29 | } 30 | } 31 | steps { 32 | script { 33 | try { 34 | sh "npm install" 35 | sh "npm run autotest fast" 36 | } finally { 37 | archiveArtifacts artifacts: "logs/**" 38 | } 39 | } 40 | } 41 | } 42 | 43 | stage("Solidity coverage") { 44 | agent { 45 | docker { 46 | image "node:11" 47 | label "${LABEL}" 48 | } 49 | } 50 | steps { 51 | script { 52 | try { 53 | sh "npm install" 54 | sh "npm run coverage" 55 | } finally { 56 | archiveArtifacts artifacts: "coverage/**" 57 | } 58 | } 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2020 IEXEC BLOCKCHAIN TECH 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # iExec-Solidity 2 | 3 | ## Release new version on both Github and NPM 4 | 5 | ### Steps : 6 | 7 | 1. **Prepare the Release** 8 | 9 | 2. **Update the Version**: Modify the version number in the `package.json` file in line with the new release. 10 | 11 | 3. **Raise a PR to commit the Version Change** 12 | 13 | 4. **Tag the Release on GitHub using the same version in `package.json`** 14 | 15 | 5. **Publish a new release on GitHub** 16 | 17 | 6. **Publish the Release on NPM**: Before publishing, ensure you have access to the npm registry of iExec team. If you don't, request access from the admin. After that, you can use the `npm publish` command to release the new version on NPM. This command will ask you to connect to your npm profile 18 | -------------------------------------------------------------------------------- /autotest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | trap catch INT 4 | 5 | GANACHE="./node_modules/.bin/ganache-cli" 6 | TRUFFLE="./node_modules/.bin/truffle" 7 | 8 | function print_style 9 | { 10 | if [ "$1" == "info" ]; then COLOR="96m"; 11 | elif [ "$1" == "success" ]; then COLOR="92m"; 12 | elif [ "$1" == "warning" ]; then COLOR="93m"; 13 | elif [ "$1" == "danger" ]; then COLOR="91m"; 14 | else COLOR="0m"; 15 | fi 16 | STARTCOLOR="\e[$COLOR"; 17 | ENDCOLOR="\e[0m"; 18 | printf "$STARTCOLOR%b$ENDCOLOR" "$2"; 19 | } 20 | 21 | function initialize 22 | { 23 | mkdir -p logs 24 | # starting ganache 25 | nohup $GANACHE -h 0.0.0.0 >> logs/ganache.$date.log 2>&1& 26 | GANACHE_PID=$! 27 | print_style 'info' "Started ganache daemon (pid=$GANACHE_PID)\n" 28 | } 29 | 30 | function finalize 31 | { 32 | # stopping ganache 33 | rm -f logs/ganache.$date.log 34 | kill -9 $GANACHE_PID 35 | print_style 'info' "Killed ganache daemon (pid=$GANACHE_PID)\n" 36 | } 37 | 38 | function catch 39 | { 40 | print_style 'warning' "\n*** Killing test suite ***\n" 41 | if [[ $LAUNCH -ne 0 ]]; then finalize; fi 42 | exit 1 43 | } 44 | 45 | function runCompile 46 | { 47 | # compile contracts 48 | logfile="logs/compile.$date.log" 49 | printf "Compiling ... " 50 | $TRUFFLE compile > $logfile 2>&1 51 | if [[ $? -ne 0 ]]; 52 | then 53 | print_style 'danger' "failure\n" 54 | print_style 'danger' "Full report is available at $logfile\n" 55 | catch 56 | else 57 | print_style 'success' "success\n" 58 | rm -f $logfile 59 | fi 60 | } 61 | 62 | function runMigrate 63 | { 64 | # try migrating contracts 65 | logfile="logs/migrate.$date.log" 66 | printf "Migrating ... " 67 | $TRUFFLE migrate $PARAMS > $logfile 2>&1 68 | if [[ $? -ne 0 ]]; 69 | then 70 | print_style 'danger' "failure\n" 71 | print_style 'danger' "Full report is available at $logfile\n" 72 | catch 73 | else 74 | print_style 'success' "success\n" 75 | rm -f $logfile 76 | fi 77 | } 78 | 79 | function runTests 80 | { 81 | # running tests 82 | if [[ $FAST -ne 0 ]]; 83 | then 84 | logfile="logs/fast.$date.log" 85 | printf "Running tests ... " 86 | $TRUFFLE test $PARAMS 2>&1 | tee $logfile 87 | if [[ $? -ne 0 ]]; 88 | then 89 | print_style 'danger' "failure\n" 90 | catch 91 | else 92 | print_style 'success' "success\n" 93 | # rm -f $logfile 94 | fi 95 | else 96 | for filepath in `find test/ -type f -name "*.js" -print | sort` 97 | do 98 | filename=$(basename $filepath) 99 | logfile="logs/${filename%.*}.$date.log" 100 | if [ "$CHECKPOINT" \> "$filename" ]; then continue; fi 101 | printf "Starting test ${filepath%.*} ... " 102 | $TRUFFLE test $filepath $PARAMS > $logfile 2>&1 103 | if [[ $? -ne 0 ]]; 104 | then 105 | print_style 'danger' "failure\n" 106 | print_style 'danger' "Full report is available at $logfile\n" 107 | catch 108 | else 109 | print_style 'success' "success\n" 110 | # rm -f $logfile 111 | fi 112 | done 113 | fi 114 | } 115 | 116 | date=$(date --utc +"%Y-%m-%dT%H:%M:%S") 117 | 118 | FAST=0 119 | LAUNCH=1 120 | COMPILE=1 121 | DEPLOY=1 122 | CHECKPOINT="" 123 | PARAMS="" 124 | 125 | while test $# -gt 0; do 126 | case $1 in 127 | fast) 128 | FAST=1 129 | ;; 130 | skip-launch) 131 | LAUNCH=0 132 | ;; 133 | skip-compile) 134 | COMPILE=0 135 | ;; 136 | skip-deploy) 137 | DEPLOY=0 138 | ;; 139 | checkpoint) 140 | CHECKPOINT=$2 141 | shift 142 | ;; 143 | *) 144 | PARAMS="$PARAMS $1" 145 | ;; 146 | esac 147 | shift 148 | done 149 | 150 | # MAIN 151 | if [[ $LAUNCH -ne 0 ]]; then initialize; fi 152 | if [[ $COMPILE -ne 0 ]]; then runCompile; fi 153 | if [[ $DEPLOY -ne 0 ]]; then runMigrate; fi 154 | runTests 155 | if [[ $LAUNCH -ne 0 ]]; then finalize; fi 156 | -------------------------------------------------------------------------------- /contracts/ENStools/ENSReverseRegistration.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity ^0.6.0; 20 | 21 | // import "@ensdomains/ens/contracts/ENS.sol"; // ENS packages are dependency heavy 22 | import "./IENS.sol"; 23 | import "./IReverseRegistrar.sol"; 24 | 25 | contract ENSReverseRegistration 26 | { 27 | bytes32 internal constant ADDR_REVERSE_NODE = 0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2; 28 | 29 | function _setName(IENS ens, string memory name) 30 | internal 31 | { 32 | IReverseRegistrar(ens.owner(ADDR_REVERSE_NODE)).setName(name); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /contracts/ENStools/IENS.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity >=0.4.24; 20 | 21 | interface IENS 22 | { 23 | event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner); 24 | event Transfer(bytes32 indexed node, address owner); 25 | event NewResolver(bytes32 indexed node, address resolver); 26 | event NewTTL(bytes32 indexed node, uint64 ttl); 27 | event ApprovalForAll(address indexed owner, address indexed operator, bool approved); 28 | 29 | function setRecord(bytes32, address, address, uint64) external; 30 | function setSubnodeRecord(bytes32, bytes32, address, address, uint64) external; 31 | function setSubnodeOwner(bytes32, bytes32, address) external returns(bytes32); 32 | function setResolver(bytes32, address) external; 33 | function setOwner(bytes32, address) external; 34 | function setTTL(bytes32, uint64) external; 35 | function setApprovalForAll(address, bool) external; 36 | function owner(bytes32) external view returns (address); 37 | function resolver(bytes32) external view returns (address); 38 | function ttl(bytes32) external view returns (uint64); 39 | function recordExists(bytes32) external view returns (bool); 40 | function isApprovedForAll(address, address) external view returns (bool); 41 | } 42 | -------------------------------------------------------------------------------- /contracts/ENStools/IReverseRegistrar.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity >=0.4.24; 20 | 21 | import "./IENS.sol"; 22 | 23 | interface IReverseRegistrar 24 | { 25 | function ADDR_REVERSE_NODE() external view returns (bytes32); 26 | function ens() external view returns (IENS); 27 | function defaultResolver() external view returns (address); 28 | function claim(address) external returns (bytes32); 29 | function claimWithResolver(address, address) external returns (bytes32); 30 | function setName(string calldata) external returns (bytes32); 31 | function node(address) external pure returns (bytes32); 32 | } 33 | -------------------------------------------------------------------------------- /contracts/ERC1154/IERC1154.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity ^0.6.0; 20 | 21 | /** 22 | * @title EIP1154 interface 23 | * @dev see https://eips.ethereum.org/EIPS/eip-1154 24 | */ 25 | interface IOracleConsumer 26 | { 27 | function receiveResult(bytes32, bytes calldata) 28 | external; 29 | } 30 | 31 | interface IOracle 32 | { 33 | function resultFor(bytes32) 34 | external view returns (bytes memory); 35 | } 36 | -------------------------------------------------------------------------------- /contracts/ERC1271/IERC1271.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity ^0.6.0; 20 | 21 | interface IERC1271 22 | { 23 | function isValidSignature(bytes calldata data, bytes calldata signature) external view returns (bytes4 magicValue); 24 | } 25 | -------------------------------------------------------------------------------- /contracts/ERC1538/ERC1538Core.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity ^0.6.0; 20 | 21 | import "./IERC1538.sol"; 22 | import "./ERC1538Store.sol"; 23 | 24 | contract ERC1538Core is IERC1538, ERC1538Store 25 | { 26 | bytes4 constant internal RECEIVE = 0xd217fcc6; // bytes4(keccak256("receive")); 27 | bytes4 constant internal FALLBACK = 0xb32cdf4d; // bytes4(keccak256("fallback")); 28 | 29 | event CommitMessage(string message); 30 | event FunctionUpdate(bytes4 indexed functionId, address indexed oldDelegate, address indexed newDelegate, string functionSignature); 31 | 32 | function _setFunc(string memory funcSignature, address funcDelegate) 33 | internal 34 | { 35 | bytes4 funcId = bytes4(keccak256(bytes(funcSignature))); 36 | if (funcId == RECEIVE ) { funcId = bytes4(0x00000000); } 37 | if (funcId == FALLBACK) { funcId = bytes4(0xFFFFFFFF); } 38 | 39 | address oldDelegate = m_funcs.value1(funcId); 40 | 41 | if (funcDelegate == oldDelegate) // No change → skip 42 | { 43 | return; 44 | } 45 | else if (funcDelegate == address(0)) // Delete 46 | { 47 | m_funcs.del(funcId); 48 | } 49 | else // Set / Update 50 | { 51 | m_funcs.set(funcId, funcDelegate, bytes(funcSignature)); 52 | } 53 | 54 | emit FunctionUpdate(funcId, oldDelegate, funcDelegate, funcSignature); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /contracts/ERC1538/ERC1538Module.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity ^0.6.0; 20 | 21 | import "./ERC1538Store.sol"; 22 | 23 | contract ERC1538Module is ERC1538Store 24 | { 25 | constructor() 26 | public 27 | { 28 | renounceOwnership(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /contracts/ERC1538/ERC1538Modules/ERC1538Query.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity ^0.6.0; 20 | 21 | import "../ERC1538Module.sol"; 22 | 23 | 24 | interface ERC1538Query 25 | { 26 | function totalFunctions ( ) external view returns(uint256); 27 | function functionByIndex (uint256 _index ) external view returns(string memory, bytes4, address); 28 | function functionById (bytes4 _id ) external view returns(string memory, bytes4, address); 29 | function functionExists (string calldata _signature) external view returns(bool); 30 | function functionSignatures ( ) external view returns(string memory); 31 | function delegateFunctionSignatures(address _delegate ) external view returns(string memory); 32 | function delegateAddress (string calldata _signature) external view returns(address); 33 | function delegateAddresses ( ) external view returns(address[] memory); 34 | } 35 | 36 | contract ERC1538QueryDelegate is ERC1538Query, ERC1538Module 37 | { 38 | function totalFunctions() 39 | external override view returns(uint256) 40 | { 41 | return m_funcs.length(); 42 | } 43 | 44 | function functionByIndex(uint256 _index) 45 | external override view returns(string memory signature, bytes4 id, address delegate) 46 | { 47 | (bytes4 funcId, address funcDelegate, bytes memory funcSignature) = m_funcs.at(_index + 1); 48 | return (string(funcSignature), funcId, funcDelegate); 49 | } 50 | 51 | function functionById(bytes4 _funcId) 52 | external override view returns(string memory signature, bytes4 id, address delegate) 53 | { 54 | return (string(m_funcs.value2(_funcId)), _funcId, m_funcs.value1(_funcId)); 55 | } 56 | 57 | function functionExists(string calldata _funcSignature) 58 | external override view returns(bool) 59 | { 60 | return m_funcs.contains(bytes4(keccak256(bytes(_funcSignature)))); 61 | } 62 | 63 | function delegateAddress(string calldata _funcSignature) 64 | external override view returns(address) 65 | { 66 | return m_funcs.value1(bytes4(keccak256(bytes(_funcSignature)))); 67 | } 68 | 69 | function functionSignatures() 70 | external override view returns(string memory) 71 | { 72 | uint256 signaturesLength = 0; 73 | for (uint256 i = 1; i <= m_funcs.length(); ++i) 74 | { 75 | signaturesLength += m_funcs.value2(m_funcs.keyAt(i)).length + 1; // EDIT 76 | } 77 | 78 | bytes memory signatures = new bytes(signaturesLength); 79 | uint256 charPos = 0; 80 | for (uint256 i = 1; i <= m_funcs.length(); ++i) 81 | { 82 | bytes memory signature = m_funcs.value2(m_funcs.keyAt(i)); 83 | for (uint256 c = 0; c < signature.length; ++c) 84 | { 85 | signatures[charPos] = signature[c]; 86 | ++charPos; 87 | } 88 | signatures[charPos] = 0x3B; 89 | ++charPos; 90 | } 91 | 92 | return string(signatures); 93 | } 94 | 95 | function delegateFunctionSignatures(address _delegate) 96 | external override view returns(string memory) 97 | { 98 | bytes[] memory delegateSignatures = new bytes[](m_funcs.length()); 99 | uint256 delegateSignaturesLength = 0; 100 | 101 | uint256 signaturesLength = 0; 102 | for (uint256 i = 1; i <= m_funcs.length(); ++i) 103 | { 104 | (bytes4 funcId, address funcDelegate, bytes memory funcSignature) = m_funcs.at(i); 105 | if (_delegate == funcDelegate) 106 | { 107 | signaturesLength += funcSignature.length + 1; 108 | delegateSignatures[delegateSignaturesLength] = funcSignature; 109 | ++delegateSignaturesLength; 110 | } 111 | } 112 | 113 | bytes memory signatures = new bytes(signaturesLength); 114 | uint256 charPos = 0; 115 | for (uint256 i = 0; i < delegateSignaturesLength; ++i) 116 | { 117 | bytes memory signature = delegateSignatures[i]; 118 | for (uint256 c = 0; c < signature.length; ++c) 119 | { 120 | signatures[charPos] = signature[c]; 121 | ++charPos; 122 | } 123 | signatures[charPos] = 0x3B; 124 | ++charPos; 125 | } 126 | 127 | return string(signatures); 128 | } 129 | 130 | function delegateAddresses() 131 | external override view returns(address[] memory) 132 | { 133 | address[] memory delegatesBucket = new address[](m_funcs.length()); 134 | 135 | uint256 numDelegates = 0; 136 | for (uint256 i = 1; i <= m_funcs.length(); ++i) 137 | { 138 | address delegate = m_funcs.value1(m_funcs.keyAt(i)); 139 | bool seen = false; 140 | for (uint256 j = 0; j < numDelegates; ++j) 141 | { 142 | if (delegate == delegatesBucket[j]) 143 | { 144 | seen = true; 145 | break; 146 | } 147 | } 148 | if (seen == false) 149 | { 150 | delegatesBucket[numDelegates] = delegate; 151 | ++numDelegates; 152 | } 153 | } 154 | 155 | address[] memory delegates = new address[](numDelegates); 156 | for (uint256 i = 0; i < numDelegates; ++i) 157 | { 158 | delegates[i] = delegatesBucket[i]; 159 | } 160 | return delegates; 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /contracts/ERC1538/ERC1538Modules/ERC1538Update.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity ^0.6.0; 20 | 21 | import "../ERC1538Core.sol"; 22 | import "../ERC1538Module.sol"; 23 | 24 | 25 | interface ERC1538Update 26 | { 27 | function updateContract(address _delegate, string calldata _functionSignatures, string calldata commitMessage) external; 28 | } 29 | 30 | contract ERC1538UpdateDelegate is ERC1538Update, ERC1538Core, ERC1538Module 31 | { 32 | function updateContract( 33 | address _delegate, 34 | string calldata _functionSignatures, 35 | string calldata _commitMessage 36 | ) 37 | external override onlyOwner 38 | { 39 | bytes memory signatures = bytes(_functionSignatures); 40 | uint256 start; 41 | uint256 end; 42 | uint256 size; 43 | 44 | if (_delegate != address(0)) 45 | { 46 | assembly { size := extcodesize(_delegate) } 47 | require(size > 0, "[ERC1538] _delegate address is not a contract and is not address(0)"); 48 | } 49 | assembly 50 | { 51 | start := add(signatures, 32) 52 | end := add(start, mload(signatures)) 53 | } 54 | for (uint256 pos = start; pos < end; ++pos) 55 | { 56 | uint256 char; 57 | assembly { char := byte(0, mload(pos)) } 58 | if (char == 0x3B) // 0x3B = ';' 59 | { 60 | uint256 length = (pos - start); 61 | assembly { mstore(signatures, length) } 62 | 63 | _setFunc(string(signatures), _delegate); 64 | 65 | assembly { signatures := add(signatures, add(length, 1)) } 66 | start = pos+1; 67 | } 68 | } 69 | emit CommitMessage(_commitMessage); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /contracts/ERC1538/ERC1538Modules/ERC1538UpdateV2.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity ^0.6.0; 20 | pragma experimental ABIEncoderV2; 21 | 22 | import "../ERC1538Core.sol"; 23 | import "../ERC1538Module.sol"; 24 | 25 | 26 | interface ERC1538UpdateV2 27 | { 28 | function updateContract(address _delegate, string[] calldata _functionSignatures, string calldata commitMessage) external; 29 | } 30 | 31 | contract ERC1538UpdateV2Delegate is ERC1538UpdateV2, ERC1538Core, ERC1538Module 32 | { 33 | function updateContract( 34 | address _delegate, 35 | string[] calldata _functionSignatures, 36 | string calldata _commitMessage 37 | ) 38 | external override onlyOwner 39 | { 40 | if (_delegate != address(0)) 41 | { 42 | uint256 size; 43 | assembly { size := extcodesize(_delegate) } 44 | require(size > 0, "[ERC1538] _delegate address is not a contract and is not address(0)"); 45 | } 46 | for (uint256 i = 0; i < _functionSignatures.length; ++i) 47 | { 48 | _setFunc(_functionSignatures[i], _delegate); 49 | } 50 | emit CommitMessage(_commitMessage); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /contracts/ERC1538/ERC1538Proxy/ERC1538Proxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity ^0.6.0; 20 | 21 | import "../../Upgradeability/Proxy.sol"; 22 | import "../ERC1538Core.sol"; 23 | 24 | 25 | contract ERC1538Proxy is ERC1538Core, Proxy 26 | { 27 | constructor(address _erc1538Delegate) 28 | public 29 | { 30 | _setFunc("updateContract(address,string,string)", _erc1538Delegate); 31 | emit CommitMessage("Added ERC1538 updateContract function at contract creation"); 32 | } 33 | 34 | function _implementation() internal override view returns (address) 35 | { 36 | address delegateFunc = m_funcs.value1(msg.sig); 37 | 38 | if (delegateFunc != address(0)) 39 | { 40 | return delegateFunc; 41 | } 42 | else 43 | { 44 | return m_funcs.value1(0xFFFFFFFF); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /contracts/ERC1538/ERC1538Proxy/ERC1538ProxyV2.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity ^0.6.0; 20 | 21 | import "../../Upgradeability/Proxy.sol"; 22 | import "../ERC1538Core.sol"; 23 | 24 | 25 | contract ERC1538ProxyV2 is ERC1538Core, Proxy 26 | { 27 | constructor(address _erc1538Delegate) 28 | public 29 | { 30 | _setFunc("updateContract(address,string[],string)", _erc1538Delegate); 31 | emit CommitMessage("Added ERC1538 updateContract function at contract creation"); 32 | } 33 | 34 | function _implementation() internal override view returns (address) 35 | { 36 | address delegateFunc = m_funcs.value1(msg.sig); 37 | 38 | if (delegateFunc != address(0)) 39 | { 40 | return delegateFunc; 41 | } 42 | else 43 | { 44 | return m_funcs.value1(0xFFFFFFFF); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /contracts/ERC1538/ERC1538Store.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity ^0.6.0; 20 | 21 | import "@openzeppelin/contracts/access/Ownable.sol"; 22 | import "solstruct/contracts/libs/LibMap2.bytes4.address.bytes.sol"; 23 | 24 | contract ERC1538Store is Ownable 25 | { 26 | using LibMap2_bytes4_address_bytes for LibMap2_bytes4_address_bytes.map; 27 | 28 | LibMap2_bytes4_address_bytes.map internal m_funcs; 29 | } 30 | -------------------------------------------------------------------------------- /contracts/ERC1538/IERC1538.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity ^0.6.0; 20 | 21 | interface IERC1538 22 | { 23 | event CommitMessage(string message); 24 | event FunctionUpdate(bytes4 indexed functionId, address indexed oldDelegate, address indexed newDelegate, string functionSignature); 25 | } 26 | -------------------------------------------------------------------------------- /contracts/ERC1654/IERC1654.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity ^0.6.0; 20 | 21 | interface IERC1654 22 | { 23 | function isValidSignature(bytes32 hash, bytes calldata signature) external view returns (bytes4 magicValue); 24 | } 25 | -------------------------------------------------------------------------------- /contracts/ERC2362/IERC2362.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity >=0.5.0 <0.7.0; 20 | 21 | 22 | interface IERC2362 23 | { 24 | function valueFor(bytes32 _id) external view returns(int256,uint256,uint256); 25 | } 26 | -------------------------------------------------------------------------------- /contracts/ERC725/IERC725.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity ^0.6.0; 20 | 21 | interface IERC725 22 | { 23 | event DataChanged(bytes32 indexed key, bytes32 indexed value); 24 | event ContractCreated(address indexed contractAddress); 25 | 26 | function getData(bytes32 _key) external view returns (bytes32 _value); 27 | function setData(bytes32 _key, bytes32 _value) external; 28 | function execute(uint256 _operationType, address _to, uint256 _value, bytes calldata _data) external; 29 | } 30 | -------------------------------------------------------------------------------- /contracts/ERC734/IERC734.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity ^0.6.0; 20 | 21 | abstract contract IERC734 22 | { 23 | // 1: MANAGEMENT keys, which can manage the identity 24 | uint256 public constant MANAGEMENT_KEY = 1; 25 | // 2: ACTION keys, which perform actions in this identities name (signing, logins, transactions, etc.) 26 | uint256 public constant ACTION_KEY = 2; 27 | // 3: CLAIM signer keys, used to sign claims on other identities which need to be revokable. 28 | uint256 public constant CLAIM_SIGNER_KEY = 3; 29 | // 4: ENCRYPTION keys, used to encrypt data e.g. hold in claims. 30 | uint256 public constant ENCRYPTION_KEY = 4; 31 | 32 | // KeyType 33 | uint256 public constant ECDSA_TYPE = 1; 34 | // https://medium.com/@alexberegszaszi/lets-bring-the-70s-to-ethereum-48daa16a4b51 35 | uint256 public constant RSA_TYPE = 2; 36 | 37 | // Events 38 | event KeyAdded (bytes32 indexed key, uint256 indexed purpose, uint256 indexed keyType); 39 | event KeyRemoved (bytes32 indexed key, uint256 indexed purpose, uint256 indexed keyType); 40 | event ExecutionRequested(uint256 indexed executionId, address indexed to, uint256 indexed value, bytes data); 41 | event Executed (uint256 indexed executionId, address indexed to, uint256 indexed value, bytes data); 42 | event ExecutionFailed (uint256 indexed executionId, address indexed to, uint256 indexed value, bytes data); 43 | event Approved (uint256 indexed executionId, bool approved); 44 | 45 | // Functions 46 | function getKey (bytes32 _key ) external virtual view returns (uint256[] memory purposes, uint256 keyType, bytes32 key); 47 | function keyHasPurpose (bytes32 _key, uint256 purpose ) external virtual view returns (bool exists); 48 | function getKeysByPurpose(uint256 _purpose ) external virtual view returns (bytes32[] memory keys); 49 | function addKey (bytes32 _key, uint256 _purpose, uint256 _keyType ) external virtual returns (bool success); 50 | function removeKey (bytes32 _key, uint256 _purpose ) external virtual returns (bool success); 51 | function execute (address _to, uint256 _value, bytes calldata _data) external virtual returns (uint256 executionId); 52 | function approve (uint256 _id, bool _approve ) external virtual returns (bool success); 53 | } 54 | -------------------------------------------------------------------------------- /contracts/Factory/CounterfactualFactory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity ^0.6.0; 20 | 21 | 22 | contract CounterfactualFactory 23 | { 24 | function _create2(bytes memory _code, bytes32 _salt) 25 | internal returns(address) 26 | { 27 | bytes memory code = _code; 28 | bytes32 salt = _salt; 29 | address addr; 30 | // solium-disable-next-line security/no-inline-assembly 31 | assembly 32 | { 33 | addr := create2(0, add(code, 0x20), mload(code), salt) 34 | if iszero(extcodesize(addr)) { revert(0, 0) } 35 | } 36 | return addr; 37 | } 38 | 39 | function _predictAddress(bytes memory _code, bytes32 _salt) 40 | internal view returns (address) 41 | { 42 | return address(bytes20(keccak256(abi.encodePacked( 43 | bytes1(0xff), 44 | address(this), 45 | _salt, 46 | keccak256(_code) 47 | )) << 0x60)); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /contracts/Factory/GenericFactory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity ^0.6.0; 20 | 21 | import "./CounterfactualFactory.sol"; 22 | 23 | 24 | contract GenericFactory is CounterfactualFactory 25 | { 26 | event NewContract(address indexed addr); 27 | 28 | function predictAddress(bytes memory _code, bytes32 _salt) 29 | public view returns(address) 30 | { 31 | return predictAddressWithCall(_code, _salt, bytes("")); 32 | } 33 | 34 | function createContract(bytes memory _code, bytes32 _salt) 35 | public returns(address) 36 | { 37 | return createContractAndCall(_code, _salt, bytes("")); 38 | } 39 | 40 | function predictAddressWithCall(bytes memory _code, bytes32 _salt, bytes memory _call) 41 | public view returns(address) 42 | { 43 | return _predictAddress(_code, keccak256(abi.encodePacked(_salt, _call))); 44 | } 45 | 46 | function createContractAndCall(bytes memory _code, bytes32 _salt, bytes memory _call) 47 | public returns(address) 48 | { 49 | address addr = _create2(_code, keccak256(abi.encodePacked(_salt, _call))); 50 | emit NewContract(addr); 51 | if (_call.length > 0) 52 | { 53 | // solium-disable-next-line security/no-low-level-calls 54 | (bool success, bytes memory reason) = addr.call(_call); 55 | require(success, string(reason)); 56 | } 57 | return addr; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /contracts/Libs/ECDSA.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity ^0.6.0; 20 | pragma experimental ABIEncoderV2; 21 | 22 | contract ECDSA 23 | { 24 | struct signature 25 | { 26 | uint8 v; 27 | bytes32 r; 28 | bytes32 s; 29 | } 30 | 31 | function recover(bytes32 hash, signature memory sign) 32 | internal pure returns (address) 33 | { 34 | require(sign.v == 27 || sign.v == 28); 35 | return ecrecover(hash, sign.v, sign.r, sign.s); 36 | } 37 | 38 | function recover(bytes32 hash, bytes memory sign) 39 | internal pure returns (address) 40 | { 41 | bytes32 r; 42 | bytes32 s; 43 | uint8 v; 44 | 45 | if (sign.length == 65) // 65bytes: (r,s,v) form 46 | { 47 | assembly 48 | { 49 | r := mload(add(sign, 0x20)) 50 | s := mload(add(sign, 0x40)) 51 | v := byte(0, mload(add(sign, 0x60))) 52 | } 53 | } 54 | else if (sign.length == 64) // 64bytes: (r,vs) form → see EIP2098 55 | { 56 | assembly 57 | { 58 | r := mload(add(sign, 0x20)) 59 | s := and( mload(add(sign, 0x40)), 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) 60 | v := shr(7, byte(0, mload(add(sign, 0x40)))) 61 | } 62 | } 63 | else 64 | { 65 | revert("invalid-signature-format"); 66 | } 67 | 68 | if (v < 27) v += 27; 69 | require(v == 27 || v == 28); 70 | return ecrecover(hash, v, r, s); 71 | } 72 | 73 | function toEthSignedMessageHash(bytes32 hash) 74 | internal pure returns (bytes32) 75 | { 76 | return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); 77 | } 78 | 79 | function toEthTypedStructHash(bytes32 struct_hash, bytes32 domain_separator) 80 | internal pure returns (bytes32) 81 | { 82 | return keccak256(abi.encodePacked("\x19\x01", domain_separator, struct_hash)); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /contracts/Libs/ECDSALib.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity ^0.6.0; 20 | pragma experimental ABIEncoderV2; 21 | 22 | library ECDSALib 23 | { 24 | struct signature 25 | { 26 | uint8 v; 27 | bytes32 r; 28 | bytes32 s; 29 | } 30 | 31 | function recover(bytes32 hash, signature memory sign) 32 | public pure returns (address) 33 | { 34 | require(sign.v == 27 || sign.v == 28); 35 | return ecrecover(hash, sign.v, sign.r, sign.s); 36 | } 37 | 38 | function recover(bytes32 hash, bytes memory sign) 39 | public pure returns (address) 40 | { 41 | bytes32 r; 42 | bytes32 s; 43 | uint8 v; 44 | 45 | if (sign.length == 65) // 65bytes: (r,s,v) form 46 | { 47 | assembly 48 | { 49 | r := mload(add(sign, 0x20)) 50 | s := mload(add(sign, 0x40)) 51 | v := byte(0, mload(add(sign, 0x60))) 52 | } 53 | } 54 | else if (sign.length == 64) // 64bytes: (r,vs) form → see EIP2098 55 | { 56 | assembly 57 | { 58 | r := mload(add(sign, 0x20)) 59 | s := and( mload(add(sign, 0x40)), 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) 60 | v := shr(7, byte(0, mload(add(sign, 0x40)))) 61 | } 62 | } 63 | else 64 | { 65 | revert("invalid-signature-format"); 66 | } 67 | 68 | if (v < 27) v += 27; 69 | require(v == 27 || v == 28); 70 | return ecrecover(hash, v, r, s); 71 | } 72 | 73 | function toEthSignedMessageHash(bytes32 hash) 74 | public pure returns (bytes32) 75 | { 76 | return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); 77 | } 78 | 79 | function toEthTypedStructHash(bytes32 struct_hash, bytes32 domain_separator) 80 | public pure returns (bytes32) 81 | { 82 | return keccak256(abi.encodePacked("\x19\x01", domain_separator, struct_hash)); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /contracts/Libs/SafeMathExtended.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity ^0.6.0; 20 | 21 | /** 22 | * @title SafeMathExtended 23 | * @dev Unsigned math operations with safety checks that revert on error 24 | */ 25 | library SafeMathExtended 26 | { 27 | /** 28 | * @dev Adds two unsigned integers, reverts on overflow. 29 | */ 30 | function add(uint256 a, uint256 b) internal pure returns (uint256) 31 | { 32 | uint256 c = a + b; 33 | require(c >= a); 34 | return c; 35 | } 36 | 37 | /** 38 | * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend). 39 | */ 40 | function sub(uint256 a, uint256 b) internal pure returns (uint256) 41 | { 42 | require(b <= a); 43 | uint256 c = a - b; 44 | return c; 45 | } 46 | 47 | /** 48 | * @dev Multiplies two unsigned integers, reverts on overflow. 49 | */ 50 | function mul(uint256 a, uint256 b) internal pure returns (uint256) 51 | { 52 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 53 | // benefit is lost if 'b' is also tested. 54 | // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 55 | if (a == 0) 56 | { 57 | return 0; 58 | } 59 | uint256 c = a * b; 60 | require(c / a == b); 61 | return c; 62 | } 63 | 64 | /** 65 | * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero. 66 | */ 67 | function div(uint256 a, uint256 b) internal pure returns (uint256) 68 | { 69 | // Solidity only automatically asserts when dividing by 0 70 | require(b > 0); 71 | uint256 c = a / b; 72 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold 73 | return c; 74 | } 75 | 76 | /** 77 | * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo), 78 | * reverts when dividing by zero. 79 | */ 80 | function mod(uint256 a, uint256 b) internal pure returns (uint256) 81 | { 82 | require(b != 0); 83 | return a % b; 84 | } 85 | 86 | /** 87 | * @dev Returns the largest of two numbers. 88 | */ 89 | function max(uint256 a, uint256 b) internal pure returns (uint256) 90 | { 91 | return a >= b ? a : b; 92 | } 93 | 94 | /** 95 | * @dev Returns the smallest of two numbers. 96 | */ 97 | function min(uint256 a, uint256 b) internal pure returns (uint256) 98 | { 99 | return a < b ? a : b; 100 | } 101 | 102 | /** 103 | * @dev Multiplies the a by the fraction b/c 104 | */ 105 | function mulByFraction(uint256 a, uint256 b, uint256 c) internal pure returns (uint256) 106 | { 107 | return div(mul(a, b), c); 108 | } 109 | 110 | /** 111 | * @dev Return b percents of a (equivalent to a percents of b) 112 | */ 113 | function percentage(uint256 a, uint256 b) internal pure returns (uint256) 114 | { 115 | return mulByFraction(a, b, 100); 116 | } 117 | 118 | /** 119 | * @dev Returns the base 2 log of x 120 | * @notice Source : https://ethereum.stackexchange.com/questions/8086/logarithm-math-operation-in-solidity 121 | */ 122 | function log(uint x) internal pure returns (uint y) 123 | { 124 | assembly 125 | { 126 | let arg := x 127 | x := sub(x,1) 128 | x := or(x, div(x, 0x02)) 129 | x := or(x, div(x, 0x04)) 130 | x := or(x, div(x, 0x10)) 131 | x := or(x, div(x, 0x100)) 132 | x := or(x, div(x, 0x10000)) 133 | x := or(x, div(x, 0x100000000)) 134 | x := or(x, div(x, 0x10000000000000000)) 135 | x := or(x, div(x, 0x100000000000000000000000000000000)) 136 | x := add(x, 1) 137 | let m := mload(0x40) 138 | mstore(m, 0xf8f9cbfae6cc78fbefe7cdc3a1793dfcf4f0e8bbd8cec470b6a28a7a5a3e1efd) 139 | mstore(add(m,0x20), 0xf5ecf1b3e9debc68e1d9cfabc5997135bfb7a7a3938b7b606b5b4b3f2f1f0ffe) 140 | mstore(add(m,0x40), 0xf6e4ed9ff2d6b458eadcdf97bd91692de2d4da8fd2d0ac50c6ae9a8272523616) 141 | mstore(add(m,0x60), 0xc8c0b887b0a8a4489c948c7f847c6125746c645c544c444038302820181008ff) 142 | mstore(add(m,0x80), 0xf7cae577eec2a03cf3bad76fb589591debb2dd67e0aa9834bea6925f6a4a2e0e) 143 | mstore(add(m,0xa0), 0xe39ed557db96902cd38ed14fad815115c786af479b7e83247363534337271707) 144 | mstore(add(m,0xc0), 0xc976c13bb96e881cb166a933a55e490d9d56952b8d4e801485467d2362422606) 145 | mstore(add(m,0xe0), 0x753a6d1b65325d0c552a4d1345224105391a310b29122104190a110309020100) 146 | mstore(0x40, add(m, 0x100)) 147 | let magic := 0x818283848586878898a8b8c8d8e8f929395969799a9b9d9e9faaeb6bedeeff 148 | let shift := 0x100000000000000000000000000000000000000000000000000000000000000 149 | let a := div(mul(x, magic), shift) 150 | y := div(mload(add(m,sub(255,a))), shift) 151 | y := add(y, mul(256, gt(arg, 0x8000000000000000000000000000000000000000000000000000000000000000))) 152 | } 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /contracts/Migrations.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity >=0.4.21; 20 | 21 | contract Migrations { 22 | address public owner; 23 | uint public last_completed_migration; 24 | 25 | constructor() public { 26 | owner = msg.sender; 27 | } 28 | 29 | modifier restricted() { 30 | if (msg.sender == owner) _; 31 | } 32 | 33 | function setCompleted(uint completed) public restricted { 34 | last_completed_migration = completed; 35 | } 36 | 37 | function upgrade(address new_address) public restricted { 38 | Migrations upgraded = Migrations(new_address); 39 | upgraded.setCompleted(last_completed_migration); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /contracts/TestContract.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity ^0.6.0; 20 | 21 | contract TestContract 22 | { 23 | string public constant id = "TestContract"; 24 | address public caller; 25 | bytes public value; 26 | 27 | event Receive(uint256 value, bytes data); 28 | event Fallback(uint256 value, bytes data); 29 | 30 | receive() 31 | external payable 32 | { 33 | emit Receive(msg.value, msg.data); 34 | } 35 | 36 | fallback() 37 | external payable 38 | { 39 | emit Fallback(msg.value, msg.data); 40 | } 41 | 42 | function set(bytes calldata _value) 43 | external 44 | { 45 | caller = msg.sender; 46 | value = _value; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /contracts/Upgradeability/BaseUpgradeabilityProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity ^0.6.0; 20 | 21 | import '@openzeppelin/contracts/utils/Address.sol'; 22 | import './Proxy.sol'; 23 | 24 | /** 25 | * @title BaseUpgradeabilityProxy 26 | * @dev This contract implements a proxy that allows to change the 27 | * implementation address to which it will delegate. 28 | * Such a change is called an implementation upgrade. 29 | */ 30 | contract BaseUpgradeabilityProxy is Proxy { 31 | /** 32 | * @dev Emitted when the implementation is upgraded. 33 | * @param implementation Address of the new implementation. 34 | */ 35 | event Upgraded(address indexed implementation); 36 | 37 | /** 38 | * @dev Storage slot with the address of the current implementation. 39 | * This is the keccak-256 hash of "org.zeppelinos.proxy.implementation", and is 40 | * validated in the constructor. 41 | */ 42 | bytes32 internal constant IMPLEMENTATION_SLOT = 0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3; 43 | 44 | /** 45 | * @dev Returns the current implementation. 46 | * @return impl Address of the current implementation 47 | */ 48 | function _implementation() internal override view returns (address impl) { 49 | bytes32 slot = IMPLEMENTATION_SLOT; 50 | assembly { 51 | impl := sload(slot) 52 | } 53 | } 54 | 55 | /** 56 | * @dev Upgrades the proxy to a new implementation. 57 | * @param newImplementation Address of the new implementation. 58 | */ 59 | function _upgradeTo(address newImplementation) internal { 60 | _setImplementation(newImplementation); 61 | emit Upgraded(newImplementation); 62 | } 63 | 64 | /** 65 | * @dev Sets the implementation address of the proxy. 66 | * @param newImplementation Address of the new implementation. 67 | */ 68 | function _setImplementation(address newImplementation) internal { 69 | require(Address.isContract(newImplementation), "Cannot set a proxy implementation to a non-contract address"); 70 | 71 | bytes32 slot = IMPLEMENTATION_SLOT; 72 | 73 | assembly { 74 | sstore(slot, newImplementation) 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /contracts/Upgradeability/InitializableUpgradeabilityProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity ^0.6.0; 20 | 21 | import './BaseUpgradeabilityProxy.sol'; 22 | 23 | /** 24 | * @title InitializableUpgradeabilityProxy 25 | * @dev Extends BaseUpgradeabilityProxy with an initializer for initializing 26 | * implementation and init data. 27 | */ 28 | contract InitializableUpgradeabilityProxy is BaseUpgradeabilityProxy { 29 | /** 30 | * @dev Contract initializer. 31 | * @param _logic Address of the initial implementation. 32 | * @param _data Data to send as msg.data to the implementation to initialize the proxied contract. 33 | * It should include the signature and the parameters of the function to be called, as described in 34 | * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. 35 | * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped. 36 | */ 37 | function initialize(address _logic, bytes memory _data) public payable { 38 | require(_implementation() == address(0)); 39 | assert(IMPLEMENTATION_SLOT == keccak256("org.zeppelinos.proxy.implementation")); 40 | _setImplementation(_logic); 41 | if(_data.length > 0) { 42 | (bool success,) = _logic.delegatecall(_data); 43 | require(success); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /contracts/Upgradeability/Proxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity ^0.6.0; 20 | 21 | /** 22 | * @title Proxy 23 | * @dev Implements delegation of calls to other contracts, with proper 24 | * forwarding of return values and bubbling of failures. 25 | * It defines a fallback function that delegates all calls to the address 26 | * returned by the abstract _implementation() internal function. 27 | */ 28 | abstract contract Proxy { 29 | /** 30 | * @dev Receive function. 31 | * Implemented entirely in `_fallback`. 32 | */ 33 | receive() external payable virtual { 34 | _fallback(); 35 | } 36 | 37 | /** 38 | * @dev Fallback function. 39 | * Implemented entirely in `_fallback`. 40 | */ 41 | fallback() external payable { 42 | _fallback(); 43 | } 44 | 45 | /** 46 | * @return impl The Address of the implementation. 47 | */ 48 | function _implementation() internal virtual view returns (address impl); 49 | 50 | /** 51 | * @dev Delegates execution to an implementation contract. 52 | * This is a low level function that doesn't return to its internal call site. 53 | * It will return to the external caller whatever the implementation returns. 54 | * @param implementation Address to delegate. 55 | */ 56 | function _delegate(address implementation) internal { 57 | assembly { 58 | // Copy msg.data. We take full control of memory in this inline assembly 59 | // block because it will not return to Solidity code. We overwrite the 60 | // Solidity scratch pad at memory position 0. 61 | calldatacopy(0, 0, calldatasize()) 62 | 63 | // Call the implementation. 64 | // out and outsize are 0 because we don't know the size yet. 65 | let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) 66 | 67 | // Copy the returned data. 68 | returndatacopy(0, 0, returndatasize()) 69 | 70 | switch result 71 | // delegatecall returns 0 on error. 72 | case 0 { revert(0, returndatasize()) } 73 | default { return(0, returndatasize()) } 74 | } 75 | } 76 | 77 | /** 78 | * @dev Function that is run as the first thing in the fallback function. 79 | * Can be redefined in derived contracts to add functionality. 80 | * Redefinitions must call super._willFallback(). 81 | */ 82 | function _willFallback() internal virtual { 83 | } 84 | 85 | /** 86 | * @dev fallback implementation. 87 | * Extracted to enable manual triggering. 88 | */ 89 | function _fallback() internal { 90 | _willFallback(); 91 | _delegate(_implementation()); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /deployment/factory.json: -------------------------------------------------------------------------------- 1 | {"address":"0xfAC000a12dA42B871c0AaD5F25391aAe62958Db1","deployer":"0x519ca6F2EA1b833de9d7B23485c403BA5a6899A8","cost":5194156000000000,"tx":"0xf908078085028fa6ae00830734848080b907b4608060405234801561001057600080fd5b50610794806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80631dcce26514610051578063482f20241461019e5780638563a8f614610244578063bbdd8aeb146102ea575b600080fd5b6101826004803603606081101561006757600080fd5b810190602081018135600160201b81111561008157600080fd5b82018360208201111561009357600080fd5b803590602001918460018302840111600160201b831117156100b457600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092958435959094909350604081019250602001359050600160201b81111561010e57600080fd5b82018360208201111561012057600080fd5b803590602001918460018302840111600160201b8311171561014157600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061041b945050505050565b604080516001600160a01b039092168252519081900360200190f35b610182600480360360408110156101b457600080fd5b810190602081018135600160201b8111156101ce57600080fd5b8201836020820111156101e057600080fd5b803590602001918460018302840111600160201b8311171561020157600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955050913592506104a4915050565b6101826004803603604081101561025a57600080fd5b810190602081018135600160201b81111561027457600080fd5b82018360208201111561028657600080fd5b803590602001918460018302840111600160201b831117156102a757600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955050913592506104c7915050565b6101826004803603606081101561030057600080fd5b810190602081018135600160201b81111561031a57600080fd5b82018360208201111561032c57600080fd5b803590602001918460018302840111600160201b8311171561034d57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092958435959094909350604081019250602001359050600160201b8111156103a757600080fd5b8201836020820111156103b957600080fd5b803590602001918460018302840111600160201b831117156103da57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506104df945050505050565b600061049c8484846040516020018083815260200182805190602001908083835b6020831061045b5780518252601f19909201916020918201910161043c565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052805190602001206106df565b949350505050565b60006104c083836040518060200160405280600081525061041b565b9392505050565b60006104c08383604051806020016040528060008152505b6000806105618585856040516020018083815260200182805190602001908083835b602083106105205780518252601f199092019160209182019101610501565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405280519060200120610735565b6040519091506001600160a01b038216907f387ea218537e939551af33bbc2dd6c53b1fee55d377a0dce288258f972cb3a9c90600090a282511561049c5760006060826001600160a01b0316856040518082805190602001908083835b602083106105dd5780518252601f1990920191602091820191016105be565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461063f576040519150601f19603f3d011682016040523d82523d6000602084013e610644565b606091505b50915091508181906106d45760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610699578181015183820152602001610681565b50505050905090810190601f1680156106c65780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050949350505050565b8151602092830120604080516001600160f81b0319818601523060601b6021820152603581019390935260558084019290925280518084039092018252607590920190915280519101206001600160a01b031690565b815160009083908390839082906020850183f59050803b61075557600080fd5b9594505050505056fea2646970667358221220d30d7bad226f3b603fe6d87b4642d706cee02daab1e811fe1e12f76f2718be2564736f6c634300060400331ca07c9ec4ee17853fed32bf4abc268715430353c3d052c9133b2d2e7f32ea0a5678a05f815e2466f467b18925a3de4e305ea397f73b7c5f6294ab208f14fb7664225a","compiler":"0.6.4+commit.1dca32f3.Emscripten.clang","abi":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"}],"name":"NewContract","type":"event"},{"inputs":[{"internalType":"bytes","name":"_code","type":"bytes"},{"internalType":"bytes32","name":"_salt","type":"bytes32"}],"name":"predictAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_code","type":"bytes"},{"internalType":"bytes32","name":"_salt","type":"bytes32"}],"name":"createContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_code","type":"bytes"},{"internalType":"bytes32","name":"_salt","type":"bytes32"},{"internalType":"bytes","name":"_call","type":"bytes"}],"name":"predictAddressWithCall","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_code","type":"bytes"},{"internalType":"bytes32","name":"_salt","type":"bytes32"},{"internalType":"bytes","name":"_call","type":"bytes"}],"name":"createContractAndCall","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"}]} 2 | -------------------------------------------------------------------------------- /migrations/1_initial_migration.js: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ******************************************************************************/ 16 | 17 | var Migrations = artifacts.require("./Migrations.sol"); 18 | 19 | module.exports = function(deployer) { 20 | deployer.deploy(Migrations); 21 | }; 22 | -------------------------------------------------------------------------------- /migrations/2_deploy_contracts.js: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ******************************************************************************/ 16 | 17 | module.exports = async function(deployer, network, accounts) 18 | { 19 | console.log("# web3 version:", web3.version); 20 | chainid = await web3.eth.net.getId(); 21 | chaintype = await web3.eth.net.getNetworkType() 22 | console.log("Chainid is:", chainid); 23 | console.log("Chaintype is:", chaintype); 24 | }; 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@iexec/solidity", 3 | "version": "0.1.1", 4 | "description": "", 5 | "main": "truffle.js", 6 | "scripts": { 7 | "build": "truffle compile", 8 | "test": "truffle test", 9 | "autotest": "./autotest.sh", 10 | "coverage": "truffle run coverage" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/iExecBlockchainComputing/iexec-solidity.git" 15 | }, 16 | "bugs": { 17 | "url": "https://github.com/iExecBlockchainComputing/iexec-solidity.git/issues" 18 | }, 19 | "files": [ 20 | "/deployment", 21 | "/build", 22 | "/contracts" 23 | ], 24 | "author": "iExec", 25 | "license": "Apache-2.0", 26 | "homepage": "https://github.com/iExecBlockchainComputing/iexec-solidity.git#readme", 27 | "dependencies": { 28 | "@openzeppelin/contracts": "3.2.0", 29 | "solstruct": "0.1.0" 30 | }, 31 | "devDependencies": { 32 | "@openzeppelin/test-helpers": "0.5.6", 33 | "chai": "4.2.0", 34 | "ganache-cli": "6.10.2", 35 | "solidity-coverage": "0.7.10", 36 | "truffle": "5.1.45" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /test/ERC1538/ERC1538.js: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ******************************************************************************/ 16 | 17 | var ERC1538Proxy = artifacts.require("./ERC1538Proxy"); 18 | var ERC1538Update = artifacts.require("./ERC1538UpdateDelegate"); 19 | var ERC1538Query = artifacts.require("./ERC1538QueryDelegate"); 20 | var TestContract = artifacts.require("./TestContract"); 21 | 22 | const { expectRevert } = require('@openzeppelin/test-helpers'); 23 | 24 | function getSerializedObject(entry) 25 | { 26 | if (entry.type == 'tuple') 27 | { 28 | return '(' + entry.components.map(getSerializedObject).join(',') + ')' 29 | } 30 | else 31 | { 32 | return entry.type; 33 | } 34 | } 35 | 36 | function getFunctionSignatures(abi) 37 | { 38 | return abi 39 | .filter(entry => entry.type == 'function') 40 | .filter(entry => !entry.name.startsWith('coverage_0x')) // remove solidity coverage injected code 41 | .map(entry => entry.name + '(' + entry.inputs.map(getSerializedObject).join(',') + ');') 42 | .join('') 43 | } 44 | 45 | function extractEvents(txMined, address, name) 46 | { 47 | return txMined.logs.filter((ev) => { return ev.address == address && ev.event == name; }); 48 | } 49 | 50 | contract('ERC1538', async (accounts) => { 51 | 52 | before("configure", async () => { 53 | ERC1538UpdateInstance = await ERC1538Update.new(); 54 | ERC1538QueryInstance = await ERC1538Query.new(); 55 | 56 | ProxyInterface = await ERC1538Proxy.new(ERC1538UpdateInstance.address); 57 | UpdateInterface = await ERC1538Update.at(ProxyInterface.address); 58 | QueryInterface = await ERC1538Query.at(ProxyInterface.address); 59 | 60 | TestContractInstance = await TestContract.new(); 61 | 62 | for (delegate of [ ERC1538QueryInstance ]) 63 | { 64 | await UpdateInterface.updateContract( 65 | delegate.address, 66 | getFunctionSignatures(delegate.abi), 67 | `Linking ${delegate.contractName}` 68 | ); 69 | } 70 | 71 | SIGNATURES = { 72 | 'updateContract(address,string,string)': ERC1538UpdateInstance.address, 73 | 'owner()': ERC1538QueryInstance.address, 74 | 'renounceOwnership()': ERC1538QueryInstance.address, 75 | 'transferOwnership(address)': ERC1538QueryInstance.address, 76 | 'totalFunctions()': ERC1538QueryInstance.address, 77 | 'functionByIndex(uint256)': ERC1538QueryInstance.address, 78 | 'functionById(bytes4)': ERC1538QueryInstance.address, 79 | 'functionExists(string)': ERC1538QueryInstance.address, 80 | 'delegateAddress(string)': ERC1538QueryInstance.address, 81 | 'functionSignatures()': ERC1538QueryInstance.address, 82 | 'delegateFunctionSignatures(address)': ERC1538QueryInstance.address, 83 | 'delegateAddresses()': ERC1538QueryInstance.address, 84 | } 85 | 86 | }); 87 | 88 | it("Ownership", async () => { 89 | assert.equal(await ERC1538UpdateInstance.owner(), "0x0000000000000000000000000000000000000000"); 90 | assert.equal(await ERC1538QueryInstance.owner(), "0x0000000000000000000000000000000000000000"); 91 | assert.equal(await ProxyInterface.owner(), accounts[0]); 92 | assert.equal(await UpdateInterface.owner(), accounts[0]); 93 | assert.equal(await QueryInterface.owner(), accounts[0]); 94 | }); 95 | 96 | it("ERC1538Query - totalFunctions", async () => { 97 | assert.equal(await QueryInterface.totalFunctions(), Object.keys(SIGNATURES).length); 98 | }); 99 | 100 | it("ERC1538Query - functionByIndex", async () => { 101 | for (const i in Object.keys(SIGNATURES)) 102 | { 103 | const [ signature, delegate ] = Object.entries(SIGNATURES)[i]; 104 | const id = web3.utils.soliditySha3({t: 'string', v: signature}).substr(0, 10) 105 | 106 | const result = await QueryInterface.functionByIndex(i); 107 | assert.equal(result.signature, signature); 108 | assert.equal(result.id, id); 109 | assert.equal(result.delegate, delegate); 110 | } 111 | }); 112 | 113 | it("ERC1538Query - functionById", async () => { 114 | for (const i in Object.keys(SIGNATURES)) 115 | { 116 | const [ signature, delegate ] = Object.entries(SIGNATURES)[i]; 117 | const id = web3.utils.soliditySha3({t: 'string', v: signature}).substr(0, 10) 118 | 119 | const result = await QueryInterface.functionById(id); 120 | assert.equal(result.signature, signature); 121 | assert.equal(result.id, id); 122 | assert.equal(result.delegate, delegate); 123 | } 124 | }); 125 | 126 | it("ERC1538Query - functionExists", async () => { 127 | for (const signature of Object.keys(SIGNATURES)) 128 | { 129 | assert.isTrue(await QueryInterface.functionExists(signature)); 130 | } 131 | }); 132 | 133 | it("ERC1538Query - functionSignatures", async () => { 134 | assert.equal( 135 | await QueryInterface.functionSignatures(), 136 | [ 137 | ...Object.keys(SIGNATURES), 138 | '' 139 | ].join(';') 140 | ); 141 | }); 142 | 143 | it("ERC1538Query - delegateFunctionSignatures", async () => { 144 | for (delegate of await QueryInterface.delegateAddresses()) 145 | { 146 | assert.equal( 147 | await QueryInterface.delegateFunctionSignatures(delegate), 148 | [ 149 | ...Object.entries(SIGNATURES).filter(([s, d]) => d == delegate).map(([s,d]) => s), 150 | '' 151 | ].join(';') 152 | ); 153 | } 154 | }); 155 | 156 | it("ERC1538Query - delegateAddress", async () => { 157 | for (const [ signature, delegate ] of Object.entries(SIGNATURES)) 158 | { 159 | assert.equal( 160 | await QueryInterface.delegateAddress(signature), 161 | delegate 162 | ); 163 | } 164 | }); 165 | 166 | it("ERC1538Query - delegateAddresses", async () => { 167 | assert.deepEqual( 168 | (await QueryInterface.delegateAddresses()), 169 | Object.values(SIGNATURES).filter((v, i, a) => a.indexOf(v) === i) 170 | ); 171 | }); 172 | 173 | it("ERC1538 - receive", async () => { 174 | tx = await UpdateInterface.updateContract(TestContractInstance.address, "receive;", "adding receive delegate"); 175 | 176 | evs = extractEvents(tx, UpdateInterface.address, "FunctionUpdate"); 177 | assert.equal(evs.length, 1); 178 | assert.equal(evs[0].args.functionId, "0x0000000000000000000000000000000000000000000000000000000000000000"); 179 | assert.equal(evs[0].args.oldDelegate, "0x0000000000000000000000000000000000000000"); 180 | assert.equal(evs[0].args.newDelegate, TestContractInstance.address); 181 | assert.equal(evs[0].args.functionSignature, "receive"); 182 | 183 | evs = extractEvents(tx, UpdateInterface.address, "CommitMessage"); 184 | assert.equal(evs.length, 1); 185 | assert.equal(evs[0].args.message, "adding receive delegate"); 186 | 187 | tx = await web3.eth.sendTransaction({ from: accounts[0], to: UpdateInterface.address, value: 0, data: "0x", gasLimit: 500000 }); 188 | assert.equal(tx.logs[0].topics[0], web3.utils.keccak256("Receive(uint256,bytes)")); 189 | }); 190 | 191 | it("ERC1538 - fallback", async () => { 192 | tx = await UpdateInterface.updateContract(TestContractInstance.address, "fallback;", "adding fallback delegate"); 193 | 194 | evs = extractEvents(tx, UpdateInterface.address, "FunctionUpdate"); 195 | assert.equal(evs.length, 1); 196 | assert.equal(evs[0].args.functionId, "0xffffffff00000000000000000000000000000000000000000000000000000000"); 197 | assert.equal(evs[0].args.oldDelegate, "0x0000000000000000000000000000000000000000"); 198 | assert.equal(evs[0].args.newDelegate, TestContractInstance.address); 199 | assert.equal(evs[0].args.functionSignature, "fallback"); 200 | 201 | evs = extractEvents(tx, UpdateInterface.address, "CommitMessage"); 202 | assert.equal(evs.length, 1); 203 | assert.equal(evs[0].args.message, "adding fallback delegate"); 204 | 205 | tx = await web3.eth.sendTransaction({ from: accounts[0], to: UpdateInterface.address, value: 0, data: "0xc0ffee", gasLimit: 500000 }); 206 | assert.equal(tx.logs[0].topics[0], web3.utils.keccak256("Fallback(uint256,bytes)")); 207 | }); 208 | 209 | it("ERC1538 - no update", async () => { 210 | tx = await UpdateInterface.updateContract(TestContractInstance.address, "fallback;", "no changes"); 211 | 212 | evs = extractEvents(tx, UpdateInterface.address, "FunctionUpdate"); 213 | assert.equal(evs.length, 0); 214 | 215 | evs = extractEvents(tx, UpdateInterface.address, "CommitMessage"); 216 | assert.equal(evs.length, 1); 217 | assert.equal(evs[0].args.message, "no changes"); 218 | }); 219 | 220 | it("ERC1538 - remove fallback", async () => { 221 | tx = await UpdateInterface.updateContract("0x0000000000000000000000000000000000000000", "fallback;", "removing"); 222 | 223 | evs = extractEvents(tx, UpdateInterface.address, "FunctionUpdate"); 224 | assert.equal(evs.length, 1); 225 | assert.equal(evs[0].args.oldDelegate, TestContractInstance.address); 226 | assert.equal(evs[0].args.newDelegate, "0x0000000000000000000000000000000000000000"); 227 | assert.equal(evs[0].args.functionSignature, "fallback"); 228 | 229 | evs = extractEvents(tx, UpdateInterface.address, "CommitMessage"); 230 | assert.equal(evs.length, 1); 231 | assert.equal(evs[0].args.message, "removing"); 232 | }); 233 | }); 234 | -------------------------------------------------------------------------------- /test/ERC1538/ERC1538v2.js: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ******************************************************************************/ 16 | 17 | var ERC1538Proxy = artifacts.require("./ERC1538ProxyV2"); 18 | var ERC1538Update = artifacts.require("./ERC1538UpdateV2Delegate"); 19 | var ERC1538Query = artifacts.require("./ERC1538QueryDelegate"); 20 | var TestContract = artifacts.require("./TestContract"); 21 | 22 | const { expectRevert } = require('@openzeppelin/test-helpers'); 23 | 24 | function getSerializedObject(entry) 25 | { 26 | if (entry.type == 'tuple') 27 | { 28 | return '(' + entry.components.map(getSerializedObject).join(',') + ')' 29 | } 30 | else 31 | { 32 | return entry.type; 33 | } 34 | } 35 | 36 | function getFunctionSignatures(abi) 37 | { 38 | return abi 39 | .filter(entry => entry.type == 'function') 40 | .filter(entry => !entry.name.startsWith('coverage_0x')) // remove solidity coverage injected code 41 | .map(entry => entry.name + '(' + entry.inputs.map(getSerializedObject).join(',') + ')') 42 | } 43 | 44 | function extractEvents(txMined, address, name) 45 | { 46 | return txMined.logs.filter((ev) => { return ev.address == address && ev.event == name; }); 47 | } 48 | 49 | contract('ERC1538', async (accounts) => { 50 | 51 | before("configure", async () => { 52 | ERC1538UpdateInstance = await ERC1538Update.new(); 53 | ERC1538QueryInstance = await ERC1538Query.new(); 54 | 55 | ProxyInterface = await ERC1538Proxy.new(ERC1538UpdateInstance.address); 56 | UpdateInterface = await ERC1538Update.at(ProxyInterface.address); 57 | QueryInterface = await ERC1538Query.at(ProxyInterface.address); 58 | 59 | TestContractInstance = await TestContract.new(); 60 | 61 | for (delegate of [ ERC1538QueryInstance ]) 62 | { 63 | await UpdateInterface.updateContract( 64 | delegate.address, 65 | getFunctionSignatures(delegate.abi), 66 | `Linking ${delegate.contractName}` 67 | ); 68 | } 69 | 70 | SIGNATURES = { 71 | 'updateContract(address,string[],string)': ERC1538UpdateInstance.address, 72 | 'owner()': ERC1538QueryInstance.address, 73 | 'renounceOwnership()': ERC1538QueryInstance.address, 74 | 'transferOwnership(address)': ERC1538QueryInstance.address, 75 | 'totalFunctions()': ERC1538QueryInstance.address, 76 | 'functionByIndex(uint256)': ERC1538QueryInstance.address, 77 | 'functionById(bytes4)': ERC1538QueryInstance.address, 78 | 'functionExists(string)': ERC1538QueryInstance.address, 79 | 'delegateAddress(string)': ERC1538QueryInstance.address, 80 | 'functionSignatures()': ERC1538QueryInstance.address, 81 | 'delegateFunctionSignatures(address)': ERC1538QueryInstance.address, 82 | 'delegateAddresses()': ERC1538QueryInstance.address, 83 | } 84 | 85 | }); 86 | 87 | it("Ownership", async () => { 88 | assert.equal(await ERC1538UpdateInstance.owner(), "0x0000000000000000000000000000000000000000"); 89 | assert.equal(await ERC1538QueryInstance.owner(), "0x0000000000000000000000000000000000000000"); 90 | assert.equal(await ProxyInterface.owner(), accounts[0]); 91 | assert.equal(await UpdateInterface.owner(), accounts[0]); 92 | assert.equal(await QueryInterface.owner(), accounts[0]); 93 | }); 94 | 95 | it("ERC1538Query - totalFunctions", async () => { 96 | assert.equal(await QueryInterface.totalFunctions(), Object.keys(SIGNATURES).length); 97 | }); 98 | 99 | it("ERC1538Query - functionByIndex", async () => { 100 | for (const i in Object.keys(SIGNATURES)) 101 | { 102 | const [ signature, delegate ] = Object.entries(SIGNATURES)[i]; 103 | const id = web3.utils.soliditySha3({t: 'string', v: signature}).substr(0, 10) 104 | 105 | const result = await QueryInterface.functionByIndex(i); 106 | assert.equal(result.signature, signature); 107 | assert.equal(result.id, id); 108 | assert.equal(result.delegate, delegate); 109 | } 110 | }); 111 | 112 | it("ERC1538Query - functionById", async () => { 113 | for (const i in Object.keys(SIGNATURES)) 114 | { 115 | const [ signature, delegate ] = Object.entries(SIGNATURES)[i]; 116 | const id = web3.utils.soliditySha3({t: 'string', v: signature}).substr(0, 10) 117 | 118 | const result = await QueryInterface.functionById(id); 119 | assert.equal(result.signature, signature); 120 | assert.equal(result.id, id); 121 | assert.equal(result.delegate, delegate); 122 | } 123 | }); 124 | 125 | it("ERC1538Query - functionExists", async () => { 126 | for (const signature of Object.keys(SIGNATURES)) 127 | { 128 | assert.isTrue(await QueryInterface.functionExists(signature)); 129 | } 130 | }); 131 | 132 | it("ERC1538Query - functionSignatures", async () => { 133 | assert.equal( 134 | await QueryInterface.functionSignatures(), 135 | [ 136 | ...Object.keys(SIGNATURES), 137 | '' 138 | ].join(';') 139 | ); 140 | }); 141 | 142 | it("ERC1538Query - delegateFunctionSignatures", async () => { 143 | for (delegate of await QueryInterface.delegateAddresses()) 144 | { 145 | assert.equal( 146 | await QueryInterface.delegateFunctionSignatures(delegate), 147 | [ 148 | ...Object.entries(SIGNATURES).filter(([s, d]) => d == delegate).map(([s,d]) => s), 149 | '' 150 | ].join(';') 151 | ); 152 | } 153 | }); 154 | 155 | it("ERC1538Query - delegateAddress", async () => { 156 | for (const [ signature, delegate ] of Object.entries(SIGNATURES)) 157 | { 158 | assert.equal( 159 | await QueryInterface.delegateAddress(signature), 160 | delegate 161 | ); 162 | } 163 | }); 164 | 165 | it("ERC1538Query - delegateAddresses", async () => { 166 | assert.deepEqual( 167 | (await QueryInterface.delegateAddresses()), 168 | Object.values(SIGNATURES).filter((v, i, a) => a.indexOf(v) === i) 169 | ); 170 | }); 171 | 172 | it("ERC1538 - receive", async () => { 173 | tx = await UpdateInterface.updateContract(TestContractInstance.address, [ "receive" ], "adding receive delegate"); 174 | 175 | evs = extractEvents(tx, UpdateInterface.address, "FunctionUpdate"); 176 | assert.equal(evs.length, 1); 177 | assert.equal(evs[0].args.functionId, "0x0000000000000000000000000000000000000000000000000000000000000000"); 178 | assert.equal(evs[0].args.oldDelegate, "0x0000000000000000000000000000000000000000"); 179 | assert.equal(evs[0].args.newDelegate, TestContractInstance.address); 180 | assert.equal(evs[0].args.functionSignature, "receive"); 181 | 182 | evs = extractEvents(tx, UpdateInterface.address, "CommitMessage"); 183 | assert.equal(evs.length, 1); 184 | assert.equal(evs[0].args.message, "adding receive delegate"); 185 | 186 | tx = await web3.eth.sendTransaction({ from: accounts[0], to: UpdateInterface.address, value: 0, data: "0x", gasLimit: 500000 }); 187 | assert.equal(tx.logs[0].topics[0], web3.utils.keccak256("Receive(uint256,bytes)")); 188 | }); 189 | 190 | it("ERC1538 - fallback", async () => { 191 | tx = await UpdateInterface.updateContract(TestContractInstance.address, [ "fallback" ], "adding fallback delegate"); 192 | 193 | evs = extractEvents(tx, UpdateInterface.address, "FunctionUpdate"); 194 | assert.equal(evs.length, 1); 195 | assert.equal(evs[0].args.functionId, "0xffffffff00000000000000000000000000000000000000000000000000000000"); 196 | assert.equal(evs[0].args.oldDelegate, "0x0000000000000000000000000000000000000000"); 197 | assert.equal(evs[0].args.newDelegate, TestContractInstance.address); 198 | assert.equal(evs[0].args.functionSignature, "fallback"); 199 | 200 | evs = extractEvents(tx, UpdateInterface.address, "CommitMessage"); 201 | assert.equal(evs.length, 1); 202 | assert.equal(evs[0].args.message, "adding fallback delegate"); 203 | 204 | tx = await web3.eth.sendTransaction({ from: accounts[0], to: UpdateInterface.address, value: 0, data: "0xc0ffee", gasLimit: 500000 }); 205 | assert.equal(tx.logs[0].topics[0], web3.utils.keccak256("Fallback(uint256,bytes)")); 206 | }); 207 | 208 | it("ERC1538 - no update", async () => { 209 | tx = await UpdateInterface.updateContract(TestContractInstance.address, [ "fallback" ], "no changes"); 210 | 211 | evs = extractEvents(tx, UpdateInterface.address, "FunctionUpdate"); 212 | assert.equal(evs.length, 0); 213 | 214 | evs = extractEvents(tx, UpdateInterface.address, "CommitMessage"); 215 | assert.equal(evs.length, 1); 216 | assert.equal(evs[0].args.message, "no changes"); 217 | }); 218 | 219 | it("ERC1538 - remove fallback", async () => { 220 | tx = await UpdateInterface.updateContract("0x0000000000000000000000000000000000000000", [ "fallback" ], "removing"); 221 | 222 | evs = extractEvents(tx, UpdateInterface.address, "FunctionUpdate"); 223 | assert.equal(evs.length, 1); 224 | assert.equal(evs[0].args.oldDelegate, TestContractInstance.address); 225 | assert.equal(evs[0].args.newDelegate, "0x0000000000000000000000000000000000000000"); 226 | assert.equal(evs[0].args.functionSignature, "fallback"); 227 | 228 | evs = extractEvents(tx, UpdateInterface.address, "CommitMessage"); 229 | assert.equal(evs.length, 1); 230 | assert.equal(evs[0].args.message, "removing"); 231 | }); 232 | }); 233 | -------------------------------------------------------------------------------- /test/Factory/GenericFactory.js: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ******************************************************************************/ 16 | 17 | var GenericFactory = artifacts.require("GenericFactory"); 18 | var TestContract = artifacts.require("TestContract"); 19 | 20 | const { expectRevert } = require('@openzeppelin/test-helpers'); 21 | const { predict } = require('./predict.js'); 22 | 23 | function extractEvents(txMined, address, name) 24 | { 25 | return txMined.logs.filter((ev) => { return ev.address == address && ev.event == name; }); 26 | } 27 | 28 | contract('GenericFactory', async (accounts) => { 29 | 30 | before("configure", async () => { 31 | GenericFactoryInstance = await GenericFactory.new(); 32 | }); 33 | 34 | describe("createContract", async () => { 35 | 36 | code = new web3.eth.Contract(TestContract.abi).deploy({ 37 | data: TestContract.bytecode, 38 | arguments: [] 39 | }).encodeABI(); 40 | 41 | it("select random salt", async () => { 42 | salt = web3.utils.randomHex(32); 43 | }); 44 | 45 | it("predict address", async () => { 46 | predictedAddress = predict(GenericFactoryInstance.address, code, salt); 47 | assert.equal(await GenericFactoryInstance.predictAddress(code, salt), predictedAddress); 48 | }); 49 | 50 | it("success (first)", async () => { 51 | txMined = await GenericFactoryInstance.createContract(code, salt); 52 | events = extractEvents(txMined, GenericFactoryInstance.address, "NewContract"); 53 | assert.equal(events[0].args.addr, predictedAddress); 54 | }); 55 | 56 | it("failure (duplicate)", async () => { 57 | await expectRevert.unspecified(GenericFactoryInstance.createContract(code, salt)); 58 | }); 59 | 60 | it("post check", async () => { 61 | TestInstance = await TestContract.at(predictedAddress); 62 | assert.equal(await TestInstance.id(), "TestContract"); 63 | assert.equal(await TestInstance.caller(), "0x0000000000000000000000000000000000000000"); 64 | assert.equal(await TestInstance.value(), null); 65 | }); 66 | 67 | }); 68 | 69 | describe("createContractAndCall", async () => { 70 | 71 | code = new web3.eth.Contract(TestContract.abi).deploy({ 72 | data: TestContract.bytecode, 73 | arguments: [] 74 | }).encodeABI(); 75 | 76 | it("select random salt and value", async () => { 77 | salt = web3.utils.randomHex(32); 78 | value = web3.utils.randomHex(64); 79 | call = web3.eth.abi.encodeFunctionCall({ name: 'set', type: 'function', inputs: [{ type: 'bytes', name: '_value' }] }, [ value ]); 80 | }); 81 | 82 | it("predict address", async () => { 83 | predictedAddress = predict(GenericFactoryInstance.address, code, salt, call); 84 | assert.equal(await GenericFactoryInstance.predictAddressWithCall(code, salt, call), predictedAddress); 85 | }); 86 | 87 | it("success (first)", async () => { 88 | txMined = await GenericFactoryInstance.createContractAndCall(code, salt, call); 89 | events = extractEvents(txMined, GenericFactoryInstance.address, "NewContract"); 90 | assert.equal(events[0].args.addr, predictedAddress); 91 | }); 92 | 93 | it("failure (duplicate)", async () => { 94 | await expectRevert.unspecified(GenericFactoryInstance.createContractAndCall(code, salt, call)); 95 | }); 96 | 97 | it("post check", async () => { 98 | TestInstance = await TestContract.at(predictedAddress); 99 | assert.equal(await TestInstance.id(), "TestContract"); 100 | assert.equal(await TestInstance.caller(), GenericFactoryInstance.address); 101 | assert.equal(await TestInstance.value(), value); 102 | }); 103 | 104 | }); 105 | }); 106 | -------------------------------------------------------------------------------- /test/Factory/predict.js: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ******************************************************************************/ 16 | 17 | function prepareSalt(salt, call="") 18 | { 19 | return web3.utils.soliditySha3( 20 | { t: 'bytes32', v: salt }, 21 | { t: 'bytes', v: call }, 22 | ); 23 | } 24 | function create2(address, code, salt) 25 | { 26 | return web3.utils.toChecksumAddress(web3.utils.soliditySha3( 27 | { t: 'bytes1', v: '0xff' }, 28 | { t: 'address', v: address }, 29 | { t: 'bytes32', v: salt }, 30 | { t: 'bytes32', v: web3.utils.keccak256(code) }, 31 | ).slice(26)); 32 | } 33 | function predict(address, code, salt, call="") 34 | { 35 | return create2(address, code, prepareSalt(salt, call)); 36 | } 37 | 38 | module.exports = { 39 | predict, 40 | } 41 | -------------------------------------------------------------------------------- /truffle.js: -------------------------------------------------------------------------------- 1 | module.exports = 2 | { 3 | plugins: [ "solidity-coverage" ], 4 | networks: 5 | { 6 | development: 7 | { 8 | host: "localhost", 9 | port: 8545, 10 | network_id: "*", // Match any network id, 11 | gasPrice: 22000000000, //22Gwei 12 | }, 13 | coverage: 14 | { 15 | host: "localhost", 16 | port: 8555, // <-- If you change this, also set the port option in .solcover.js. 17 | network_id: "*", 18 | gas: 0xFFFFFFFFFFF, // <-- Use this high gas value 19 | gasPrice: 0x01 // <-- Use this low gas price 20 | } 21 | }, 22 | compilers: { 23 | solc: { 24 | version: "0.6.12", 25 | settings: { 26 | optimizer: { 27 | enabled: true, 28 | runs: 200 29 | } 30 | } 31 | } 32 | }, 33 | mocha: 34 | { 35 | enableTimeouts: false 36 | } 37 | }; 38 | --------------------------------------------------------------------------------