├── .gitignore ├── .solcover.js ├── README.md ├── contracts ├── Funding.sol ├── Migrations.sol └── Ownable.sol ├── migrations ├── 1_initial_migration.js └── 2_funding.js ├── package-lock.json ├── package.json ├── test ├── FundingTest.js ├── FundingTest.sol └── utils.js ├── truffle-config.js └── truffle.js /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | node_modules 3 | coverage 4 | coverage.json 5 | -------------------------------------------------------------------------------- /.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | copyPackages: ["openzeppelin-solidity"] 3 | }; 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Test driven introduction to Solidity 2 | 3 | This repository contains the full source code of test suits and the smart contact from the article: [Ethereum: Test driven introduction to Solidity](https://michalzalecki.com/ethereum-test-driven-introduction-to-solidity/) 4 | 5 | ## Usage 6 | 7 | npm run test # run tests 8 | npm run test:coverage # check tests coverage 9 | -------------------------------------------------------------------------------- /contracts/Funding.sol: -------------------------------------------------------------------------------- 1 | // contracts/Funding.sol 2 | pragma solidity 0.4.24; 3 | 4 | import "openzeppelin-solidity/contracts/ownership/Ownable.sol"; 5 | import "openzeppelin-solidity/contracts/math/SafeMath.sol"; 6 | 7 | contract Funding is Ownable { 8 | using SafeMath for uint; 9 | 10 | uint public raised; 11 | uint public goal; 12 | uint public finishesAt; 13 | mapping(address => uint) public balances; 14 | 15 | modifier onlyNotFinished() { 16 | require(!isFinished()); 17 | _; 18 | } 19 | 20 | modifier onlyFinished() { 21 | require(isFinished()); 22 | _; 23 | } 24 | 25 | modifier onlyNotFunded() { 26 | require(!isFunded()); 27 | _; 28 | } 29 | 30 | modifier onlyFunded() { 31 | require(isFunded()); 32 | _; 33 | } 34 | 35 | function () public payable {} 36 | 37 | constructor(uint _duration, uint _goal) public { 38 | finishesAt = now + _duration; 39 | goal = _goal; 40 | } 41 | 42 | function isFinished() public view returns (bool) { 43 | return finishesAt <= now; 44 | } 45 | 46 | function isFunded() public view returns (bool) { 47 | return raised >= goal; 48 | } 49 | 50 | function donate() public onlyNotFinished payable { 51 | balances[msg.sender] = balances[msg.sender].add(msg.value); 52 | raised = raised.add(msg.value); 53 | } 54 | 55 | function withdraw() public onlyOwner onlyFunded { 56 | owner.transfer(address(this).balance); 57 | } 58 | 59 | function refund() public onlyFinished onlyNotFunded { 60 | uint amount = balances[msg.sender]; 61 | require(amount > 0); 62 | balances[msg.sender] = 0; 63 | msg.sender.transfer(amount); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /contracts/Migrations.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.24; 2 | 3 | contract Migrations { 4 | address public owner; 5 | uint public last_completed_migration; 6 | 7 | modifier restricted() { 8 | if (msg.sender == owner) _; 9 | } 10 | 11 | constructor() public { 12 | owner = msg.sender; 13 | } 14 | 15 | function setCompleted(uint completed) public restricted { 16 | last_completed_migration = completed; 17 | } 18 | 19 | function upgrade(address new_address) public restricted { 20 | Migrations upgraded = Migrations(new_address); 21 | upgraded.setCompleted(last_completed_migration); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /contracts/Ownable.sol: -------------------------------------------------------------------------------- 1 | // contracts/Ownable.sol 2 | pragma solidity 0.4.24; 3 | 4 | contract Ownable { 5 | address public owner; 6 | 7 | modifier onlyOwner() { 8 | require(owner == msg.sender); 9 | _; 10 | } 11 | 12 | constructor() public { 13 | owner = msg.sender; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /migrations/1_initial_migration.js: -------------------------------------------------------------------------------- 1 | var Migrations = artifacts.require("./Migrations.sol"); 2 | 3 | module.exports = function(deployer) { 4 | deployer.deploy(Migrations); 5 | }; 6 | -------------------------------------------------------------------------------- /migrations/2_funding.js: -------------------------------------------------------------------------------- 1 | // migrations/2_funding.js 2 | const Funding = artifacts.require("./Funding.sol"); 3 | 4 | const FINNEY = 10 ** 15; 5 | const DAY = 3600 * 12; 6 | 7 | module.exports = function(deployer) { 8 | deployer.deploy(Funding, DAY, 100 * FINNEY); 9 | }; 10 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "requires": true, 3 | "lockfileVersion": 1, 4 | "dependencies": { 5 | "abbrev": { 6 | "version": "1.0.9", 7 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", 8 | "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", 9 | "dev": true 10 | }, 11 | "align-text": { 12 | "version": "0.1.4", 13 | "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", 14 | "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", 15 | "dev": true, 16 | "requires": { 17 | "kind-of": "^3.0.2", 18 | "longest": "^1.0.1", 19 | "repeat-string": "^1.5.2" 20 | } 21 | }, 22 | "amdefine": { 23 | "version": "1.0.1", 24 | "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", 25 | "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", 26 | "dev": true 27 | }, 28 | "ansi-regex": { 29 | "version": "2.1.1", 30 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 31 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" 32 | }, 33 | "argparse": { 34 | "version": "1.0.10", 35 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 36 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 37 | "dev": true, 38 | "requires": { 39 | "sprintf-js": "~1.0.2" 40 | } 41 | }, 42 | "async": { 43 | "version": "1.5.2", 44 | "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", 45 | "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", 46 | "dev": true 47 | }, 48 | "balanced-match": { 49 | "version": "1.0.0", 50 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 51 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 52 | }, 53 | "bignumber.js": { 54 | "version": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", 55 | "from": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", 56 | "dev": true 57 | }, 58 | "brace-expansion": { 59 | "version": "1.1.11", 60 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 61 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 62 | "requires": { 63 | "balanced-match": "^1.0.0", 64 | "concat-map": "0.0.1" 65 | } 66 | }, 67 | "browser-stdout": { 68 | "version": "1.3.0", 69 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", 70 | "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=" 71 | }, 72 | "browserify-sha3": { 73 | "version": "0.0.1", 74 | "resolved": "https://registry.npmjs.org/browserify-sha3/-/browserify-sha3-0.0.1.tgz", 75 | "integrity": "sha1-P/NKMAbvFcD7NWflQbkaI0ASPRE=", 76 | "dev": true, 77 | "requires": { 78 | "js-sha3": "^0.3.1" 79 | } 80 | }, 81 | "buffer-from": { 82 | "version": "1.1.1", 83 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 84 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", 85 | "dev": true 86 | }, 87 | "builtin-modules": { 88 | "version": "1.1.1", 89 | "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", 90 | "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" 91 | }, 92 | "camelcase": { 93 | "version": "3.0.0", 94 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", 95 | "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" 96 | }, 97 | "center-align": { 98 | "version": "0.1.3", 99 | "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", 100 | "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", 101 | "dev": true, 102 | "optional": true, 103 | "requires": { 104 | "align-text": "^0.1.3", 105 | "lazy-cache": "^1.0.3" 106 | } 107 | }, 108 | "cliui": { 109 | "version": "3.2.0", 110 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", 111 | "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", 112 | "requires": { 113 | "string-width": "^1.0.1", 114 | "strip-ansi": "^3.0.1", 115 | "wrap-ansi": "^2.0.0" 116 | } 117 | }, 118 | "code-point-at": { 119 | "version": "1.1.0", 120 | "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", 121 | "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" 122 | }, 123 | "commander": { 124 | "version": "2.11.0", 125 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", 126 | "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==" 127 | }, 128 | "concat-map": { 129 | "version": "0.0.1", 130 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 131 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 132 | }, 133 | "crypto-js": { 134 | "version": "3.1.8", 135 | "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.8.tgz", 136 | "integrity": "sha1-cV8HC/YBTyrpkqmLOSkli3E/CNU=", 137 | "dev": true 138 | }, 139 | "death": { 140 | "version": "1.1.0", 141 | "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", 142 | "integrity": "sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg=", 143 | "dev": true 144 | }, 145 | "debug": { 146 | "version": "3.1.0", 147 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 148 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 149 | "requires": { 150 | "ms": "2.0.0" 151 | } 152 | }, 153 | "decamelize": { 154 | "version": "1.2.0", 155 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 156 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" 157 | }, 158 | "deep-is": { 159 | "version": "0.1.3", 160 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 161 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 162 | "dev": true 163 | }, 164 | "diff": { 165 | "version": "3.3.1", 166 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", 167 | "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==" 168 | }, 169 | "error-ex": { 170 | "version": "1.3.2", 171 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", 172 | "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", 173 | "requires": { 174 | "is-arrayish": "^0.2.1" 175 | } 176 | }, 177 | "escape-string-regexp": { 178 | "version": "1.0.5", 179 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 180 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" 181 | }, 182 | "escodegen": { 183 | "version": "1.8.1", 184 | "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", 185 | "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", 186 | "dev": true, 187 | "requires": { 188 | "esprima": "^2.7.1", 189 | "estraverse": "^1.9.1", 190 | "esutils": "^2.0.2", 191 | "optionator": "^0.8.1", 192 | "source-map": "~0.2.0" 193 | }, 194 | "dependencies": { 195 | "source-map": { 196 | "version": "0.2.0", 197 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", 198 | "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", 199 | "dev": true, 200 | "optional": true, 201 | "requires": { 202 | "amdefine": ">=0.0.4" 203 | } 204 | } 205 | } 206 | }, 207 | "esprima": { 208 | "version": "2.7.3", 209 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", 210 | "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", 211 | "dev": true 212 | }, 213 | "estraverse": { 214 | "version": "1.9.3", 215 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", 216 | "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", 217 | "dev": true 218 | }, 219 | "esutils": { 220 | "version": "2.0.2", 221 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", 222 | "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", 223 | "dev": true 224 | }, 225 | "ethereumjs-testrpc-sc": { 226 | "version": "6.1.6", 227 | "resolved": "https://registry.npmjs.org/ethereumjs-testrpc-sc/-/ethereumjs-testrpc-sc-6.1.6.tgz", 228 | "integrity": "sha512-iv2qiGBFgk9mn5Nq2enX8dG5WQ7Lk+FCqpnxfPfH4Ns8KLPwttmNOy264nh3SXDJJvcQwz/XnlLteDQVILotbg==", 229 | "dev": true, 230 | "requires": { 231 | "source-map-support": "^0.5.3" 232 | } 233 | }, 234 | "fast-levenshtein": { 235 | "version": "2.0.6", 236 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 237 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 238 | "dev": true 239 | }, 240 | "find-up": { 241 | "version": "1.1.2", 242 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", 243 | "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", 244 | "requires": { 245 | "path-exists": "^2.0.0", 246 | "pinkie-promise": "^2.0.0" 247 | } 248 | }, 249 | "fs-extra": { 250 | "version": "0.30.0", 251 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", 252 | "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", 253 | "requires": { 254 | "graceful-fs": "^4.1.2", 255 | "jsonfile": "^2.1.0", 256 | "klaw": "^1.0.0", 257 | "path-is-absolute": "^1.0.0", 258 | "rimraf": "^2.2.8" 259 | } 260 | }, 261 | "fs.realpath": { 262 | "version": "1.0.0", 263 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 264 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 265 | }, 266 | "get-caller-file": { 267 | "version": "1.0.3", 268 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", 269 | "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" 270 | }, 271 | "glob": { 272 | "version": "7.1.2", 273 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 274 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 275 | "requires": { 276 | "fs.realpath": "^1.0.0", 277 | "inflight": "^1.0.4", 278 | "inherits": "2", 279 | "minimatch": "^3.0.4", 280 | "once": "^1.3.0", 281 | "path-is-absolute": "^1.0.0" 282 | } 283 | }, 284 | "graceful-fs": { 285 | "version": "4.1.11", 286 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", 287 | "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" 288 | }, 289 | "growl": { 290 | "version": "1.10.3", 291 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", 292 | "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==" 293 | }, 294 | "handlebars": { 295 | "version": "4.0.11", 296 | "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz", 297 | "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", 298 | "dev": true, 299 | "requires": { 300 | "async": "^1.4.0", 301 | "optimist": "^0.6.1", 302 | "source-map": "^0.4.4", 303 | "uglify-js": "^2.6" 304 | }, 305 | "dependencies": { 306 | "source-map": { 307 | "version": "0.4.4", 308 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", 309 | "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", 310 | "dev": true, 311 | "requires": { 312 | "amdefine": ">=0.0.4" 313 | } 314 | } 315 | } 316 | }, 317 | "has-flag": { 318 | "version": "2.0.0", 319 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", 320 | "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" 321 | }, 322 | "he": { 323 | "version": "1.1.1", 324 | "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", 325 | "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=" 326 | }, 327 | "hosted-git-info": { 328 | "version": "2.7.1", 329 | "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", 330 | "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==" 331 | }, 332 | "inflight": { 333 | "version": "1.0.6", 334 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 335 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 336 | "requires": { 337 | "once": "^1.3.0", 338 | "wrappy": "1" 339 | } 340 | }, 341 | "inherits": { 342 | "version": "2.0.3", 343 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 344 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 345 | }, 346 | "interpret": { 347 | "version": "1.1.0", 348 | "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", 349 | "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", 350 | "dev": true 351 | }, 352 | "invert-kv": { 353 | "version": "1.0.0", 354 | "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", 355 | "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" 356 | }, 357 | "is-arrayish": { 358 | "version": "0.2.1", 359 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", 360 | "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" 361 | }, 362 | "is-buffer": { 363 | "version": "1.1.6", 364 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", 365 | "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", 366 | "dev": true 367 | }, 368 | "is-builtin-module": { 369 | "version": "1.0.0", 370 | "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", 371 | "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", 372 | "requires": { 373 | "builtin-modules": "^1.0.0" 374 | } 375 | }, 376 | "is-fullwidth-code-point": { 377 | "version": "1.0.0", 378 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", 379 | "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", 380 | "requires": { 381 | "number-is-nan": "^1.0.0" 382 | } 383 | }, 384 | "is-utf8": { 385 | "version": "0.2.1", 386 | "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", 387 | "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" 388 | }, 389 | "isexe": { 390 | "version": "2.0.0", 391 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 392 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 393 | "dev": true 394 | }, 395 | "istanbul": { 396 | "version": "0.4.5", 397 | "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz", 398 | "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", 399 | "dev": true, 400 | "requires": { 401 | "abbrev": "1.0.x", 402 | "async": "1.x", 403 | "escodegen": "1.8.x", 404 | "esprima": "2.7.x", 405 | "glob": "^5.0.15", 406 | "handlebars": "^4.0.1", 407 | "js-yaml": "3.x", 408 | "mkdirp": "0.5.x", 409 | "nopt": "3.x", 410 | "once": "1.x", 411 | "resolve": "1.1.x", 412 | "supports-color": "^3.1.0", 413 | "which": "^1.1.1", 414 | "wordwrap": "^1.0.0" 415 | }, 416 | "dependencies": { 417 | "glob": { 418 | "version": "5.0.15", 419 | "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", 420 | "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", 421 | "dev": true, 422 | "requires": { 423 | "inflight": "^1.0.4", 424 | "inherits": "2", 425 | "minimatch": "2 || 3", 426 | "once": "^1.3.0", 427 | "path-is-absolute": "^1.0.0" 428 | } 429 | }, 430 | "has-flag": { 431 | "version": "1.0.0", 432 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", 433 | "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", 434 | "dev": true 435 | }, 436 | "supports-color": { 437 | "version": "3.2.3", 438 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", 439 | "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", 440 | "dev": true, 441 | "requires": { 442 | "has-flag": "^1.0.0" 443 | } 444 | } 445 | } 446 | }, 447 | "js-sha3": { 448 | "version": "0.3.1", 449 | "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.3.1.tgz", 450 | "integrity": "sha1-hhIoAhQvCChQKg0d7h2V4lO7AkM=", 451 | "dev": true 452 | }, 453 | "js-yaml": { 454 | "version": "3.12.0", 455 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", 456 | "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", 457 | "dev": true, 458 | "requires": { 459 | "argparse": "^1.0.7", 460 | "esprima": "^4.0.0" 461 | }, 462 | "dependencies": { 463 | "esprima": { 464 | "version": "4.0.1", 465 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 466 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 467 | "dev": true 468 | } 469 | } 470 | }, 471 | "jsonfile": { 472 | "version": "2.4.0", 473 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", 474 | "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", 475 | "requires": { 476 | "graceful-fs": "^4.1.6" 477 | } 478 | }, 479 | "keccakjs": { 480 | "version": "0.2.1", 481 | "resolved": "https://registry.npmjs.org/keccakjs/-/keccakjs-0.2.1.tgz", 482 | "integrity": "sha1-HWM6+QfvMFu/ny+mFtVsRFYd+k0=", 483 | "dev": true, 484 | "requires": { 485 | "browserify-sha3": "^0.0.1", 486 | "sha3": "^1.1.0" 487 | } 488 | }, 489 | "kind-of": { 490 | "version": "3.2.2", 491 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", 492 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", 493 | "dev": true, 494 | "requires": { 495 | "is-buffer": "^1.1.5" 496 | } 497 | }, 498 | "klaw": { 499 | "version": "1.3.1", 500 | "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", 501 | "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", 502 | "requires": { 503 | "graceful-fs": "^4.1.9" 504 | } 505 | }, 506 | "lazy-cache": { 507 | "version": "1.0.4", 508 | "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", 509 | "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", 510 | "dev": true, 511 | "optional": true 512 | }, 513 | "lcid": { 514 | "version": "1.0.0", 515 | "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", 516 | "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", 517 | "requires": { 518 | "invert-kv": "^1.0.0" 519 | } 520 | }, 521 | "levn": { 522 | "version": "0.3.0", 523 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 524 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 525 | "dev": true, 526 | "requires": { 527 | "prelude-ls": "~1.1.2", 528 | "type-check": "~0.3.2" 529 | } 530 | }, 531 | "load-json-file": { 532 | "version": "1.1.0", 533 | "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", 534 | "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", 535 | "requires": { 536 | "graceful-fs": "^4.1.2", 537 | "parse-json": "^2.2.0", 538 | "pify": "^2.0.0", 539 | "pinkie-promise": "^2.0.0", 540 | "strip-bom": "^2.0.0" 541 | } 542 | }, 543 | "lodash.assign": { 544 | "version": "4.2.0", 545 | "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", 546 | "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=" 547 | }, 548 | "longest": { 549 | "version": "1.0.1", 550 | "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", 551 | "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", 552 | "dev": true 553 | }, 554 | "memorystream": { 555 | "version": "0.3.1", 556 | "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", 557 | "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=" 558 | }, 559 | "minimatch": { 560 | "version": "3.0.4", 561 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 562 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 563 | "requires": { 564 | "brace-expansion": "^1.1.7" 565 | } 566 | }, 567 | "minimist": { 568 | "version": "0.0.8", 569 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 570 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" 571 | }, 572 | "mkdirp": { 573 | "version": "0.5.1", 574 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 575 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 576 | "requires": { 577 | "minimist": "0.0.8" 578 | } 579 | }, 580 | "mocha": { 581 | "version": "4.1.0", 582 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", 583 | "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", 584 | "requires": { 585 | "browser-stdout": "1.3.0", 586 | "commander": "2.11.0", 587 | "debug": "3.1.0", 588 | "diff": "3.3.1", 589 | "escape-string-regexp": "1.0.5", 590 | "glob": "7.1.2", 591 | "growl": "1.10.3", 592 | "he": "1.1.1", 593 | "mkdirp": "0.5.1", 594 | "supports-color": "4.4.0" 595 | } 596 | }, 597 | "ms": { 598 | "version": "2.0.0", 599 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 600 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 601 | }, 602 | "nan": { 603 | "version": "2.10.0", 604 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", 605 | "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", 606 | "dev": true 607 | }, 608 | "nopt": { 609 | "version": "3.0.6", 610 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", 611 | "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", 612 | "dev": true, 613 | "requires": { 614 | "abbrev": "1" 615 | } 616 | }, 617 | "normalize-package-data": { 618 | "version": "2.4.0", 619 | "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", 620 | "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", 621 | "requires": { 622 | "hosted-git-info": "^2.1.4", 623 | "is-builtin-module": "^1.0.0", 624 | "semver": "2 || 3 || 4 || 5", 625 | "validate-npm-package-license": "^3.0.1" 626 | } 627 | }, 628 | "number-is-nan": { 629 | "version": "1.0.1", 630 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", 631 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" 632 | }, 633 | "once": { 634 | "version": "1.4.0", 635 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 636 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 637 | "requires": { 638 | "wrappy": "1" 639 | } 640 | }, 641 | "openzeppelin-solidity": { 642 | "version": "1.12.0", 643 | "resolved": "https://registry.npmjs.org/openzeppelin-solidity/-/openzeppelin-solidity-1.12.0.tgz", 644 | "integrity": "sha512-WlorzMXIIurugiSdw121RVD5qA3EfSI7GybTn+/Du0mPNgairjt29NpVTAaH8eLjAeAwlw46y7uQKy0NYem/gA==" 645 | }, 646 | "optimist": { 647 | "version": "0.6.1", 648 | "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", 649 | "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", 650 | "dev": true, 651 | "requires": { 652 | "minimist": "~0.0.1", 653 | "wordwrap": "~0.0.2" 654 | }, 655 | "dependencies": { 656 | "wordwrap": { 657 | "version": "0.0.3", 658 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", 659 | "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", 660 | "dev": true 661 | } 662 | } 663 | }, 664 | "optionator": { 665 | "version": "0.8.2", 666 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", 667 | "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", 668 | "dev": true, 669 | "requires": { 670 | "deep-is": "~0.1.3", 671 | "fast-levenshtein": "~2.0.4", 672 | "levn": "~0.3.0", 673 | "prelude-ls": "~1.1.2", 674 | "type-check": "~0.3.2", 675 | "wordwrap": "~1.0.0" 676 | } 677 | }, 678 | "original-require": { 679 | "version": "1.0.1", 680 | "resolved": "https://registry.npmjs.org/original-require/-/original-require-1.0.1.tgz", 681 | "integrity": "sha1-DxMEcVhM0zURxew4yNWSE/msXiA=" 682 | }, 683 | "os-locale": { 684 | "version": "1.4.0", 685 | "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", 686 | "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", 687 | "requires": { 688 | "lcid": "^1.0.0" 689 | } 690 | }, 691 | "parse-json": { 692 | "version": "2.2.0", 693 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", 694 | "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", 695 | "requires": { 696 | "error-ex": "^1.2.0" 697 | } 698 | }, 699 | "path-exists": { 700 | "version": "2.1.0", 701 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", 702 | "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", 703 | "requires": { 704 | "pinkie-promise": "^2.0.0" 705 | } 706 | }, 707 | "path-is-absolute": { 708 | "version": "1.0.1", 709 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 710 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 711 | }, 712 | "path-type": { 713 | "version": "1.1.0", 714 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", 715 | "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", 716 | "requires": { 717 | "graceful-fs": "^4.1.2", 718 | "pify": "^2.0.0", 719 | "pinkie-promise": "^2.0.0" 720 | } 721 | }, 722 | "pegjs": { 723 | "version": "0.10.0", 724 | "resolved": "https://registry.npmjs.org/pegjs/-/pegjs-0.10.0.tgz", 725 | "integrity": "sha1-z4uvrm7d/0tafvsYUmnqr0YQ3b0=", 726 | "dev": true 727 | }, 728 | "pify": { 729 | "version": "2.3.0", 730 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", 731 | "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" 732 | }, 733 | "pinkie": { 734 | "version": "2.0.4", 735 | "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", 736 | "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" 737 | }, 738 | "pinkie-promise": { 739 | "version": "2.0.1", 740 | "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", 741 | "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", 742 | "requires": { 743 | "pinkie": "^2.0.0" 744 | } 745 | }, 746 | "prelude-ls": { 747 | "version": "1.1.2", 748 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 749 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", 750 | "dev": true 751 | }, 752 | "read-pkg": { 753 | "version": "1.1.0", 754 | "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", 755 | "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", 756 | "requires": { 757 | "load-json-file": "^1.0.0", 758 | "normalize-package-data": "^2.3.2", 759 | "path-type": "^1.0.0" 760 | } 761 | }, 762 | "read-pkg-up": { 763 | "version": "1.0.1", 764 | "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", 765 | "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", 766 | "requires": { 767 | "find-up": "^1.0.0", 768 | "read-pkg": "^1.0.0" 769 | } 770 | }, 771 | "rechoir": { 772 | "version": "0.6.2", 773 | "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", 774 | "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", 775 | "dev": true, 776 | "requires": { 777 | "resolve": "^1.1.6" 778 | } 779 | }, 780 | "repeat-string": { 781 | "version": "1.6.1", 782 | "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", 783 | "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", 784 | "dev": true 785 | }, 786 | "req-cwd": { 787 | "version": "1.0.1", 788 | "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-1.0.1.tgz", 789 | "integrity": "sha1-DXOurpJm5penj3l2AZZ352rPD/8=", 790 | "dev": true, 791 | "requires": { 792 | "req-from": "^1.0.1" 793 | } 794 | }, 795 | "req-from": { 796 | "version": "1.0.1", 797 | "resolved": "https://registry.npmjs.org/req-from/-/req-from-1.0.1.tgz", 798 | "integrity": "sha1-v4HaUUeUfTLRO5R9wSpYrUWHNQ4=", 799 | "dev": true, 800 | "requires": { 801 | "resolve-from": "^2.0.0" 802 | } 803 | }, 804 | "require-directory": { 805 | "version": "2.1.1", 806 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 807 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" 808 | }, 809 | "require-from-string": { 810 | "version": "1.2.1", 811 | "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", 812 | "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=" 813 | }, 814 | "require-main-filename": { 815 | "version": "1.0.1", 816 | "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", 817 | "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" 818 | }, 819 | "resolve": { 820 | "version": "1.1.7", 821 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", 822 | "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", 823 | "dev": true 824 | }, 825 | "resolve-from": { 826 | "version": "2.0.0", 827 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", 828 | "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=", 829 | "dev": true 830 | }, 831 | "right-align": { 832 | "version": "0.1.3", 833 | "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", 834 | "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", 835 | "dev": true, 836 | "optional": true, 837 | "requires": { 838 | "align-text": "^0.1.1" 839 | } 840 | }, 841 | "rimraf": { 842 | "version": "2.6.2", 843 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", 844 | "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", 845 | "requires": { 846 | "glob": "^7.0.5" 847 | } 848 | }, 849 | "semver": { 850 | "version": "5.5.0", 851 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", 852 | "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" 853 | }, 854 | "set-blocking": { 855 | "version": "2.0.0", 856 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 857 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" 858 | }, 859 | "sha3": { 860 | "version": "1.2.2", 861 | "resolved": "https://registry.npmjs.org/sha3/-/sha3-1.2.2.tgz", 862 | "integrity": "sha1-pmxQmN5MJbyIM27ItIF9AFvKe6k=", 863 | "dev": true, 864 | "requires": { 865 | "nan": "2.10.0" 866 | } 867 | }, 868 | "shelljs": { 869 | "version": "0.7.8", 870 | "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", 871 | "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", 872 | "dev": true, 873 | "requires": { 874 | "glob": "^7.0.0", 875 | "interpret": "^1.0.0", 876 | "rechoir": "^0.6.2" 877 | } 878 | }, 879 | "sol-explore": { 880 | "version": "1.6.2", 881 | "resolved": "https://registry.npmjs.org/sol-explore/-/sol-explore-1.6.2.tgz", 882 | "integrity": "sha1-Q66MQZ/TrAVqBfip0fsQIs1B7MI=", 883 | "dev": true 884 | }, 885 | "solc": { 886 | "version": "0.4.24", 887 | "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.24.tgz", 888 | "integrity": "sha512-2xd7Cf1HeVwrIb6Bu1cwY2/TaLRodrppCq3l7rhLimFQgmxptXhTC3+/wesVLpB09F1A2kZgvbMOgH7wvhFnBQ==", 889 | "requires": { 890 | "fs-extra": "^0.30.0", 891 | "memorystream": "^0.3.1", 892 | "require-from-string": "^1.1.0", 893 | "semver": "^5.3.0", 894 | "yargs": "^4.7.1" 895 | } 896 | }, 897 | "solidity-coverage": { 898 | "version": "0.5.7", 899 | "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.5.7.tgz", 900 | "integrity": "sha512-2cVYJ3BHkcuQVzkb71DVbgVd7a+1ebuRCCAup/XXRySmuOo39/sk9vOVK8gMJ1Q8keRXAnpWcL5i8lvDc/GjsA==", 901 | "dev": true, 902 | "requires": { 903 | "death": "^1.1.0", 904 | "ethereumjs-testrpc-sc": "6.1.6", 905 | "istanbul": "^0.4.5", 906 | "keccakjs": "^0.2.1", 907 | "req-cwd": "^1.0.1", 908 | "shelljs": "^0.7.4", 909 | "sol-explore": "^1.6.2", 910 | "solidity-parser-sc": "0.4.11", 911 | "tree-kill": "^1.2.0", 912 | "web3": "^0.18.4" 913 | } 914 | }, 915 | "solidity-parser-sc": { 916 | "version": "0.4.11", 917 | "resolved": "https://registry.npmjs.org/solidity-parser-sc/-/solidity-parser-sc-0.4.11.tgz", 918 | "integrity": "sha512-1kV5iC7m3CtMDfmHaVNwz2saSGQVIuF16rIxU417Al38MVCWHMQQ5vT6cmLsNwDe60S74auobWij9vNawSeOyw==", 919 | "dev": true, 920 | "requires": { 921 | "mocha": "^4.1.0", 922 | "pegjs": "^0.10.0", 923 | "yargs": "^4.6.0" 924 | } 925 | }, 926 | "source-map": { 927 | "version": "0.6.1", 928 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 929 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 930 | "dev": true 931 | }, 932 | "source-map-support": { 933 | "version": "0.5.8", 934 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.8.tgz", 935 | "integrity": "sha512-WqAEWPdb78u25RfKzOF0swBpY0dKrNdjc4GvLwm7ScX/o9bj8Eh/YL8mcMhBHYDGl87UkkSXDOFnW4G7GhWhGg==", 936 | "dev": true, 937 | "requires": { 938 | "buffer-from": "^1.0.0", 939 | "source-map": "^0.6.0" 940 | } 941 | }, 942 | "spdx-correct": { 943 | "version": "3.0.0", 944 | "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", 945 | "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", 946 | "requires": { 947 | "spdx-expression-parse": "^3.0.0", 948 | "spdx-license-ids": "^3.0.0" 949 | } 950 | }, 951 | "spdx-exceptions": { 952 | "version": "2.1.0", 953 | "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", 954 | "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==" 955 | }, 956 | "spdx-expression-parse": { 957 | "version": "3.0.0", 958 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", 959 | "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", 960 | "requires": { 961 | "spdx-exceptions": "^2.1.0", 962 | "spdx-license-ids": "^3.0.0" 963 | } 964 | }, 965 | "spdx-license-ids": { 966 | "version": "3.0.0", 967 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", 968 | "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==" 969 | }, 970 | "sprintf-js": { 971 | "version": "1.0.3", 972 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 973 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 974 | "dev": true 975 | }, 976 | "string-width": { 977 | "version": "1.0.2", 978 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", 979 | "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", 980 | "requires": { 981 | "code-point-at": "^1.0.0", 982 | "is-fullwidth-code-point": "^1.0.0", 983 | "strip-ansi": "^3.0.0" 984 | } 985 | }, 986 | "strip-ansi": { 987 | "version": "3.0.1", 988 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 989 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 990 | "requires": { 991 | "ansi-regex": "^2.0.0" 992 | } 993 | }, 994 | "strip-bom": { 995 | "version": "2.0.0", 996 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", 997 | "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", 998 | "requires": { 999 | "is-utf8": "^0.2.0" 1000 | } 1001 | }, 1002 | "supports-color": { 1003 | "version": "4.4.0", 1004 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", 1005 | "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", 1006 | "requires": { 1007 | "has-flag": "^2.0.0" 1008 | } 1009 | }, 1010 | "tree-kill": { 1011 | "version": "1.2.0", 1012 | "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.0.tgz", 1013 | "integrity": "sha512-DlX6dR0lOIRDFxI0mjL9IYg6OTncLm/Zt+JiBhE5OlFcAR8yc9S7FFXU9so0oda47frdM/JFsk7UjNt9vscKcg==", 1014 | "dev": true 1015 | }, 1016 | "truffle": { 1017 | "version": "4.1.14", 1018 | "resolved": "https://registry.npmjs.org/truffle/-/truffle-4.1.14.tgz", 1019 | "integrity": "sha512-e7tTLvKP3bN9dE7MagfWyFjy4ZgoEGbeujECy1me1ENBzbj/aO/+45gs72qsL3+3IkCNNcWNOJjjrm8BYZZNNg==", 1020 | "requires": { 1021 | "mocha": "^4.1.0", 1022 | "original-require": "1.0.1", 1023 | "solc": "0.4.24" 1024 | } 1025 | }, 1026 | "type-check": { 1027 | "version": "0.3.2", 1028 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 1029 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 1030 | "dev": true, 1031 | "requires": { 1032 | "prelude-ls": "~1.1.2" 1033 | } 1034 | }, 1035 | "uglify-js": { 1036 | "version": "2.8.29", 1037 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", 1038 | "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", 1039 | "dev": true, 1040 | "optional": true, 1041 | "requires": { 1042 | "source-map": "~0.5.1", 1043 | "uglify-to-browserify": "~1.0.0", 1044 | "yargs": "~3.10.0" 1045 | }, 1046 | "dependencies": { 1047 | "camelcase": { 1048 | "version": "1.2.1", 1049 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", 1050 | "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", 1051 | "dev": true, 1052 | "optional": true 1053 | }, 1054 | "cliui": { 1055 | "version": "2.1.0", 1056 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", 1057 | "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", 1058 | "dev": true, 1059 | "optional": true, 1060 | "requires": { 1061 | "center-align": "^0.1.1", 1062 | "right-align": "^0.1.1", 1063 | "wordwrap": "0.0.2" 1064 | } 1065 | }, 1066 | "source-map": { 1067 | "version": "0.5.7", 1068 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", 1069 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", 1070 | "dev": true, 1071 | "optional": true 1072 | }, 1073 | "window-size": { 1074 | "version": "0.1.0", 1075 | "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", 1076 | "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", 1077 | "dev": true, 1078 | "optional": true 1079 | }, 1080 | "wordwrap": { 1081 | "version": "0.0.2", 1082 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", 1083 | "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", 1084 | "dev": true, 1085 | "optional": true 1086 | }, 1087 | "yargs": { 1088 | "version": "3.10.0", 1089 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", 1090 | "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", 1091 | "dev": true, 1092 | "optional": true, 1093 | "requires": { 1094 | "camelcase": "^1.0.2", 1095 | "cliui": "^2.1.0", 1096 | "decamelize": "^1.0.0", 1097 | "window-size": "0.1.0" 1098 | } 1099 | } 1100 | } 1101 | }, 1102 | "uglify-to-browserify": { 1103 | "version": "1.0.2", 1104 | "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", 1105 | "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", 1106 | "dev": true, 1107 | "optional": true 1108 | }, 1109 | "utf8": { 1110 | "version": "2.1.2", 1111 | "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.2.tgz", 1112 | "integrity": "sha1-H6DZJw6b6FDZsFAn9jUZv0ZFfZY=", 1113 | "dev": true 1114 | }, 1115 | "validate-npm-package-license": { 1116 | "version": "3.0.4", 1117 | "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", 1118 | "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", 1119 | "requires": { 1120 | "spdx-correct": "^3.0.0", 1121 | "spdx-expression-parse": "^3.0.0" 1122 | } 1123 | }, 1124 | "web3": { 1125 | "version": "0.18.4", 1126 | "resolved": "https://registry.npmjs.org/web3/-/web3-0.18.4.tgz", 1127 | "integrity": "sha1-gewXhBRUkfLqqJVbMcBgSeB8Xn0=", 1128 | "dev": true, 1129 | "requires": { 1130 | "bignumber.js": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", 1131 | "crypto-js": "^3.1.4", 1132 | "utf8": "^2.1.1", 1133 | "xhr2": "*", 1134 | "xmlhttprequest": "*" 1135 | } 1136 | }, 1137 | "which": { 1138 | "version": "1.3.1", 1139 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 1140 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 1141 | "dev": true, 1142 | "requires": { 1143 | "isexe": "^2.0.0" 1144 | } 1145 | }, 1146 | "which-module": { 1147 | "version": "1.0.0", 1148 | "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", 1149 | "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=" 1150 | }, 1151 | "window-size": { 1152 | "version": "0.2.0", 1153 | "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", 1154 | "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=" 1155 | }, 1156 | "wordwrap": { 1157 | "version": "1.0.0", 1158 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", 1159 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", 1160 | "dev": true 1161 | }, 1162 | "wrap-ansi": { 1163 | "version": "2.1.0", 1164 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", 1165 | "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", 1166 | "requires": { 1167 | "string-width": "^1.0.1", 1168 | "strip-ansi": "^3.0.1" 1169 | } 1170 | }, 1171 | "wrappy": { 1172 | "version": "1.0.2", 1173 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1174 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 1175 | }, 1176 | "xhr2": { 1177 | "version": "0.1.4", 1178 | "resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.1.4.tgz", 1179 | "integrity": "sha1-f4dliEdxbbUCYyOBL4GMras4el8=", 1180 | "dev": true 1181 | }, 1182 | "xmlhttprequest": { 1183 | "version": "1.8.0", 1184 | "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", 1185 | "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=", 1186 | "dev": true 1187 | }, 1188 | "y18n": { 1189 | "version": "3.2.1", 1190 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", 1191 | "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" 1192 | }, 1193 | "yargs": { 1194 | "version": "4.8.1", 1195 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", 1196 | "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", 1197 | "requires": { 1198 | "cliui": "^3.2.0", 1199 | "decamelize": "^1.1.1", 1200 | "get-caller-file": "^1.0.1", 1201 | "lodash.assign": "^4.0.3", 1202 | "os-locale": "^1.4.0", 1203 | "read-pkg-up": "^1.0.1", 1204 | "require-directory": "^2.1.1", 1205 | "require-main-filename": "^1.0.1", 1206 | "set-blocking": "^2.0.0", 1207 | "string-width": "^1.0.1", 1208 | "which-module": "^1.0.0", 1209 | "window-size": "^0.2.0", 1210 | "y18n": "^3.2.1", 1211 | "yargs-parser": "^2.4.1" 1212 | } 1213 | }, 1214 | "yargs-parser": { 1215 | "version": "2.4.1", 1216 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", 1217 | "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", 1218 | "requires": { 1219 | "camelcase": "^3.0.0", 1220 | "lodash.assign": "^4.0.6" 1221 | } 1222 | } 1223 | } 1224 | } 1225 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "openzeppelin-solidity": "1.12.0", 4 | "truffle": "^4.1.14" 5 | }, 6 | "devDependencies": { 7 | "solidity-coverage": "^0.5.7" 8 | }, 9 | "scripts": { 10 | "build": "truffle compile", 11 | "test": "truffle test", 12 | "test:coverage": "solidity-coverage" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/FundingTest.js: -------------------------------------------------------------------------------- 1 | // test/FundingTest.js 2 | const { increaseTime } = require("./utils"); 3 | const Funding = artifacts.require("Funding"); 4 | 5 | const FINNEY = 10**15; 6 | const DAY = 3600 * 24; 7 | 8 | contract("Funding", accounts => { 9 | const [firstAccount, secondAccount, thirdAccount] = accounts; 10 | let funding; 11 | 12 | beforeEach(async () => { 13 | funding = await Funding.new(DAY, 100 * FINNEY); 14 | }); 15 | 16 | it("sets an owner", async () => { 17 | assert.equal(await funding.owner.call(), firstAccount); 18 | }); 19 | 20 | it("accepts donations", async () => { 21 | await funding.donate({ from: firstAccount, value: 10 * FINNEY }); 22 | await funding.donate({ from: secondAccount, value: 20 * FINNEY }); 23 | assert.equal(await funding.raised.call(), 30 * FINNEY); 24 | }); 25 | 26 | it("keeps track of donator balance", async () => { 27 | await funding.donate({ from: firstAccount, value: 5 * FINNEY }); 28 | await funding.donate({ from: secondAccount, value: 15 * FINNEY }); 29 | await funding.donate({ from: secondAccount, value: 3 * FINNEY }); 30 | assert.equal(await funding.balances.call(firstAccount), 5 * FINNEY); 31 | assert.equal(await funding.balances.call(secondAccount), 18 * FINNEY); 32 | }); 33 | 34 | it("finishes fundraising when time is up", async () => { 35 | assert.equal(await funding.isFinished.call(), false); 36 | await increaseTime(DAY); 37 | assert.equal(await funding.isFinished.call(), true); 38 | }); 39 | 40 | it("does not allow for donations when time is up", async () => { 41 | await funding.donate({ from: firstAccount, value: 10 * FINNEY }); 42 | await increaseTime(DAY); 43 | try { 44 | await funding.donate({ from: firstAccount, value: 10 * FINNEY }); 45 | assert.fail(); 46 | } catch (err) { 47 | assert.ok(/revert/.test(err.message)); 48 | } 49 | }); 50 | 51 | it("allows an owner to withdraw funds when goal is reached", async () => { 52 | await funding.donate({ from: secondAccount, value: 30 * FINNEY }); 53 | await funding.donate({ from: thirdAccount, value: 70 * FINNEY }); 54 | const initBalance = web3.eth.getBalance(firstAccount); 55 | assert.equal(web3.eth.getBalance(funding.address), 100 * FINNEY); 56 | await funding.withdraw(); 57 | const finalBalance = web3.eth.getBalance(firstAccount); 58 | assert.ok(finalBalance.greaterThan(initBalance)); 59 | }); 60 | 61 | it("does not allow non-owners to withdraw funds", async () => { 62 | await funding.donate({ from: secondAccount, value: 100 * FINNEY }); 63 | try { 64 | await funding.withdraw({ from: secondAccount }); 65 | assert.fail(); 66 | } catch (err) { 67 | assert.ok(/revert/.test(err.message)); 68 | } 69 | }); 70 | 71 | it("allows to withdraw funds after time is up and goal is not reached", async () => { 72 | await funding.donate({ from: secondAccount, value: 50 * FINNEY }); 73 | const initBalance = web3.eth.getBalance(secondAccount); 74 | assert.equal((await funding.balances.call(secondAccount)), 50 * FINNEY); 75 | await increaseTime(DAY); 76 | await funding.refund({ from: secondAccount }); 77 | const finalBalance = web3.eth.getBalance(secondAccount); 78 | assert.ok(finalBalance.greaterThan(initBalance)); // hard to be exact due to the gas usage 79 | }); 80 | 81 | it("does not allow to withdraw funds after time in up and goal is reached", async () => { 82 | await funding.donate({ from: secondAccount, value: 100 * FINNEY }); 83 | assert.equal((await funding.balances.call(secondAccount)), 100 * FINNEY); 84 | await increaseTime(DAY); 85 | try { 86 | await funding.refund({ from: secondAccount }); 87 | assert.fail(); 88 | } catch (err) { 89 | assert.ok(/revert/.test(err.message)); 90 | } 91 | }); 92 | 93 | it("does not allow to withdraw funds before time in up and goal is not reached", async () => { 94 | await funding.donate({ from: secondAccount, value: 50 * FINNEY }); 95 | assert.equal((await funding.balances.call(secondAccount)), 50 * FINNEY); 96 | try { 97 | await funding.refund({ from: secondAccount }); 98 | assert.fail(); 99 | } catch (err) { 100 | assert.ok(/revert/.test(err.message)); 101 | } 102 | }); 103 | }); 104 | -------------------------------------------------------------------------------- /test/FundingTest.sol: -------------------------------------------------------------------------------- 1 | // test/FundingTest.sol 2 | pragma solidity 0.4.24; 3 | 4 | import "truffle/Assert.sol"; 5 | import "truffle/DeployedAddresses.sol"; 6 | import "../contracts/Funding.sol"; 7 | 8 | contract FundingTest { 9 | Funding funding; 10 | uint public initialBalance = 10 ether; 11 | 12 | function () public payable {} 13 | 14 | function beforeEach() public { 15 | funding = new Funding(1 days, 100 finney); 16 | } 17 | 18 | function testSettingAnOwnerDuringCreation() public { 19 | Assert.equal(funding.owner(), this, "An owner is different than a deployer"); 20 | } 21 | 22 | function testSettingAnOwnerOfDeployedContract() public { 23 | funding = Funding(DeployedAddresses.Funding()); 24 | Assert.equal(funding.owner(), msg.sender, "An owner is different than a deployer"); 25 | } 26 | 27 | function testAcceptingDonations() public { 28 | Assert.equal(funding.raised(), 0, "Initial raised amount is different than 0"); 29 | funding.donate.value(10 finney)(); 30 | funding.donate.value(20 finney)(); 31 | Assert.equal(funding.raised(), 30 finney, "Raised amount is different than sum of donations"); 32 | } 33 | 34 | function testTrackingDonorsBalance() public { 35 | funding.donate.value(5 finney)(); 36 | funding.donate.value(15 finney)(); 37 | Assert.equal(funding.balances(this), 20 finney, "Donator balance is different than sum of donations"); 38 | } 39 | 40 | function testDonatingAfterTimeIsUp() public { 41 | funding = new Funding(0, 100 finney); 42 | bool result = address(funding).call.value(10 finney)(bytes4(keccak256("donate()"))); 43 | Assert.equal(result, false, "Allows for donations when time is up"); 44 | } 45 | 46 | function testWithdrawalByAnOwner() public { 47 | uint initBalance = address(this).balance; 48 | funding.donate.value(50 finney)(); 49 | bool result = address(funding).call(bytes4(keccak256("withdraw()"))); 50 | Assert.equal(result, false, "Allows for withdrawal before reaching the goal"); 51 | funding.donate.value(50 finney)(); 52 | Assert.equal(address(this).balance, initBalance - 100 finney, "Balance before withdrawal doesn't correspond to the sum of donations"); 53 | result = address(funding).call(bytes4(keccak256("withdraw()"))); 54 | Assert.equal(result, true, "Doesn't allow for withdrawal after reaching the goal"); 55 | Assert.equal(address(this).balance, initBalance, "Balance after withdrawal doesn't correspond to the sum of donations"); 56 | } 57 | 58 | function testWithdrawalByNotAnOwner() public { 59 | funding = Funding(DeployedAddresses.Funding()); 60 | funding.donate.value(100 finney)(); 61 | bool result = address(funding).call(bytes4(keccak256("withdraw()"))); 62 | Assert.equal(result, false, "Allows for withdrawal by not an owner"); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /test/utils.js: -------------------------------------------------------------------------------- 1 | // source: https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/test/helpers/increaseTime.js 2 | module.exports.increaseTime = function increaseTime(duration) { 3 | const id = Date.now(); 4 | 5 | return new Promise((resolve, reject) => { 6 | web3.currentProvider.sendAsync( 7 | { 8 | jsonrpc: "2.0", 9 | method: "evm_increaseTime", 10 | params: [duration], 11 | id: id 12 | }, 13 | err1 => { 14 | if (err1) return reject(err1); 15 | 16 | web3.currentProvider.sendAsync( 17 | { 18 | jsonrpc: "2.0", 19 | method: "evm_mine", 20 | id: id + 1 21 | }, 22 | (err2, res) => { 23 | return err2 ? reject(err2) : resolve(res); 24 | } 25 | ); 26 | } 27 | ); 28 | }); 29 | }; 30 | -------------------------------------------------------------------------------- /truffle-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // See 3 | // to customize your Truffle configuration! 4 | }; 5 | -------------------------------------------------------------------------------- /truffle.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // See 3 | // to customize your Truffle configuration! 4 | }; 5 | --------------------------------------------------------------------------------