diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..adb20fe --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +*.sol linguist-language=Solidity +*.vy linguist-language=Python diff --git a/.github/workflow/test.yml b/.github/workflow/test.yml new file mode 100644 index 0000000..f8fca72 --- /dev/null +++ b/.github/workflow/test.yml @@ -0,0 +1,45 @@ +on: ["push", "pull_request"] + +name: main workflow + +env: + # ETHERSCAN_TOKEN: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # WEB3_INFURA_PROJECT_ID: + + # increasing available memory for node reduces issues with ganache crashing + # https://nodejs.org/api/cli.html#cli_max_old_space_size_size_in_megabytes + NODE_OPTIONS: --max_old_space_size=4096 + +jobs: + + tests: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Cache Compiler Installations + uses: actions/cache@v2 + with: + path: | + ~/.solcx + ~/.vvm + key: compiler-cache + + - name: Setup Node.js + uses: actions/setup-node@v1 + + - name: Install Ganache + run: npm install -g ganache-cli@6.10.2 + + - name: Setup Python 3.8 + uses: actions/setup-python@v2 + with: + python-version: 3.8 + + - name: Install Requirements + run: pip install -r requirements.txt + + - name: Run Tests + run: brownie test \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..898188a --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +__pycache__ +.env +.history +.hypothesis/ +build/ +reports/ diff --git a/Pipfile b/Pipfile new file mode 100644 index 0000000..2f434bf --- /dev/null +++ b/Pipfile @@ -0,0 +1,12 @@ +[[source]] +name = "pypi" +url = "https://pypi.org/simple" +verify_ssl = true + +[dev-packages] + +[packages] +eth-brownie = "*" + +[requires] +python_version = "3.10.8" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 0000000..2150e40 --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,1393 @@ +{ + "_meta": { + "hash": { + "sha256": "08e0c61d7ae1b9391707868a90c3146219f4ae39586ef1079b814abd629e6475" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.10.8" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "aiohttp": { + "hashes": [ + "sha256:02f9a2c72fc95d59b881cf38a4b2be9381b9527f9d328771e90f72ac76f31ad8", + "sha256:059a91e88f2c00fe40aed9031b3606c3f311414f86a90d696dd982e7aec48142", + "sha256:05a3c31c6d7cd08c149e50dc7aa2568317f5844acd745621983380597f027a18", + "sha256:08c78317e950e0762c2983f4dd58dc5e6c9ff75c8a0efeae299d363d439c8e34", + "sha256:09e28f572b21642128ef31f4e8372adb6888846f32fecb288c8b0457597ba61a", + "sha256:0d2c6d8c6872df4a6ec37d2ede71eff62395b9e337b4e18efd2177de883a5033", + "sha256:16c121ba0b1ec2b44b73e3a8a171c4f999b33929cd2397124a8c7fcfc8cd9e06", + "sha256:1d90043c1882067f1bd26196d5d2db9aa6d268def3293ed5fb317e13c9413ea4", + "sha256:1e56b9cafcd6531bab5d9b2e890bb4937f4165109fe98e2b98ef0dcfcb06ee9d", + "sha256:20acae4f268317bb975671e375493dbdbc67cddb5f6c71eebdb85b34444ac46b", + "sha256:21b30885a63c3f4ff5b77a5d6caf008b037cb521a5f33eab445dc566f6d092cc", + "sha256:21d69797eb951f155026651f7e9362877334508d39c2fc37bd04ff55b2007091", + "sha256:256deb4b29fe5e47893fa32e1de2d73c3afe7407738bd3c63829874661d4822d", + "sha256:25892c92bee6d9449ffac82c2fe257f3a6f297792cdb18ad784737d61e7a9a85", + "sha256:2ca9af5f8f5812d475c5259393f52d712f6d5f0d7fdad9acdb1107dd9e3cb7eb", + "sha256:2d252771fc85e0cf8da0b823157962d70639e63cb9b578b1dec9868dd1f4f937", + "sha256:2dea10edfa1a54098703cb7acaa665c07b4e7568472a47f4e64e6319d3821ccf", + "sha256:2df5f139233060578d8c2c975128fb231a89ca0a462b35d4b5fcf7c501ebdbe1", + "sha256:2feebbb6074cdbd1ac276dbd737b40e890a1361b3cc30b74ac2f5e24aab41f7b", + "sha256:309aa21c1d54b8ef0723181d430347d7452daaff93e8e2363db8e75c72c2fb2d", + "sha256:3828fb41b7203176b82fe5d699e0d845435f2374750a44b480ea6b930f6be269", + "sha256:398701865e7a9565d49189f6c90868efaca21be65c725fc87fc305906be915da", + "sha256:43046a319664a04b146f81b40e1545d4c8ac7b7dd04c47e40bf09f65f2437346", + "sha256:437399385f2abcd634865705bdc180c8314124b98299d54fe1d4c8990f2f9494", + "sha256:45d88b016c849d74ebc6f2b6e8bc17cabf26e7e40c0661ddd8fae4c00f015697", + "sha256:47841407cc89a4b80b0c52276f3cc8138bbbfba4b179ee3acbd7d77ae33f7ac4", + "sha256:4a4fbc769ea9b6bd97f4ad0b430a6807f92f0e5eb020f1e42ece59f3ecfc4585", + "sha256:4ab94426ddb1ecc6a0b601d832d5d9d421820989b8caa929114811369673235c", + "sha256:4b0f30372cef3fdc262f33d06e7b411cd59058ce9174ef159ad938c4a34a89da", + "sha256:4e3a23ec214e95c9fe85a58470b660efe6534b83e6cbe38b3ed52b053d7cb6ad", + "sha256:512bd5ab136b8dc0ffe3fdf2dfb0c4b4f49c8577f6cae55dca862cd37a4564e2", + "sha256:527b3b87b24844ea7865284aabfab08eb0faf599b385b03c2aa91fc6edd6e4b6", + "sha256:54d107c89a3ebcd13228278d68f1436d3f33f2dd2af5415e3feaeb1156e1a62c", + "sha256:5835f258ca9f7c455493a57ee707b76d2d9634d84d5d7f62e77be984ea80b849", + "sha256:598adde339d2cf7d67beaccda3f2ce7c57b3b412702f29c946708f69cf8222aa", + "sha256:599418aaaf88a6d02a8c515e656f6faf3d10618d3dd95866eb4436520096c84b", + "sha256:5bf651afd22d5f0c4be16cf39d0482ea494f5c88f03e75e5fef3a85177fecdeb", + "sha256:5c59fcd80b9049b49acd29bd3598cada4afc8d8d69bd4160cd613246912535d7", + "sha256:653acc3880459f82a65e27bd6526e47ddf19e643457d36a2250b85b41a564715", + "sha256:66bd5f950344fb2b3dbdd421aaa4e84f4411a1a13fca3aeb2bcbe667f80c9f76", + "sha256:6f3553510abdbec67c043ca85727396ceed1272eef029b050677046d3387be8d", + "sha256:7018ecc5fe97027214556afbc7c502fbd718d0740e87eb1217b17efd05b3d276", + "sha256:713d22cd9643ba9025d33c4af43943c7a1eb8547729228de18d3e02e278472b6", + "sha256:73a4131962e6d91109bca6536416aa067cf6c4efb871975df734f8d2fd821b37", + "sha256:75880ed07be39beff1881d81e4a907cafb802f306efd6d2d15f2b3c69935f6fb", + "sha256:75e14eac916f024305db517e00a9252714fce0abcb10ad327fb6dcdc0d060f1d", + "sha256:8135fa153a20d82ffb64f70a1b5c2738684afa197839b34cc3e3c72fa88d302c", + "sha256:84b14f36e85295fe69c6b9789b51a0903b774046d5f7df538176516c3e422446", + "sha256:86fc24e58ecb32aee09f864cb11bb91bc4c1086615001647dbfc4dc8c32f4008", + "sha256:87f44875f2804bc0511a69ce44a9595d5944837a62caecc8490bbdb0e18b1342", + "sha256:88c70ed9da9963d5496d38320160e8eb7e5f1886f9290475a881db12f351ab5d", + "sha256:88e5be56c231981428f4f506c68b6a46fa25c4123a2e86d156c58a8369d31ab7", + "sha256:89d2e02167fa95172c017732ed7725bc8523c598757f08d13c5acca308e1a061", + "sha256:8d6aaa4e7155afaf994d7924eb290abbe81a6905b303d8cb61310a2aba1c68ba", + "sha256:92a2964319d359f494f16011e23434f6f8ef0434acd3cf154a6b7bec511e2fb7", + "sha256:96372fc29471646b9b106ee918c8eeb4cca423fcbf9a34daa1b93767a88a2290", + "sha256:978b046ca728073070e9abc074b6299ebf3501e8dee5e26efacb13cec2b2dea0", + "sha256:9c7149272fb5834fc186328e2c1fa01dda3e1fa940ce18fded6d412e8f2cf76d", + "sha256:a0239da9fbafd9ff82fd67c16704a7d1bccf0d107a300e790587ad05547681c8", + "sha256:ad5383a67514e8e76906a06741febd9126fc7c7ff0f599d6fcce3e82b80d026f", + "sha256:ad61a9639792fd790523ba072c0555cd6be5a0baf03a49a5dd8cfcf20d56df48", + "sha256:b29bfd650ed8e148f9c515474a6ef0ba1090b7a8faeee26b74a8ff3b33617502", + "sha256:b97decbb3372d4b69e4d4c8117f44632551c692bb1361b356a02b97b69e18a62", + "sha256:ba71c9b4dcbb16212f334126cc3d8beb6af377f6703d9dc2d9fb3874fd667ee9", + "sha256:c37c5cce780349d4d51739ae682dec63573847a2a8dcb44381b174c3d9c8d403", + "sha256:c971bf3786b5fad82ce5ad570dc6ee420f5b12527157929e830f51c55dc8af77", + "sha256:d1fde0f44029e02d02d3993ad55ce93ead9bb9b15c6b7ccd580f90bd7e3de476", + "sha256:d24b8bb40d5c61ef2d9b6a8f4528c2f17f1c5d2d31fed62ec860f6006142e83e", + "sha256:d5ba88df9aa5e2f806650fcbeedbe4f6e8736e92fc0e73b0400538fd25a4dd96", + "sha256:d6f76310355e9fae637c3162936e9504b4767d5c52ca268331e2756e54fd4ca5", + "sha256:d737fc67b9a970f3234754974531dc9afeea11c70791dcb7db53b0cf81b79784", + "sha256:da22885266bbfb3f78218dc40205fed2671909fbd0720aedba39b4515c038091", + "sha256:da37dcfbf4b7f45d80ee386a5f81122501ec75672f475da34784196690762f4b", + "sha256:db19d60d846283ee275d0416e2a23493f4e6b6028825b51290ac05afc87a6f97", + "sha256:db4c979b0b3e0fa7e9e69ecd11b2b3174c6963cebadeecfb7ad24532ffcdd11a", + "sha256:e164e0a98e92d06da343d17d4e9c4da4654f4a4588a20d6c73548a29f176abe2", + "sha256:e168a7560b7c61342ae0412997b069753f27ac4862ec7867eff74f0fe4ea2ad9", + "sha256:e381581b37db1db7597b62a2e6b8b57c3deec95d93b6d6407c5b61ddc98aca6d", + "sha256:e65bc19919c910127c06759a63747ebe14f386cda573d95bcc62b427ca1afc73", + "sha256:e7b8813be97cab8cb52b1375f41f8e6804f6507fe4660152e8ca5c48f0436017", + "sha256:e8a78079d9a39ca9ca99a8b0ac2fdc0c4d25fc80c8a8a82e5c8211509c523363", + "sha256:ebf909ea0a3fc9596e40d55d8000702a85e27fd578ff41a5500f68f20fd32e6c", + "sha256:ec40170327d4a404b0d91855d41bfe1fe4b699222b2b93e3d833a27330a87a6d", + "sha256:f178d2aadf0166be4df834c4953da2d7eef24719e8aec9a65289483eeea9d618", + "sha256:f88df3a83cf9df566f171adba39d5bd52814ac0b94778d2448652fc77f9eb491", + "sha256:f973157ffeab5459eefe7b97a804987876dd0a55570b8fa56b4e1954bf11329b", + "sha256:ff25f48fc8e623d95eca0670b8cc1469a83783c924a602e0fbd47363bb54aaca" + ], + "markers": "python_version >= '3.6'", + "version": "==3.8.3" + }, + "aiosignal": { + "hashes": [ + "sha256:26e62109036cd181df6e6ad646f91f0dcfd05fe16d0cb924138ff2ab75d64e3a", + "sha256:78ed67db6c7b7ced4f98e495e572106d5c432a93e1ddd1bf475e1dc05f5b7df2" + ], + "markers": "python_version >= '3.6'", + "version": "==1.2.0" + }, + "asttokens": { + "hashes": [ + "sha256:0844691e88552595a6f4a4281a9f7f79b8dd45ca4ccea82e5e05b4bbdb76705c", + "sha256:9a54c114f02c7a9480d56550932546a3f1fe71d8a02f1bc7ccd0ee3ee35cf4d5" + ], + "version": "==2.0.5" + }, + "async-timeout": { + "hashes": [ + "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15", + "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c" + ], + "markers": "python_version >= '3.6'", + "version": "==4.0.2" + }, + "attrs": { + "hashes": [ + "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6", + "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c" + ], + "markers": "python_version >= '3.5'", + "version": "==22.1.0" + }, + "base58": { + "hashes": [ + "sha256:11a36f4d3ce51dfc1043f3218591ac4eb1ceb172919cebe05b52a5bcc8d245c2", + "sha256:c5d0cb3f5b6e81e8e35da5754388ddcc6d0d14b6c6a132cb93d69ed580a7278c" + ], + "markers": "python_version >= '3.5'", + "version": "==2.1.1" + }, + "bitarray": { + "hashes": [ + "sha256:035d3e5ab3c1afa2cd88bbc33af595b4875a24b0d037dfef907b41bc4b0dbe2b", + "sha256:0399886ca8ead7d0f16f94545bda800467d6d9c63fbd4866ee7ede7981166ba8", + "sha256:049e8f017b5b6d1763ababa156ca5cbdea8a01e20a1e80525b0fbe9fb839d695", + "sha256:076a72531bcca99114036c3714bac8124f5529b60fb6a6986067c6f345238c76", + "sha256:0b756e5c771cdceb17622b6a0678fa78364e329d875de73a4f26bbacab8915a8", + "sha256:11996c4da9c1ca9f97143e939af75c5b24ad0fdc2fa13aeb0007ebfa3c602caf", + "sha256:119d503edf09bef37f2d0dc3b4a23c36c3c1e88e17701ab71388eb4780c046c7", + "sha256:12c96dedd6e4584fecc2bf5fbffe1c635bd516eee7ade7b839c35aeba84336b4", + "sha256:1479f533eaff4080078b6e5d06b467868bd6edd73bb6651a295bf662d40afa62", + "sha256:15d2a1c060a11fc5508715fef6177937614f9354dd3afe6a00e261775f8b0e8f", + "sha256:1d0a2d896bcbcb5f32f60571ebd48349ec322dee5e137b342483108c5cbd0f03", + "sha256:24331bd2f52cd5410e48c132f486ed02a4ca3b96133fb26e3a8f50a57c354be6", + "sha256:2cfe1661b614314d67e6884e5e19e36957ff6faea5fcea7f25840dff95288248", + "sha256:346d2c5452cc024c41d267ba99e48d38783c1706c50c4632a4484cc57b152d0e", + "sha256:36802129a3115023700c07725d981c74e23b0914551898f788e5a41aed2d63bf", + "sha256:3f238127789c993de937178c3ff836d0fad4f2da08af9f579668873ac1332a42", + "sha256:42a071c9db755f267e5d3b9909ea8c22fb071d27860dd940facfacffbde79de8", + "sha256:4d42fee0add2114e572b0cd6edefc4c52207874f58b70043f82faa8bb7141620", + "sha256:4ffc076a0e22cda949ccd062f37ecc3dc53856c6e8bdfe07e1e81c411cf31621", + "sha256:5276c7247d350819d1dae385d8f78ebfb44ee90ff11a775f981d45cb366573e5", + "sha256:565c4334cb410f5eb62280dcfb3a52629e60ce430f31dfa4bbef92ec80de4890", + "sha256:56d3f16dd807b1c56732a244ce071c135ee973d3edc9929418c1b24c5439a0fd", + "sha256:5a0bb91363041b45523e5bcbc4153a5e1eb1ddb21e46fe1910340c0d095e1a8e", + "sha256:5bd315ac63b62de5eefbfa07969162ffbda8e535c3b7b3d41b565d2a88817b71", + "sha256:5f5df0377f3e7f1366e506c5295f08d3f8761e4a6381918931fc1d9594aa435e", + "sha256:6071d12043300e50a4b7ba9caeeca92aac567bb4ac4a227709e3c77a3d788587", + "sha256:67c5822f4bb6a419bc2f2dba9fa07b5646f0cda930bafa9e1130af6822e4bdf3", + "sha256:6c3d0a4a6061adc3d3128e1e1146940d17df8cbfe3d77cb66a1df69ddcdf27d5", + "sha256:6c46c2ba24a517f391c3ab9e7a214185f95146d0b664b4b0463ab31e5387669f", + "sha256:6d8ba8065d1b60da24d94078249cbf24a02d869d7dc9eba12db1fb513a375c79", + "sha256:6fa63a86aad0f45a27c7c5a27cd9b787fe9b1aed431f97f49ee8b834fa0780a0", + "sha256:7126563c86f6b60d87414124f035ff0d29de02ad9e46ea085de2c772b0be1331", + "sha256:71cc3d1da4f682f27728745f21ed3447ee8f6a0019932126c422dd91278eb414", + "sha256:742d43cbbc7267caae6379e2156a1fd8532332920a3d919b68c2982d439a98ba", + "sha256:763cac57692d07aa950b92c20f55ef66801955b71b4a1f4f48d5422d748c6dda", + "sha256:76c4e3261d6370383b02018cb964b5d9260e3c62dea31949910e9cc3a1c802d2", + "sha256:7ae3b8b48167579066a17c5ba1631d089f931f4eae8b4359ad123807d5e75c51", + "sha256:7f369872d551708d608e50a9ab8748d3d4f32a697dc5c2c37ff16cb8d7060210", + "sha256:874a222ece2100b3a3a8f08c57da3267a4e2219d26474a46937552992fcec771", + "sha256:878f16daa9c2062e4d29c1928b6f3eb50911726ad6d2006918a29ca6b38b5080", + "sha256:8c811e59c86ce0a8515daf47db9c2484fd42e51bdb44581d7bcc9caad6c9a7a1", + "sha256:97609495479c5214c7b57173c17206ebb056507a8d26eebc17942d62f8f25944", + "sha256:985a937218aa3d1ac7013174bfcbb1cb2f3157e17c6e349e83386f33459be1c0", + "sha256:a239313e75da37d1f6548d666d4dd8554c4a92dabed15741612855d186e86e72", + "sha256:b080eb25811db46306dfce58b4760df32f40bcf5551ebba3b7c8d3ec90d9b988", + "sha256:b0cfca1b5a57b540f4761b57de485196218733153c430d58f9e048e325c98b47", + "sha256:b0e4a6f5360e5f6c3a2b250c9e9cd539a9aabf0465dbedbaf364203e74ff101b", + "sha256:b849a6cdd46608e7cc108c75e1265304e79488480a822bae7471e628f971a6f0", + "sha256:bfda0af4072df6e932ec510b72c461e1ec0ad0820a76df588cdfebf5a07f5b5d", + "sha256:c19e900b6f9df13c7f406f827c5643f83c0839a58d007b35a4d7df827601f740", + "sha256:c24d4a1b5baa46920b801aa55c0e0a640c6e7683a73a941302e102e2bd11a830", + "sha256:c774328057a4b1fc48bee2dd5a60ee1e8e0ec112d29c4e6b9c550e1686b6db5c", + "sha256:d34673ebaf562347d004a465e16e2930c6568d196bb79d67fc6358f1213a1ac7", + "sha256:d523ffef1927cb686ad787b25b2e98a5bd53e3c40673c394f07bf9b281e69796", + "sha256:d53520b54206d8569b81eee56ccd9477af2f1b3ca355df9c48ee615a11e1a637", + "sha256:d697cc38cb6fa9bae3b994dd3ce68552ffe69c453a3b6fd6a4f94bb8a8bfd70b", + "sha256:d7bec01818c3a9d185f929cd36a82cc7acf13905920f7f595942105c5eef2300", + "sha256:e6a4a4bf6fbc42b2674023ca58a47c86ee55c023a8af85420f266e86b10e7065", + "sha256:e6bd32e492cdc740ec36b6725457685c9f2aa012dd8cbdae1643fed2b6821895", + "sha256:e76642232db8330589ed1ac1cec0e9c3814c708521c336a5c79d39a5d8d8c206", + "sha256:e7ba4c964a36fe198a8c4b5d08924709d4ed0337b65ae222b6503ed3442a46e8", + "sha256:ec18a0b97ea6b912ea57dc00a3f8f3ce515d774d00951d30e2ae243589d3d021", + "sha256:ecce266e24b21615a3ed234869be84bef492f6a34bb650d0e25dc3662c59bce4", + "sha256:f0302605b3bbc439083a400cf57d7464f1ac098c722309a03abaa7d97cd420b5", + "sha256:f253b9bdf5abd039741a9594a681453c973b09dcb7edac9105961838675b7c6b", + "sha256:f263b18fdb8bf42cd7cf9849d5863847d215024c68fe74cf33bcd82641d4376a", + "sha256:f37b5282b029d9f51454f8c580eb6a24e5dc140ef5866290afb20e607d2dce5f", + "sha256:f4849709571b1a53669798d23cc8430e677dcf0eea88610a0412e1911233899a", + "sha256:f853589426920d9bb3683f6b6cd11ce48d9d06a62c0b98ea4b82ebd8db3bddec", + "sha256:f9c492644f70f80f8266748c18309a0d73c22c47903f4b62f3fb772a15a8fd5f", + "sha256:fc635b27939969d53cac53e8b8f860ea69fc98cc9867cac17dd193f41dc2a57f", + "sha256:febaf00e498230ce2e75dac910056f0e3a91c8631b7ceb6385bb39d448960bc5" + ], + "version": "==2.6.0" + }, + "black": { + "hashes": [ + "sha256:14ff67aec0a47c424bc99b71005202045dc09270da44a27848d534600ac64fc7", + "sha256:197df8509263b0b8614e1df1756b1dd41be6738eed2ba9e9769f3880c2b9d7b6", + "sha256:1e464456d24e23d11fced2bc8c47ef66d471f845c7b7a42f3bd77bf3d1789650", + "sha256:2039230db3c6c639bd84efe3292ec7b06e9214a2992cd9beb293d639c6402edb", + "sha256:21199526696b8f09c3997e2b4db8d0b108d801a348414264d2eb8eb2532e540d", + "sha256:2644b5d63633702bc2c5f3754b1b475378fbbfb481f62319388235d0cd104c2d", + "sha256:432247333090c8c5366e69627ccb363bc58514ae3e63f7fc75c54b1ea80fa7de", + "sha256:444ebfb4e441254e87bad00c661fe32df9969b2bf224373a448d8aca2132b395", + "sha256:5b9b29da4f564ba8787c119f37d174f2b69cdfdf9015b7d8c5c16121ddc054ae", + "sha256:5cc42ca67989e9c3cf859e84c2bf014f6633db63d1cbdf8fdb666dcd9e77e3fa", + "sha256:5d8f74030e67087b219b032aa33a919fae8806d49c867846bfacde57f43972ef", + "sha256:72ef3925f30e12a184889aac03d77d031056860ccae8a1e519f6cbb742736383", + "sha256:819dc789f4498ecc91438a7de64427c73b45035e2e3680c92e18795a839ebb66", + "sha256:915ace4ff03fdfff953962fa672d44be269deb2eaf88499a0f8805221bc68c87", + "sha256:9311e99228ae10023300ecac05be5a296f60d2fd10fff31cf5c1fa4ca4b1988d", + "sha256:974308c58d057a651d182208a484ce80a26dac0caef2895836a92dd6ebd725e0", + "sha256:b8b49776299fece66bffaafe357d929ca9451450f5466e997a7285ab0fe28e3b", + "sha256:c957b2b4ea88587b46cf49d1dc17681c1e672864fd7af32fc1e9664d572b3458", + "sha256:e41a86c6c650bcecc6633ee3180d80a025db041a8e2398dcc059b3afa8382cd4", + "sha256:f513588da599943e0cde4e32cc9879e825d58720d6557062d1098c5ad80080e1", + "sha256:fba8a281e570adafb79f7755ac8721b6cf1bbf691186a287e990c7929c7692ff" + ], + "markers": "python_version >= '3.7'", + "version": "==22.10.0" + }, + "certifi": { + "hashes": [ + "sha256:0d9c601124e5a6ba9712dbc60d9c53c21e34f5f641fe83002317394311bdce14", + "sha256:90c1a32f1d68f940488354e36370f6cca89f0f106db09518524c88d6ed83f382" + ], + "markers": "python_version >= '3.6'", + "version": "==2022.9.24" + }, + "charset-normalizer": { + "hashes": [ + "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845", + "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f" + ], + "markers": "python_full_version >= '3.6.0'", + "version": "==2.1.1" + }, + "click": { + "hashes": [ + "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e", + "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48" + ], + "markers": "python_version >= '3.7'", + "version": "==8.1.3" + }, + "cytoolz": { + "hashes": [ + "sha256:02583c9fd4668f9e343ad4fc0e0f9651b1a0c16fe92bd208d07fd07de90fdc99", + "sha256:02dc4565a8d27c9f3e87b715c0a300890e17c94ba1294af61c4ba97aa8482b22", + "sha256:09f5652caeac85e3735bd5aaed49ebf4eeb7c0f15cb9b7c4a5fb6f45308dc2fd", + "sha256:09fac69cebcb79a6ed75565fe2de9511be6e3d93f30dad115832cc1a3933b6ce", + "sha256:0c9fe89548b1dc7c8b3160758d192791b32bd42b1c244a20809a1053a9d74428", + "sha256:0f94b4a3500345de5853d1896b7e770ce4a6577a431f43ff7d8f05f9051aeb7d", + "sha256:12d3d11ceb0fce8be5463f1e363366888c4b71e68fb2f5d536e4790b933cfd7e", + "sha256:16748ea2b40c5978190d9acf9aa8fbacbfb440964c1035dc16cb14dbd557edb5", + "sha256:1744217505b835fcf55d82d67addd0d361791c4fd6a2f485f034b343ffc7edb3", + "sha256:1a79658fd264c5f82ea1b5cb45cf3899afabd9ec3e58c333bea042a2b4a94134", + "sha256:1c22255e7458feb6f43d99c9578396e91d5934757c552128f6afd3b093b41c00", + "sha256:1cf9ae77eed57924becd3ab65ae24487d7b1f9823d3e685d796e58f57424f82a", + "sha256:21986f4a970c03ca84806b3a08e89386ac4aeb54c9b79d6a7268e83225331a87", + "sha256:231d87ffb5fc468989e35336a2f8da1c9b8d97cfd9300cf2df32e953e4d20cae", + "sha256:25c037a7b4f49730ccc295a03cd2217ba67ff43ac0918299f5f368271433ff0f", + "sha256:274bc965cd93d6fa0bfe6f770cf6549bbe58d7b0a48dd6893d3f2c4b495d7f95", + "sha256:2bd1c692ab706acb46cfebe7105945b07f7274598097e32c8979d3b22ae62cc6", + "sha256:2d29cf7a44a8abaeb00537e3bad7abf823fce194fe707c366f81020d384e22f7", + "sha256:2ee9ca2cfc939607926096c7cc6f298cee125f8ca53a4f46745f8dfbb7fb7ab1", + "sha256:336551092eb1cfc2ad5878cc08ef290f744843f84c1dda06f9e4a84d2c440b73", + "sha256:337c9a3ce2929c6361bcc1b304ce81ed675078a34c203dbb7c3e154f7ed1cca8", + "sha256:38e3386f63ebaea46a4ee0bfefc9a38590c3b78ab86439766b5225443468a76b", + "sha256:3a5408a74df84e84aa1c86a2f9f2ffaed51a55f34bbad5b8fae547cb9167e977", + "sha256:3e8335998e21205574fc7d8d17844a9cc0dd4cbb25bb7716d90683a935d2c879", + "sha256:46b9f4af719b113c01a4144c52fc4b929f98a47017a5408e3910050f4641126b", + "sha256:4b8b1d9764d08782caa8ba0e91d76b95b973a82f4ce2a3f9c7e726bfeaddbdfa", + "sha256:59263f296e043d4210dd34f91e6f11c4b20e6195976da23170d5ad056030258a", + "sha256:5b7079b3197256ac6bf73f8b9484d514fac68a36d05513b9e5247354d6fc2885", + "sha256:68336dfbe00efebbb1d02b8aa00b570dceec5d03fbd818c620aa246a8f5e5409", + "sha256:69c04ae878d5bcde5462e7290f950bfce11fd139ec4b481687983326658e6dbe", + "sha256:6aade6ebb4507330b0540af58dc2804415945611e90c70bb97360973e487c48a", + "sha256:6f87472837c26b3bc91f9767c7adcfb935d0c097937c6744250672cd8c36019d", + "sha256:6fa49cfaa0eedad59d8357a482bd10e2cc2a12ad9f41aae53427e82d3eba068a", + "sha256:7244fb0d0b87499becc29051b82925e0daf3838e6c352e6b2d62e0f969b090af", + "sha256:798dff7a40adbb3dfa2d50499c2038779061ebc37eccedaf28fa296cb517b84e", + "sha256:79b46cda959f026bd9fc33b4046294b32bd5e7664a4cf607179f80ac93844e7f", + "sha256:7fe93ffde090e2867f8ce4369d0c1abf5651817a74a3d0a4da2b1ffd412603ff", + "sha256:8060be3b1fa24a4e3b165ce3c0ee6048f5e181289af57dbd9e3c4d4b8545dd78", + "sha256:8237612fed78d4580e94141a74ac0977f5a9614dd7fa8f3d2fcb30e6d04e73aa", + "sha256:886b3bf8fa99510836107097a5e5a2bd81631d3795dedc5684e25bef6538ac39", + "sha256:8c0101bb2b2bcc0de2e2eb288a132c261e5fa883b1423799b47d4f0cfd879cd6", + "sha256:8f40897f6f341e03a945759fcdb2208dc7c64dc312386d3088c47b78fca2a3b2", + "sha256:94b067c88de0eaca174211c8422b3f72cbfb63b101a0eeb528c4f21282ca0afe", + "sha256:9ac7758c5c5a66664285831261a9af8e0af504026e0987cd01535045945df6e1", + "sha256:9dd7dbdfc24ed309af96be170c9030f43713950afab2b4bed1d372a91b37cbb0", + "sha256:9e32292721f16516a574891a1af6760cba37a0f426a2b2cea6f9d560131a76ea", + "sha256:9ecdd6e2be8d59b76c2bd3e2d832e7b3d5b2535c418b13cfa85e3b17de985199", + "sha256:a15157f4280f6e5d7c2d0892847a6c4dffbd2c5cefccaf1ac1f1c6c3d2cf9936", + "sha256:a2cca43caea857e761cc458ffb4f7af397a13824c5e71341ca08035ff5ff0b27", + "sha256:a4acf6cb20f01a5eb5b6d459e08fb92aacfb4de8bc97e25437c1a3e71860b452", + "sha256:a8e69c9f3a32e0f9331cf6707a0f159c6dec0ff2a9f41507f6b2d06cd423f0d0", + "sha256:a8feb4d056c22983723278160aff8a28c507b0e942768f4e856539a60e7bb874", + "sha256:ae403cac13c2b9a2a92e56468ca1f822899b64d75d5be8ca802f1c14870d9133", + "sha256:ae7f417bb2b4e3906e525b3dbe944791dfa9248faea719c7a9c200aa1a019a4e", + "sha256:b05dc257996c0accf6f877b1f212f74dc134b39c46baac09e1894d9d9c970b6a", + "sha256:b716f66b5ee72dbf9a001316ffe72afe0bb8f6ce84e341aec64291c0ff16b9f4", + "sha256:bb0fc2ed8efa89f31ffa99246b1d434ff3db2b7b7e35147486172da849c8024a", + "sha256:c105b05f85e03fbcd60244375968e62e44fe798c15a3531c922d531018d22412", + "sha256:c4ff74cb0e1a50de7f59e54a156dfd734b6593008f6f804d0726a73b89d170cd", + "sha256:c818a382b828e960fbbedbc85663414edbbba816c2bf8c1bb5651305d79bdb97", + "sha256:c9f8c9b3cfa20b4ce6a89b7e2e7ffda76bdd81e95b7d20bbb2c47c2b31e72622", + "sha256:cb072fa81caab93a5892c4b69dfe0d48f52026a7fe83ba2567020a7995a456e7", + "sha256:d035805dcdefcdfe64d97d6e1e7603798588d5e1ae08e61a5dae3258c3cb407a", + "sha256:d212296e996a70db8d9e1c0622bc8aefa732eb0416b5441624d0fd5b853ea391", + "sha256:d511dd49eb1263ccb4e5f84ae1478dc2824d66b813cdf700e1ba593faa256ade", + "sha256:d61bc1713662e7d9aa3e298dad790dfd027c5c0f1342c36be8401aebe3d3d453", + "sha256:db619f17705067f1f112d3e84a0904b2f04117e50cefc4016f435ff0dc59bc4e", + "sha256:dc8df9adfca0da9956589f53764d459389ce86d824663c7217422232f1dfbc9d", + "sha256:dd840adfe027d379e7aede973bc0e193e6eef9b33d46d1d42826e26db9b37d7e", + "sha256:deb8550f487de756f1c24c56fa2c8451a53c0346868c13899c6b3a39b1f3d2c3", + "sha256:e17516a102731bcf86446ce148127a8cd2887cf27ac388990cd63881115b4fdc", + "sha256:ed8771e36430fb0e4398030569bdab1419e4e74f7bcd51ea57239aa95441983a", + "sha256:edf460dc6bed081f274cd3d8ae162dd7e382014161d65edcdec832035d93901b", + "sha256:ee1fe1a3d0c8c456c3fbf62f28d178f870d14302fcd1edbc240b717ae3ab08de", + "sha256:ee92dadb312e657b9b666a0385fafc6dad073d8a0fbef5cea09e21011554206a", + "sha256:ef4a496a3175aec595ae24ad03e0bb2fe76401f8f79e7ef3d344533ba990ec0e", + "sha256:f1f5c1ef04240b323b9e6b87d4b1d7f14b735e284a33b18a509537a10f62715c", + "sha256:f24e70d29223cde8ce3f5aefa7fd06bda12ae4386dcfbc726773e95b099cde0d", + "sha256:f26079bc2d0b7aa1a185516ac9f7cda0d7932da6c60589bfed4079e3a5369e83", + "sha256:f5784adcdb285e70b61efc1a369cd61c6b7f1e0b5d521651f93cde09549681f5", + "sha256:f71b49a41826a8e7fd464d6991134a6d022a666be4e76d517850abbea561c909", + "sha256:f909760f89a54d860cf960b4cd828f9f6301fb104cd0de5b15b16822c9c4828b", + "sha256:f959c1319b7e6ed3367b0f5a54a7b9c59063bd053c74278b27999db013e568df", + "sha256:fa5ded9f811c36668239adb4806fca1244b06add4d64af31119c279aab1ef8a6" + ], + "markers": "implementation_name == 'cpython'", + "version": "==0.12.0" + }, + "dataclassy": { + "hashes": [ + "sha256:ad6622cb91e644d13f68768558983fbc22c90a8ff7e355638485d18b9baf1198", + "sha256:bcb030d3d700cf9b1597042bbc8375b92773e6f68f65675a7071862c0ddb87f5" + ], + "markers": "python_version >= '3.6'", + "version": "==0.11.1" + }, + "eip712": { + "hashes": [ + "sha256:2655c8ab58a552bc2adf0b5a07465483fe24a27237e07c4384f36f16efafa418", + "sha256:8d91257bb94cc33b0115b2f65c71297b6e8b8f16ed49173313e13ac8931df4b1" + ], + "markers": "python_version >= '3.6' and python_version < '4'", + "version": "==0.1.0" + }, + "eth-abi": { + "hashes": [ + "sha256:8d018351b00e304113f50ffded9baf4b9c6ef1c7e4ddec71bd64048c1c5c438c", + "sha256:d1bd16a911dd8fe45f1e6ed02099b4fceb8ae9ea741ab11b135cf288ada74a99" + ], + "markers": "python_version >= '3.6' and python_version < '4'", + "version": "==2.2.0" + }, + "eth-account": { + "hashes": [ + "sha256:42f9eefbf0e1c84a278bf27a25eccc2e0c20b18c17e2ab6f46044a534479e95a", + "sha256:ee62e121d977ca452f600043338af36f9349aa1f8409c5096d75df6576c79f1b" + ], + "markers": "python_version >= '3.6' and python_version < '4'", + "version": "==0.5.9" + }, + "eth-brownie": { + "hashes": [ + "sha256:8a4aff53ca4e759f380334e37a1adb9136ca92ef57bb03303a1c4e17c9789b0d", + "sha256:f26012728d1f9b83c88ecb59c9ddf38c11b2a51cc6c650fdff5842defc808004" + ], + "index": "pypi", + "version": "==1.19.2" + }, + "eth-event": { + "hashes": [ + "sha256:1589b583a9b0294f9aba4dedce8077685ced298393872f7f19bbf7d67ed9e49a", + "sha256:5d86d049eded86d0fb41538590487e1ccea2e1fa3e6d16ee2fc0952be7e5c59a" + ], + "markers": "python_version >= '3.6' and python_version < '4'", + "version": "==1.2.3" + }, + "eth-hash": { + "extras": [ + "pycryptodome" + ], + "hashes": [ + "sha256:3c884e4f788b38cc92cff05c4e43bc6b82686066f04ecfae0e11cdcbe5a283bd", + "sha256:8cde211519ff1a98b46e9057cb909f12ab62e263eb30a0a94e2f7e1f46ac67a0" + ], + "markers": "python_version >= '3.5' and python_version < '4'", + "version": "==0.3.3" + }, + "eth-keyfile": { + "hashes": [ + "sha256:70d734af17efdf929a90bb95375f43522be4ed80c3b9e0a8bca575fb11cd1159", + "sha256:939540efb503380bc30d926833e6a12b22c6750de80feef3720d79e5a79de47d" + ], + "version": "==0.5.1" + }, + "eth-keys": { + "hashes": [ + "sha256:565bf62179b8143bcbd302a0ec6c49882d9c7678f9e6ab0484a8a5725f5ef10e", + "sha256:e5590797f5e2930086c705a6dd1ac14397f74f19bdcd1b5f837475554f354ad8" + ], + "version": "==0.3.4" + }, + "eth-rlp": { + "hashes": [ + "sha256:cc389ef8d7b6f76a98f90bcdbff1b8684b3a78f53d47e871191b50d4d6aee5a1", + "sha256:f016f980b0ed42ee7650ba6e4e4d3c4e9aa06d8b9c6825a36d3afe5aa0187a8b" + ], + "markers": "python_version >= '3.6' and python_version < '4'", + "version": "==0.2.1" + }, + "eth-typing": { + "hashes": [ + "sha256:39cce97f401f082739b19258dfa3355101c64390914c73fe2b90012f443e0dc7", + "sha256:b7fa58635c1cb0cbf538b2f5f1e66139575ea4853eac1d6000f0961a4b277422" + ], + "markers": "python_version >= '3.5' and python_version < '4'", + "version": "==2.3.0" + }, + "eth-utils": { + "hashes": [ + "sha256:74240a8c6f652d085ed3c85f5f1654203d2f10ff9062f83b3bad0a12ff321c7a", + "sha256:bf82762a46978714190b0370265a7148c954d3f0adaa31c6f085ea375e4c61af" + ], + "markers": "python_version >= '3.5' and python_full_version != '3.5.2' and python_version < '4'", + "version": "==1.10.0" + }, + "execnet": { + "hashes": [ + "sha256:8f694f3ba9cc92cab508b152dcfe322153975c29bda272e2fd7f3f00f36e47c5", + "sha256:a295f7cc774947aac58dde7fdc85f4aa00c42adf5d8f5468fc630c1acf30a142" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==1.9.0" + }, + "frozenlist": { + "hashes": [ + "sha256:022178b277cb9277d7d3b3f2762d294f15e85cd2534047e68a118c2bb0058f3e", + "sha256:086ca1ac0a40e722d6833d4ce74f5bf1aba2c77cbfdc0cd83722ffea6da52a04", + "sha256:0bc75692fb3770cf2b5856a6c2c9de967ca744863c5e89595df64e252e4b3944", + "sha256:0dde791b9b97f189874d654c55c24bf7b6782343e14909c84beebd28b7217845", + "sha256:12607804084d2244a7bd4685c9d0dca5df17a6a926d4f1967aa7978b1028f89f", + "sha256:19127f8dcbc157ccb14c30e6f00392f372ddb64a6ffa7106b26ff2196477ee9f", + "sha256:1b51eb355e7f813bcda00276b0114c4172872dc5fb30e3fea059b9367c18fbcb", + "sha256:1e1cf7bc8cbbe6ce3881863671bac258b7d6bfc3706c600008925fb799a256e2", + "sha256:219a9676e2eae91cb5cc695a78b4cb43d8123e4160441d2b6ce8d2c70c60e2f3", + "sha256:2743bb63095ef306041c8f8ea22bd6e4d91adabf41887b1ad7886c4c1eb43d5f", + "sha256:2af6f7a4e93f5d08ee3f9152bce41a6015b5cf87546cb63872cc19b45476e98a", + "sha256:31b44f1feb3630146cffe56344704b730c33e042ffc78d21f2125a6a91168131", + "sha256:31bf9539284f39ff9398deabf5561c2b0da5bb475590b4e13dd8b268d7a3c5c1", + "sha256:35c3d79b81908579beb1fb4e7fcd802b7b4921f1b66055af2578ff7734711cfa", + "sha256:3a735e4211a04ccfa3f4833547acdf5d2f863bfeb01cfd3edaffbc251f15cec8", + "sha256:42719a8bd3792744c9b523674b752091a7962d0d2d117f0b417a3eba97d1164b", + "sha256:49459f193324fbd6413e8e03bd65789e5198a9fa3095e03f3620dee2f2dabff2", + "sha256:4c0c99e31491a1d92cde8648f2e7ccad0e9abb181f6ac3ddb9fc48b63301808e", + "sha256:52137f0aea43e1993264a5180c467a08a3e372ca9d378244c2d86133f948b26b", + "sha256:526d5f20e954d103b1d47232e3839f3453c02077b74203e43407b962ab131e7b", + "sha256:53b2b45052e7149ee8b96067793db8ecc1ae1111f2f96fe1f88ea5ad5fd92d10", + "sha256:572ce381e9fe027ad5e055f143763637dcbac2542cfe27f1d688846baeef5170", + "sha256:58fb94a01414cddcdc6839807db77ae8057d02ddafc94a42faee6004e46c9ba8", + "sha256:5e77a8bd41e54b05e4fb2708dc6ce28ee70325f8c6f50f3df86a44ecb1d7a19b", + "sha256:5f271c93f001748fc26ddea409241312a75e13466b06c94798d1a341cf0e6989", + "sha256:5f63c308f82a7954bf8263a6e6de0adc67c48a8b484fab18ff87f349af356efd", + "sha256:61d7857950a3139bce035ad0b0945f839532987dfb4c06cfe160254f4d19df03", + "sha256:61e8cb51fba9f1f33887e22488bad1e28dd8325b72425f04517a4d285a04c519", + "sha256:625d8472c67f2d96f9a4302a947f92a7adbc1e20bedb6aff8dbc8ff039ca6189", + "sha256:6e19add867cebfb249b4e7beac382d33215d6d54476bb6be46b01f8cafb4878b", + "sha256:717470bfafbb9d9be624da7780c4296aa7935294bd43a075139c3d55659038ca", + "sha256:74140933d45271c1a1283f708c35187f94e1256079b3c43f0c2267f9db5845ff", + "sha256:74e6b2b456f21fc93ce1aff2b9728049f1464428ee2c9752a4b4f61e98c4db96", + "sha256:9494122bf39da6422b0972c4579e248867b6b1b50c9b05df7e04a3f30b9a413d", + "sha256:94e680aeedc7fd3b892b6fa8395b7b7cc4b344046c065ed4e7a1e390084e8cb5", + "sha256:97d9e00f3ac7c18e685320601f91468ec06c58acc185d18bb8e511f196c8d4b2", + "sha256:9c6ef8014b842f01f5d2b55315f1af5cbfde284eb184075c189fd657c2fd8204", + "sha256:a027f8f723d07c3f21963caa7d585dcc9b089335565dabe9c814b5f70c52705a", + "sha256:a718b427ff781c4f4e975525edb092ee2cdef6a9e7bc49e15063b088961806f8", + "sha256:ab386503f53bbbc64d1ad4b6865bf001414930841a870fc97f1546d4d133f141", + "sha256:ab6fa8c7871877810e1b4e9392c187a60611fbf0226a9e0b11b7b92f5ac72792", + "sha256:b47d64cdd973aede3dd71a9364742c542587db214e63b7529fbb487ed67cddd9", + "sha256:b499c6abe62a7a8d023e2c4b2834fce78a6115856ae95522f2f974139814538c", + "sha256:bbb1a71b1784e68870800b1bc9f3313918edc63dbb8f29fbd2e767ce5821696c", + "sha256:c3b31180b82c519b8926e629bf9f19952c743e089c41380ddca5db556817b221", + "sha256:c56c299602c70bc1bb5d1e75f7d8c007ca40c9d7aebaf6e4ba52925d88ef826d", + "sha256:c92deb5d9acce226a501b77307b3b60b264ca21862bd7d3e0c1f3594022f01bc", + "sha256:cc2f3e368ee5242a2cbe28323a866656006382872c40869b49b265add546703f", + "sha256:d82bed73544e91fb081ab93e3725e45dd8515c675c0e9926b4e1f420a93a6ab9", + "sha256:da1cdfa96425cbe51f8afa43e392366ed0b36ce398f08b60de6b97e3ed4affef", + "sha256:da5ba7b59d954f1f214d352308d1d86994d713b13edd4b24a556bcc43d2ddbc3", + "sha256:e0c8c803f2f8db7217898d11657cb6042b9b0553a997c4a0601f48a691480fab", + "sha256:ee4c5120ddf7d4dd1eaf079af3af7102b56d919fa13ad55600a4e0ebe532779b", + "sha256:eee0c5ecb58296580fc495ac99b003f64f82a74f9576a244d04978a7e97166db", + "sha256:f5abc8b4d0c5b556ed8cd41490b606fe99293175a82b98e652c3f2711b452988", + "sha256:f810e764617b0748b49a731ffaa525d9bb36ff38332411704c2400125af859a6", + "sha256:f89139662cc4e65a4813f4babb9ca9544e42bddb823d2ec434e18dad582543bc", + "sha256:fa47319a10e0a076709644a0efbcaab9e91902c8bd8ef74c6adb19d320f69b83", + "sha256:fabb953ab913dadc1ff9dcc3a7a7d3dc6a92efab3a0373989b8063347f8705be" + ], + "markers": "python_version >= '3.7'", + "version": "==1.3.1" + }, + "hexbytes": { + "hashes": [ + "sha256:199daa356aeb14879ee9c43de637acaaa1409febf15151a0e3dbcf1f8df128c0", + "sha256:1b33a3f101084763551e0094dbf35104868dfa82ba48787a1ca77f81ce15a44c" + ], + "markers": "python_version >= '3.6' and python_version < '4'", + "version": "==0.2.3" + }, + "hypothesis": { + "hashes": [ + "sha256:1c4568f40ca893c884330a1de0e0e5dcb1e867c60a56f414cb7bce97afc8dfec", + "sha256:587da483bcc324494cec09cbbde3396c00da280c1732e387d7b5b89eff1aaff3" + ], + "markers": "python_version >= '3.6'", + "version": "==6.27.3" + }, + "idna": { + "hashes": [ + "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", + "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" + ], + "markers": "python_version >= '3.5'", + "version": "==3.4" + }, + "inflection": { + "hashes": [ + "sha256:88b101b2668a1d81d6d72d4c2018e53bc6c7fc544c987849da1c7f77545c3bc9", + "sha256:f576e85132d34f5bf7df5183c2c6f94cfb32e528f53065345cf71329ba0b8924" + ], + "markers": "python_version >= '3.5'", + "version": "==0.5.0" + }, + "iniconfig": { + "hashes": [ + "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3", + "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32" + ], + "version": "==1.1.1" + }, + "ipfshttpclient": { + "hashes": [ + "sha256:0d80e95ee60b02c7d414e79bf81a36fc3c8fbab74265475c52f70b2620812135", + "sha256:ce6bac0e3963c4ced74d7eb6978125362bb05bbe219088ca48f369ce14d3cc39" + ], + "markers": "python_full_version >= '3.6.2' and python_full_version not in '3.7.0, 3.7.1'", + "version": "==0.8.0a2" + }, + "jsonschema": { + "hashes": [ + "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163", + "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a" + ], + "version": "==3.2.0" + }, + "lazy-object-proxy": { + "hashes": [ + "sha256:043651b6cb706eee4f91854da4a089816a6606c1428fd391573ef8cb642ae4f7", + "sha256:07fa44286cda977bd4803b656ffc1c9b7e3bc7dff7d34263446aec8f8c96f88a", + "sha256:12f3bb77efe1367b2515f8cb4790a11cffae889148ad33adad07b9b55e0ab22c", + "sha256:2052837718516a94940867e16b1bb10edb069ab475c3ad84fd1e1a6dd2c0fcfc", + "sha256:2130db8ed69a48a3440103d4a520b89d8a9405f1b06e2cc81640509e8bf6548f", + "sha256:39b0e26725c5023757fc1ab2a89ef9d7ab23b84f9251e28f9cc114d5b59c1b09", + "sha256:46ff647e76f106bb444b4533bb4153c7370cdf52efc62ccfc1a28bdb3cc95442", + "sha256:4dca6244e4121c74cc20542c2ca39e5c4a5027c81d112bfb893cf0790f96f57e", + "sha256:553b0f0d8dbf21890dd66edd771f9b1b5f51bd912fa5f26de4449bfc5af5e029", + "sha256:677ea950bef409b47e51e733283544ac3d660b709cfce7b187f5ace137960d61", + "sha256:6a24357267aa976abab660b1d47a34aaf07259a0c3859a34e536f1ee6e76b5bb", + "sha256:6a6e94c7b02641d1311228a102607ecd576f70734dc3d5e22610111aeacba8a0", + "sha256:6aff3fe5de0831867092e017cf67e2750c6a1c7d88d84d2481bd84a2e019ec35", + "sha256:6ecbb350991d6434e1388bee761ece3260e5228952b1f0c46ffc800eb313ff42", + "sha256:7096a5e0c1115ec82641afbdd70451a144558ea5cf564a896294e346eb611be1", + "sha256:70ed0c2b380eb6248abdef3cd425fc52f0abd92d2b07ce26359fcbc399f636ad", + "sha256:8561da8b3dd22d696244d6d0d5330618c993a215070f473b699e00cf1f3f6443", + "sha256:85b232e791f2229a4f55840ed54706110c80c0a210d076eee093f2b2e33e1bfd", + "sha256:898322f8d078f2654d275124a8dd19b079080ae977033b713f677afcfc88e2b9", + "sha256:8f3953eb575b45480db6568306893f0bd9d8dfeeebd46812aa09ca9579595148", + "sha256:91ba172fc5b03978764d1df5144b4ba4ab13290d7bab7a50f12d8117f8630c38", + "sha256:9d166602b525bf54ac994cf833c385bfcc341b364e3ee71e3bf5a1336e677b55", + "sha256:a57d51ed2997e97f3b8e3500c984db50a554bb5db56c50b5dab1b41339b37e36", + "sha256:b9e89b87c707dd769c4ea91f7a31538888aad05c116a59820f28d59b3ebfe25a", + "sha256:bb8c5fd1684d60a9902c60ebe276da1f2281a318ca16c1d0a96db28f62e9166b", + "sha256:c19814163728941bb871240d45c4c30d33b8a2e85972c44d4e63dd7107faba44", + "sha256:c4ce15276a1a14549d7e81c243b887293904ad2d94ad767f42df91e75fd7b5b6", + "sha256:c7a683c37a8a24f6428c28c561c80d5f4fd316ddcf0c7cab999b15ab3f5c5c69", + "sha256:d609c75b986def706743cdebe5e47553f4a5a1da9c5ff66d76013ef396b5a8a4", + "sha256:d66906d5785da8e0be7360912e99c9188b70f52c422f9fc18223347235691a84", + "sha256:dd7ed7429dbb6c494aa9bc4e09d94b778a3579be699f9d67da7e6804c422d3de", + "sha256:df2631f9d67259dc9620d831384ed7732a198eb434eadf69aea95ad18c587a28", + "sha256:e368b7f7eac182a59ff1f81d5f3802161932a41dc1b1cc45c1f757dc876b5d2c", + "sha256:e40f2013d96d30217a51eeb1db28c9ac41e9d0ee915ef9d00da639c5b63f01a1", + "sha256:f769457a639403073968d118bc70110e7dce294688009f5c24ab78800ae56dc8", + "sha256:fccdf7c2c5821a8cbd0a9440a456f5050492f2270bd54e94360cac663398739b", + "sha256:fd45683c3caddf83abbb1249b653a266e7069a09f486daa8863fb0e7496a9fdb" + ], + "markers": "python_version >= '3.6'", + "version": "==1.7.1" + }, + "lru-dict": { + "hashes": [ + "sha256:075b9dd46d7022b675419bc6e3631748ae184bc8af195d20365a98b4f3bb2914", + "sha256:0972d669e9e207617e06416166718b073a49bf449abbd23940d9545c0847a4d9", + "sha256:0f83cd70a6d32f9018d471be609f3af73058f700691657db4a3d3dd78d3f96dd", + "sha256:10fe823ff90b655f0b6ba124e2b576ecda8c61b8ead76b456db67831942d22f2", + "sha256:163079dbda54c3e6422b23da39fb3ecc561035d65e8496ff1950cbdb376018e1", + "sha256:1fe16ade5fd0a57e9a335f69b8055aaa6fb278fbfa250458e4f6b8255115578f", + "sha256:262a4e622010ceb960a6a5222ed011090e50954d45070fd369c0fa4d2ed7d9a9", + "sha256:2f340b61f3cdfee71f66da7dbfd9a5ea2db6974502ccff2065cdb76619840dca", + "sha256:348167f110494cfafae70c066470a6f4e4d43523933edf16ccdb8947f3b5fae0", + "sha256:3b1692755fef288b67af5cd8a973eb331d1f44cb02cbdc13660040809c2bfec6", + "sha256:3ca497cb25f19f24171f9172805f3ff135b911aeb91960bd4af8e230421ccb51", + "sha256:3d003a864899c29b0379e412709a6e516cbd6a72ee10b09d0b33226343617412", + "sha256:3fef595c4f573141d54a38bda9221b9ee3cbe0acc73d67304a1a6d5972eb2a02", + "sha256:484ac524e4615f06dc72ffbfd83f26e073c9ec256de5413634fbd024c010a8bc", + "sha256:55aeda6b6789b2d030066b4f5f6fc3596560ba2a69028f35f3682a795701b5b1", + "sha256:5a592363c93d6fc6472d5affe2819e1c7590746aecb464774a4f67e09fbefdfc", + "sha256:5b09dbe47bc4b4d45ffe56067aff190bc3c0049575da6e52127e114236e0a6a7", + "sha256:6e2a7aa9e36626fb48fdc341c7e3685a31a7b50ea4918677ea436271ad0d904d", + "sha256:70364e3cbef536adab8762b4835e18f5ca8e3fddd8bd0ec9258c42bbebd0ee77", + "sha256:720f5728e537f11a311e8b720793a224e985d20e6b7c3d34a891a391865af1a2", + "sha256:7284bdbc5579bbdc3fc8f869ed4c169f403835566ab0f84567cdbfdd05241847", + "sha256:7be1b66926277993cecdc174c15a20c8ce785c1f8b39aa560714a513eef06473", + "sha256:86d32a4498b74a75340497890a260d37bf1560ad2683969393032977dd36b088", + "sha256:878bc8ef4073e5cfb953dfc1cf4585db41e8b814c0106abde34d00ee0d0b3115", + "sha256:881104711900af45967c2e5ce3e62291dd57d5b2a224d58b7c9f60bf4ad41b8c", + "sha256:8c50ab9edaa5da5838426816a2b7bcde9d576b4fc50e6a8c062073dbc4969d78", + "sha256:8f6561f9cd5a452cb84905c6a87aa944fdfdc0f41cc057d03b71f9b29b2cc4bd", + "sha256:93336911544ebc0e466272043adab9fb9f6e9dcba6024b639c32553a3790e089", + "sha256:9447214e4857e16d14158794ef01e4501d8fad07d298d03308d9f90512df02fa", + "sha256:97c24ffc55de6013075979f440acd174e88819f30387074639fb7d7178ca253e", + "sha256:99f6cfb3e28490357a0805b409caf693e46c61f8dbb789c51355adb693c568d3", + "sha256:9be6c4039ef328676b868acea619cd100e3de1a35b3be211cf0eaf9775563b65", + "sha256:9d70257246b8207e8ef3d8b18457089f5ff0dfb087bd36eb33bce6584f2e0b3a", + "sha256:a777d48319d293b1b6a933d606c0e4899690a139b4c81173451913bbcab6f44f", + "sha256:add762163f4af7f4173fafa4092eb7c7f023cf139ef6d2015cfea867e1440d82", + "sha256:b6f64005ede008b7a866be8f3f6274dbf74e656e15e4004e9d99ad65efb01809", + "sha256:beb089c46bd95243d1ac5b2bd13627317b08bf40dd8dc16d4b7ee7ecb3cf65ca", + "sha256:c07163c9dcbb2eca377f366b1331f46302fd8b6b72ab4d603087feca00044bb0", + "sha256:c2fe692332c2f1d81fd27457db4b35143801475bfc2e57173a2403588dd82a42", + "sha256:ca8f89361e0e7aad0bf93ae03a31502e96280faeb7fb92267f4998fb230d36b2", + "sha256:d2ed4151445c3f30423c2698f72197d64b27b1cd61d8d56702ffe235584e47c2", + "sha256:db20597c4e67b4095b376ce2e83930c560f4ce481e8d05737885307ed02ba7c1", + "sha256:de972c7f4bc7b6002acff2a8de984c55fbd7f2289dba659cfd90f7a0f5d8f5d1", + "sha256:f1df1da204a9f0b5eb8393a46070f1d984fa8559435ee790d7f8f5602038fc00", + "sha256:f4d0a6d733a23865019b1c97ed6fb1fdb739be923192abf4dbb644f697a26a69", + "sha256:f874e9c2209dada1a080545331aa1277ec060a13f61684a8642788bf44b2325f", + "sha256:f877f53249c3e49bbd7612f9083127290bede6c7d6501513567ab1bf9c581381", + "sha256:f9d5815c0e85922cd0fb8344ca8b1c7cf020bf9fc45e670d34d51932c91fd7ec" + ], + "version": "==1.1.8" + }, + "multiaddr": { + "hashes": [ + "sha256:30b2695189edc3d5b90f1c303abb8f02d963a3a4edf2e7178b975eb417ab0ecf", + "sha256:5c0f862cbcf19aada2a899f80ef896ddb2e85614e0c8f04dd287c06c69dac95b" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==0.0.9" + }, + "multidict": { + "hashes": [ + "sha256:0327292e745a880459ef71be14e709aaea2f783f3537588fb4ed09b6c01bca60", + "sha256:041b81a5f6b38244b34dc18c7b6aba91f9cdaf854d9a39e5ff0b58e2b5773b9c", + "sha256:0556a1d4ea2d949efe5fd76a09b4a82e3a4a30700553a6725535098d8d9fb672", + "sha256:05f6949d6169878a03e607a21e3b862eaf8e356590e8bdae4227eedadacf6e51", + "sha256:07a017cfa00c9890011628eab2503bee5872f27144936a52eaab449be5eaf032", + "sha256:0b9e95a740109c6047602f4db4da9949e6c5945cefbad34a1299775ddc9a62e2", + "sha256:19adcfc2a7197cdc3987044e3f415168fc5dc1f720c932eb1ef4f71a2067e08b", + "sha256:19d9bad105dfb34eb539c97b132057a4e709919ec4dd883ece5838bcbf262b80", + "sha256:225383a6603c086e6cef0f2f05564acb4f4d5f019a4e3e983f572b8530f70c88", + "sha256:23b616fdc3c74c9fe01d76ce0d1ce872d2d396d8fa8e4899398ad64fb5aa214a", + "sha256:2957489cba47c2539a8eb7ab32ff49101439ccf78eab724c828c1a54ff3ff98d", + "sha256:2d36e929d7f6a16d4eb11b250719c39560dd70545356365b494249e2186bc389", + "sha256:2e4a0785b84fb59e43c18a015ffc575ba93f7d1dbd272b4cdad9f5134b8a006c", + "sha256:3368bf2398b0e0fcbf46d85795adc4c259299fec50c1416d0f77c0a843a3eed9", + "sha256:373ba9d1d061c76462d74e7de1c0c8e267e9791ee8cfefcf6b0b2495762c370c", + "sha256:4070613ea2227da2bfb2c35a6041e4371b0af6b0be57f424fe2318b42a748516", + "sha256:45183c96ddf61bf96d2684d9fbaf6f3564d86b34cb125761f9a0ef9e36c1d55b", + "sha256:4571f1beddff25f3e925eea34268422622963cd8dc395bb8778eb28418248e43", + "sha256:47e6a7e923e9cada7c139531feac59448f1f47727a79076c0b1ee80274cd8eee", + "sha256:47fbeedbf94bed6547d3aa632075d804867a352d86688c04e606971595460227", + "sha256:497988d6b6ec6ed6f87030ec03280b696ca47dbf0648045e4e1d28b80346560d", + "sha256:4bae31803d708f6f15fd98be6a6ac0b6958fcf68fda3c77a048a4f9073704aae", + "sha256:50bd442726e288e884f7be9071016c15a8742eb689a593a0cac49ea093eef0a7", + "sha256:514fe2b8d750d6cdb4712346a2c5084a80220821a3e91f3f71eec11cf8d28fd4", + "sha256:5774d9218d77befa7b70d836004a768fb9aa4fdb53c97498f4d8d3f67bb9cfa9", + "sha256:5fdda29a3c7e76a064f2477c9aab1ba96fd94e02e386f1e665bca1807fc5386f", + "sha256:5ff3bd75f38e4c43f1f470f2df7a4d430b821c4ce22be384e1459cb57d6bb013", + "sha256:626fe10ac87851f4cffecee161fc6f8f9853f0f6f1035b59337a51d29ff3b4f9", + "sha256:6701bf8a5d03a43375909ac91b6980aea74b0f5402fbe9428fc3f6edf5d9677e", + "sha256:684133b1e1fe91eda8fa7447f137c9490a064c6b7f392aa857bba83a28cfb693", + "sha256:6f3cdef8a247d1eafa649085812f8a310e728bdf3900ff6c434eafb2d443b23a", + "sha256:75bdf08716edde767b09e76829db8c1e5ca9d8bb0a8d4bd94ae1eafe3dac5e15", + "sha256:7c40b7bbece294ae3a87c1bc2abff0ff9beef41d14188cda94ada7bcea99b0fb", + "sha256:8004dca28e15b86d1b1372515f32eb6f814bdf6f00952699bdeb541691091f96", + "sha256:8064b7c6f0af936a741ea1efd18690bacfbae4078c0c385d7c3f611d11f0cf87", + "sha256:89171b2c769e03a953d5969b2f272efa931426355b6c0cb508022976a17fd376", + "sha256:8cbf0132f3de7cc6c6ce00147cc78e6439ea736cee6bca4f068bcf892b0fd658", + "sha256:9cc57c68cb9139c7cd6fc39f211b02198e69fb90ce4bc4a094cf5fe0d20fd8b0", + "sha256:a007b1638e148c3cfb6bf0bdc4f82776cef0ac487191d093cdc316905e504071", + "sha256:a2c34a93e1d2aa35fbf1485e5010337c72c6791407d03aa5f4eed920343dd360", + "sha256:a45e1135cb07086833ce969555df39149680e5471c04dfd6a915abd2fc3f6dbc", + "sha256:ac0e27844758d7177989ce406acc6a83c16ed4524ebc363c1f748cba184d89d3", + "sha256:aef9cc3d9c7d63d924adac329c33835e0243b5052a6dfcbf7732a921c6e918ba", + "sha256:b9d153e7f1f9ba0b23ad1568b3b9e17301e23b042c23870f9ee0522dc5cc79e8", + "sha256:bfba7c6d5d7c9099ba21f84662b037a0ffd4a5e6b26ac07d19e423e6fdf965a9", + "sha256:c207fff63adcdf5a485969131dc70e4b194327666b7e8a87a97fbc4fd80a53b2", + "sha256:d0509e469d48940147e1235d994cd849a8f8195e0bca65f8f5439c56e17872a3", + "sha256:d16cce709ebfadc91278a1c005e3c17dd5f71f5098bfae1035149785ea6e9c68", + "sha256:d48b8ee1d4068561ce8033d2c344cf5232cb29ee1a0206a7b828c79cbc5982b8", + "sha256:de989b195c3d636ba000ee4281cd03bb1234635b124bf4cd89eeee9ca8fcb09d", + "sha256:e07c8e79d6e6fd37b42f3250dba122053fddb319e84b55dd3a8d6446e1a7ee49", + "sha256:e2c2e459f7050aeb7c1b1276763364884595d47000c1cddb51764c0d8976e608", + "sha256:e5b20e9599ba74391ca0cfbd7b328fcc20976823ba19bc573983a25b32e92b57", + "sha256:e875b6086e325bab7e680e4316d667fc0e5e174bb5611eb16b3ea121c8951b86", + "sha256:f4f052ee022928d34fe1f4d2bc743f32609fb79ed9c49a1710a5ad6b2198db20", + "sha256:fcb91630817aa8b9bc4a74023e4198480587269c272c58b3279875ed7235c293", + "sha256:fd9fc9c4849a07f3635ccffa895d57abce554b467d611a5009ba4f39b78a8849", + "sha256:feba80698173761cddd814fa22e88b0661e98cb810f9f986c54aa34d281e4937", + "sha256:feea820722e69451743a3d56ad74948b68bf456984d63c1a92e8347b7b88452d" + ], + "markers": "python_version >= '3.7'", + "version": "==6.0.2" + }, + "mypy-extensions": { + "hashes": [ + "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", + "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8" + ], + "version": "==0.4.3" + }, + "mythx-models": { + "hashes": [ + "sha256:037090723c5006df25656473db7875469e11d9d03478d41bb8d1f1517c1c474c", + "sha256:4b9133c2ee41f97c03545bb480a16f3388b10557c5622aeada7ce79aaadcf7de" + ], + "version": "==1.9.1" + }, + "netaddr": { + "hashes": [ + "sha256:9666d0232c32d2656e5e5f8d735f58fd6c7457ce52fc21c98d45f2af78f990ac", + "sha256:d6cc57c7a07b1d9d2e917aa8b36ae8ce61c35ba3fcd1b83ca31c5a0ee2b5a243" + ], + "version": "==0.8.0" + }, + "packaging": { + "hashes": [ + "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb", + "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522" + ], + "markers": "python_version >= '3.6'", + "version": "==21.3" + }, + "parsimonious": { + "hashes": [ + "sha256:3add338892d580e0cb3b1a39e4a1b427ff9f687858fdd61097053742391a9f6b" + ], + "version": "==0.8.1" + }, + "pathspec": { + "hashes": [ + "sha256:46846318467efc4556ccfd27816e004270a9eeeeb4d062ce5e6fc7a87c573f93", + "sha256:7ace6161b621d31e7902eb6b5ae148d12cfd23f4a249b9ffb6b9fee12084323d" + ], + "markers": "python_version >= '3.7'", + "version": "==0.10.1" + }, + "platformdirs": { + "hashes": [ + "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788", + "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19" + ], + "markers": "python_version >= '3.7'", + "version": "==2.5.2" + }, + "pluggy": { + "hashes": [ + "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159", + "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3" + ], + "markers": "python_version >= '3.6'", + "version": "==1.0.0" + }, + "prompt-toolkit": { + "hashes": [ + "sha256:9696f386133df0fc8ca5af4895afe5d78f5fcfe5258111c2a79a1c3e41ffa96d", + "sha256:9ada952c9d1787f52ff6d5f3484d0b4df8952787c087edf6a1f7c2cb1ea88148" + ], + "markers": "python_full_version >= '3.6.2'", + "version": "==3.0.31" + }, + "protobuf": { + "hashes": [ + "sha256:1867f93b06a183f87696871bb8d1e99ee71dbb69d468ce1f0cc8bf3d30f982f3", + "sha256:3c4160b601220627f7e91154e572baf5e161a9c3f445a8242d536ee3d0b7b17c", + "sha256:4ee2af7051d3b10c8a4fe6fd1a2c69f201fea36aeee7086cf202a692e1b99ee1", + "sha256:5266c36cc0af3bb3dbf44f199d225b33da66a9a5c3bdc2b14865ad10eddf0e37", + "sha256:5470f892961af464ae6eaf0f3099e2c1190ae8c7f36f174b89491281341f79ca", + "sha256:66d14b5b90090353efe75c9fb1bf65ef7267383034688d255b500822e37d5c2f", + "sha256:67efb5d20618020aa9596e17bfc37ca068c28ec0c1507d9507f73c93d46c9855", + "sha256:696e6cfab94cc15a14946f2bf72719dced087d437adbd994fff34f38986628bc", + "sha256:6a02172b9650f819d01fb8e224fc69b0706458fc1ab4f1c669281243c71c1a5e", + "sha256:950abd6c00e7b51f87ae8b18a0ce4d69fea217f62f171426e77de5061f6d9850", + "sha256:9e1d74032f56ff25f417cfe84c8147047732e5059137ca42efad20cbbd25f5e0", + "sha256:9e42b1cf2ecd8a1bd161239e693f22035ba99905ae6d7efeac8a0546c7ec1a27", + "sha256:9f957ef53e872d58a0afd3bf6d80d48535d28c99b40e75e6634cbc33ea42fd54", + "sha256:a89aa0c042e61e11ade320b802d6db4ee5391d8d973e46d3a48172c1597789f8", + "sha256:c0f80876a8ff0ae7064084ed094eb86497bd5a3812e6fc96a05318b92301674e", + "sha256:c44e3282cff74ad18c7e8a0375f407f69ee50c2116364b44492a196293e08b21", + "sha256:d249519ba5ecf5dd6b18150c9b6bcde510b273714b696f3923ff8308fc11ae49", + "sha256:d3973a2d58aefc7d1230725c2447ce7f86a71cbc094b86a77c6ee1505ac7cdb1", + "sha256:dca2284378a5f2a86ffed35c6ac147d14c48b525eefcd1083e5a9ce28dfa8657", + "sha256:e63b0b3c42e51c94add62b010366cd4979cb6d5f06158bcae8faac4c294f91e1", + "sha256:f2b599a21c9a32e171ec29a2ac54e03297736c578698e11b099d031f79da114b", + "sha256:f2bde37667b18c2b5280df83bc799204394a5d2d774e4deaf9de0eb741df6833", + "sha256:f4f909f4dde413dec435a44b0894956d55bb928ded7d6e3c726556ca4c796e84", + "sha256:f976234e20ab2785f54224bcdafa027674e23663b132fa3ca0caa291a6cfbde7", + "sha256:f9cebda093c2f6bfed88f1c17cdade09d4d96096421b344026feee236532d4de" + ], + "markers": "python_version >= '3.5'", + "version": "==3.19.5" + }, + "psutil": { + "hashes": [ + "sha256:14b29f581b5edab1f133563272a6011925401804d52d603c5c606936b49c8b97", + "sha256:256098b4f6ffea6441eb54ab3eb64db9ecef18f6a80d7ba91549195d55420f84", + "sha256:39ec06dc6c934fb53df10c1672e299145ce609ff0611b569e75a88f313634969", + "sha256:404f4816c16a2fcc4eaa36d7eb49a66df2d083e829d3e39ee8759a411dbc9ecf", + "sha256:42638876b7f5ef43cef8dcf640d3401b27a51ee3fa137cb2aa2e72e188414c32", + "sha256:4642fd93785a29353d6917a23e2ac6177308ef5e8be5cc17008d885cb9f70f12", + "sha256:4fb54941aac044a61db9d8eb56fc5bee207db3bc58645d657249030e15ba3727", + "sha256:561dec454853846d1dd0247b44c2e66a0a0c490f937086930ec4b8f83bf44f06", + "sha256:5d39e3a2d5c40efa977c9a8dd4f679763c43c6c255b1340a56489955dbca767c", + "sha256:614337922702e9be37a39954d67fdb9e855981624d8011a9927b8f2d3c9625d9", + "sha256:67b33f27fc0427483b61563a16c90d9f3b547eeb7af0ef1b9fe024cdc9b3a6ea", + "sha256:68b35cbff92d1f7103d8f1db77c977e72f49fcefae3d3d2b91c76b0e7aef48b8", + "sha256:7cbb795dcd8ed8fd238bc9e9f64ab188f3f4096d2e811b5a82da53d164b84c3f", + "sha256:8f024fbb26c8daf5d70287bb3edfafa22283c255287cf523c5d81721e8e5d82c", + "sha256:91aa0dac0c64688667b4285fa29354acfb3e834e1fd98b535b9986c883c2ce1d", + "sha256:94e621c6a4ddb2573d4d30cba074f6d1aa0186645917df42c811c473dd22b339", + "sha256:9770c1d25aee91417eba7869139d629d6328a9422ce1cdd112bd56377ca98444", + "sha256:b1928b9bf478d31fdffdb57101d18f9b70ed4e9b0e41af751851813547b2a9ab", + "sha256:b2f248ffc346f4f4f0d747ee1947963613216b06688be0be2e393986fe20dbbb", + "sha256:b315febaebae813326296872fdb4be92ad3ce10d1d742a6b0c49fb619481ed0b", + "sha256:b3591616fa07b15050b2f87e1cdefd06a554382e72866fcc0ab2be9d116486c8", + "sha256:b4018d5f9b6651f9896c7a7c2c9f4652e4eea53f10751c4e7d08a9093ab587ec", + "sha256:d75291912b945a7351d45df682f9644540d564d62115d4a20d45fa17dc2d48f8", + "sha256:dc9bda7d5ced744622f157cc8d8bdd51735dafcecff807e928ff26bdb0ff097d", + "sha256:e3ac2c0375ef498e74b9b4ec56df3c88be43fe56cac465627572dbfb21c4be34", + "sha256:e4c4a7636ffc47b7141864f1c5e7d649f42c54e49da2dd3cceb1c5f5d29bfc85", + "sha256:ed29ea0b9a372c5188cdb2ad39f937900a10fb5478dc077283bf86eeac678ef1", + "sha256:f40ba362fefc11d6bea4403f070078d60053ed422255bd838cd86a40674364c9", + "sha256:f4cb67215c10d4657e320037109939b1c1d2fd70ca3d76301992f89fe2edb1f1", + "sha256:f7929a516125f62399d6e8e026129c8835f6c5a3aab88c3fff1a05ee8feb840d", + "sha256:fd331866628d18223a4265371fd255774affd86244fc307ef66eaf00de0633d5", + "sha256:feb861a10b6c3bb00701063b37e4afc754f8217f0f09c42280586bd6ac712b5c" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==5.9.2" + }, + "py": { + "hashes": [ + "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719", + "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==1.11.0" + }, + "py-solc-ast": { + "hashes": [ + "sha256:5a5c3bb1998de32eed4b793ebbf2f14f1fd5c681cf8b62af6b8f9f76b805164d", + "sha256:f636217ef77bbe0f9c87a71af2f6cc9577f6301aa2ffb9af119f4c8fa8522b2d" + ], + "markers": "python_version >= '3.6' and python_version < '4'", + "version": "==1.2.9" + }, + "py-solc-x": { + "hashes": [ + "sha256:8f5caa4f54e227fc301e2e4c8aa868e869c2bc0c6636aa9e8115f8414bb891f9", + "sha256:d8b0bd2b04f47cff6e92181739d9e94e41b2d62f056900761c797fa5babc76b6" + ], + "markers": "python_version >= '3.6' and python_version < '4'", + "version": "==1.1.1" + }, + "pycryptodome": { + "hashes": [ + "sha256:045d75527241d17e6ef13636d845a12e54660aa82e823b3b3341bcf5af03fa79", + "sha256:0926f7cc3735033061ef3cf27ed16faad6544b14666410727b31fea85a5b16eb", + "sha256:092a26e78b73f2530b8bd6b3898e7453ab2f36e42fd85097d705d6aba2ec3e5e", + "sha256:1b22bcd9ec55e9c74927f6b1f69843cb256fb5a465088ce62837f793d9ffea88", + "sha256:2aa55aae81f935a08d5a3c2042eb81741a43e044bd8a81ea7239448ad751f763", + "sha256:2ea63d46157386c5053cfebcdd9bd8e0c8b7b0ac4a0507a027f5174929403884", + "sha256:2ec709b0a58b539a4f9d33fb8508264c3678d7edb33a68b8906ba914f71e8c13", + "sha256:2ffd8b31561455453ca9f62cb4c24e6b8d119d6d531087af5f14b64bee2c23e6", + "sha256:4b52cb18b0ad46087caeb37a15e08040f3b4c2d444d58371b6f5d786d95534c2", + "sha256:4c3ccad74eeb7b001f3538643c4225eac398c77d617ebb3e57571a897943c667", + "sha256:5099c9ca345b2f252f0c28e96904643153bae9258647585e5e6f649bb7a1844a", + "sha256:57f565acd2f0cf6fb3e1ba553d0cb1f33405ec1f9c5ded9b9a0a5320f2c0bd3d", + "sha256:60b4faae330c3624cc5a546ba9cfd7b8273995a15de94ee4538130d74953ec2e", + "sha256:7c9ed8aa31c146bef65d89a1b655f5f4eab5e1120f55fc297713c89c9e56ff0b", + "sha256:7e3a8f6ee405b3bd1c4da371b93c31f7027944b2bcce0697022801db93120d83", + "sha256:9135dddad504592bcc18b0d2d95ce86c3a5ea87ec6447ef25cfedea12d6018b8", + "sha256:9c772c485b27967514d0df1458b56875f4b6d025566bf27399d0c239ff1b369f", + "sha256:9eaadc058106344a566dc51d3d3a758ab07f8edde013712bc8d22032a86b264f", + "sha256:9ee40e2168f1348ae476676a2e938ca80a2f57b14a249d8fe0d3cdf803e5a676", + "sha256:a8f06611e691c2ce45ca09bbf983e2ff2f8f4f87313609d80c125aff9fad6e7f", + "sha256:b9c5b1a1977491533dfd31e01550ee36ae0249d78aae7f632590db833a5012b8", + "sha256:b9cc96e274b253e47ad33ae1fccc36ea386f5251a823ccb50593a935db47fdd2", + "sha256:c3640deff4197fa064295aaac10ab49a0d55ef3d6a54ae1499c40d646655c89f", + "sha256:c77126899c4b9c9827ddf50565e93955cb3996813c18900c16b2ea0474e130e9", + "sha256:d2a39a66057ab191e5c27211a7daf8f0737f23acbf6b3562b25a62df65ffcb7b", + "sha256:e244ab85c422260de91cda6379e8e986405b4f13dc97d2876497178707f87fc1", + "sha256:ecaaef2d21b365d9c5ca8427ffc10cebed9d9102749fd502218c23cb9a05feb5", + "sha256:fd2184aae6ee2a944aaa49113e6f5787cdc5e4db1eb8edb1aea914bd75f33a0c", + "sha256:ff287bcba9fbeb4f1cccc1f2e90a08d691480735a611ee83c80a7d74ad72b9d9", + "sha256:ff7ae90e36c1715a54446e7872b76102baa5c63aa980917f4aa45e8c78d1a3ec" + ], + "version": "==3.15.0" + }, + "pygments": { + "hashes": [ + "sha256:56a8508ae95f98e2b9bdf93a6be5ae3f7d8af858b43e02c5a2ff083726be40c1", + "sha256:f643f331ab57ba3c9d89212ee4a2dabc6e94f117cf4eefde99a0574720d14c42" + ], + "markers": "python_version >= '3.6'", + "version": "==2.13.0" + }, + "pygments-lexer-solidity": { + "hashes": [ + "sha256:a347fd96981838331b6d98b0f891776908a49406d343ff2a40a6a1c8475a9350" + ], + "version": "==0.7.0" + }, + "pyjwt": { + "hashes": [ + "sha256:5c6eca3c2940464d106b99ba83b00c6add741c9becaec087fb7ccdefea71350e", + "sha256:8d59a976fb773f3e6a39c85636357c4f0e242707394cadadd9814f5cbaa20e96" + ], + "version": "==1.7.1" + }, + "pyparsing": { + "hashes": [ + "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb", + "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc" + ], + "markers": "python_full_version >= '3.6.8'", + "version": "==3.0.9" + }, + "pyrsistent": { + "hashes": [ + "sha256:0e3e1fcc45199df76053026a51cc59ab2ea3fc7c094c6627e93b7b44cdae2c8c", + "sha256:1b34eedd6812bf4d33814fca1b66005805d3640ce53140ab8bbb1e2651b0d9bc", + "sha256:4ed6784ceac462a7d6fcb7e9b663e93b9a6fb373b7f43594f9ff68875788e01e", + "sha256:5d45866ececf4a5fff8742c25722da6d4c9e180daa7b405dc0a2a2790d668c26", + "sha256:636ce2dc235046ccd3d8c56a7ad54e99d5c1cd0ef07d9ae847306c91d11b5fec", + "sha256:6455fc599df93d1f60e1c5c4fe471499f08d190d57eca040c0ea182301321286", + "sha256:6bc66318fb7ee012071b2792024564973ecc80e9522842eb4e17743604b5e045", + "sha256:7bfe2388663fd18bd8ce7db2c91c7400bf3e1a9e8bd7d63bf7e77d39051b85ec", + "sha256:7ec335fc998faa4febe75cc5268a9eac0478b3f681602c1f27befaf2a1abe1d8", + "sha256:914474c9f1d93080338ace89cb2acee74f4f666fb0424896fcfb8d86058bf17c", + "sha256:b568f35ad53a7b07ed9b1b2bae09eb15cdd671a5ba5d2c66caee40dbf91c68ca", + "sha256:cdfd2c361b8a8e5d9499b9082b501c452ade8bbf42aef97ea04854f4a3f43b22", + "sha256:d1b96547410f76078eaf66d282ddca2e4baae8964364abb4f4dcdde855cd123a", + "sha256:d4d61f8b993a7255ba714df3aca52700f8125289f84f704cf80916517c46eb96", + "sha256:d7a096646eab884bf8bed965bad63ea327e0d0c38989fc83c5ea7b8a87037bfc", + "sha256:df46c854f490f81210870e509818b729db4488e1f30f2a1ce1698b2295a878d1", + "sha256:e24a828f57e0c337c8d8bb9f6b12f09dfdf0273da25fda9e314f0b684b415a07", + "sha256:e4f3149fd5eb9b285d6bfb54d2e5173f6a116fe19172686797c056672689daf6", + "sha256:e92a52c166426efbe0d1ec1332ee9119b6d32fc1f0bbfd55d5c1088070e7fc1b", + "sha256:f87cc2863ef33c709e237d4b5f4502a62a00fab450c9e020892e8e2ede5847f5", + "sha256:fd8da6d0124efa2f67d86fa70c851022f87c98e205f0594e1fae044e7119a5a6" + ], + "markers": "python_version >= '3.7'", + "version": "==0.18.1" + }, + "pytest": { + "hashes": [ + "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89", + "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134" + ], + "markers": "python_version >= '3.6'", + "version": "==6.2.5" + }, + "pytest-forked": { + "hashes": [ + "sha256:8b67587c8f98cbbadfdd804539ed5455b6ed03802203485dd2f53c1422d7440e", + "sha256:bbbb6717efc886b9d64537b41fb1497cfaf3c9601276be8da2cccfea5a3c8ad8" + ], + "markers": "python_version >= '3.6'", + "version": "==1.4.0" + }, + "pytest-xdist": { + "hashes": [ + "sha256:340e8e83e2a4c0d861bdd8d05c5d7b7143f6eea0aba902997db15c2a86be04ee", + "sha256:ba5d10729372d65df3ac150872f9df5d2ed004a3b0d499cc0164aafedd8c7b66" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==1.34.0" + }, + "python-dateutil": { + "hashes": [ + "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", + "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "version": "==2.8.1" + }, + "python-dotenv": { + "hashes": [ + "sha256:31d752f5b748f4e292448c9a0cac6a08ed5e6f4cefab85044462dcad56905cec", + "sha256:9fa413c37d4652d3fa02fea0ff465c384f5db75eab259c4fc5d0c5b8bf20edd4" + ], + "version": "==0.16.0" + }, + "pythx": { + "hashes": [ + "sha256:44cb6c88f5213a3dd516e8322dbd17551fc7d435dc6290d3a6145333258d901f", + "sha256:7758a00125d5ba96d902bd2c79c1b1d10713a86479dc4f9ea7febc2337ff1eca" + ], + "version": "==1.6.1" + }, + "pyyaml": { + "hashes": [ + "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf", + "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696", + "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393", + "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77", + "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922", + "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5", + "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8", + "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10", + "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc", + "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018", + "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e", + "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253", + "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347", + "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183", + "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541", + "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb", + "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185", + "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc", + "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db", + "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa", + "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46", + "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122", + "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b", + "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63", + "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df", + "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc", + "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247", + "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6", + "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", + "version": "==5.4.1" + }, + "requests": { + "hashes": [ + "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983", + "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349" + ], + "markers": "python_version >= '3.7' and python_version < '4'", + "version": "==2.28.1" + }, + "rlp": { + "hashes": [ + "sha256:52a57c9f53f03c88b189283734b397314288250cc4a3c4113e9e36e2ac6bdd16", + "sha256:665e8312750b3fc5f7002e656d05b9dcb6e93b6063df40d95c49ad90c19d1f0e" + ], + "version": "==2.0.1" + }, + "semantic-version": { + "hashes": [ + "sha256:bdabb6d336998cbb378d4b9db3a4b56a1e3235701dc05ea2690d9a997ed5041c", + "sha256:de78a3b8e0feda74cabc54aab2da702113e33ac9d9eb9d2389bcf1f58b7d9177" + ], + "markers": "python_version >= '2.7'", + "version": "==2.10.0" + }, + "six": { + "hashes": [ + "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", + "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "version": "==1.16.0" + }, + "sortedcontainers": { + "hashes": [ + "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88", + "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0" + ], + "version": "==2.4.0" + }, + "toml": { + "hashes": [ + "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", + "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" + ], + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'", + "version": "==0.10.2" + }, + "tomli": { + "hashes": [ + "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", + "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" + ], + "markers": "python_full_version < '3.11.0a7'", + "version": "==2.0.1" + }, + "toolz": { + "hashes": [ + "sha256:2059bd4148deb1884bb0eb770a3cde70e7f954cfbbdc2285f1f2de01fd21eb6f", + "sha256:88c570861c440ee3f2f6037c4654613228ff40c93a6c25e0eba70d17282c6194" + ], + "markers": "python_version >= '3.5'", + "version": "==0.12.0" + }, + "tqdm": { + "hashes": [ + "sha256:5f4f682a004951c1b450bc753c710e9280c5746ce6ffedee253ddbcbf54cf1e4", + "sha256:6fee160d6ffcd1b1c68c65f14c829c22832bc401726335ce92c52d395944a6a1" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==4.64.1" + }, + "urllib3": { + "hashes": [ + "sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e", + "sha256:b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' and python_version < '4'", + "version": "==1.26.12" + }, + "varint": { + "hashes": [ + "sha256:a6ecc02377ac5ee9d65a6a8ad45c9ff1dac8ccee19400a5950fb51d594214ca5" + ], + "version": "==1.0.2" + }, + "vvm": { + "hashes": [ + "sha256:814c67bc8049d45ea8049bc26b04ce4065015f5a3e2896a1a2a2a44ab6e85edc", + "sha256:a1474915b12e0084299d2c7fe7d72434fa99c00ebb117e400756a5d7e0edac2a" + ], + "markers": "python_version >= '3.6' and python_version < '4'", + "version": "==0.1.0" + }, + "vyper": { + "hashes": [ + "sha256:1874eff683b7034ac376547d566d29fd05780bcec9f875c3d9615a9efc82636a", + "sha256:9432db96db9d685ce74423b2bf685b0bcefa7bec39589036cd52bb1635fc1800" + ], + "markers": "python_version < '3.11' and python_version >= '3.7'", + "version": "==0.3.7" + }, + "wcwidth": { + "hashes": [ + "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784", + "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83" + ], + "version": "==0.2.5" + }, + "web3": { + "hashes": [ + "sha256:74732fbd4b2e2baff9d0ac61f268b3e7b25b09ca6572d619390a9d782c2289f2", + "sha256:9c2e72688a5b35881062ef4f9da01c4a1e922afeb3134cfc92f6b4b95bb7df06" + ], + "markers": "python_version >= '3.6' and python_version < '4'", + "version": "==5.31.1" + }, + "websockets": { + "hashes": [ + "sha256:0dd4eb8e0bbf365d6f652711ce21b8fd2b596f873d32aabb0fbb53ec604418cc", + "sha256:1d0971cc7251aeff955aa742ec541ee8aaea4bb2ebf0245748fbec62f744a37e", + "sha256:1d6b4fddb12ab9adf87b843cd4316c4bd602db8d5efd2fb83147f0458fe85135", + "sha256:230a3506df6b5f446fed2398e58dcaafdff12d67fe1397dff196411a9e820d02", + "sha256:276d2339ebf0df4f45df453923ebd2270b87900eda5dfd4a6b0cfa15f82111c3", + "sha256:2cf04601633a4ec176b9cc3d3e73789c037641001dbfaf7c411f89cd3e04fcaf", + "sha256:3ddff38894c7857c476feb3538dd847514379d6dc844961dc99f04b0384b1b1b", + "sha256:48c222feb3ced18f3dc61168ca18952a22fb88e5eb8902d2bf1b50faefdc34a2", + "sha256:51d04df04ed9d08077d10ccbe21e6805791b78eac49d16d30a1f1fe2e44ba0af", + "sha256:597c28f3aa7a09e8c070a86b03107094ee5cdafcc0d55f2f2eac92faac8dc67d", + "sha256:5c8f0d82ea2468282e08b0cf5307f3ad022290ed50c45d5cb7767957ca782880", + "sha256:7189e51955f9268b2bdd6cc537e0faa06f8fffda7fb386e5922c6391de51b077", + "sha256:7df3596838b2a0c07c6f6d67752c53859a54993d4f062689fdf547cb56d0f84f", + "sha256:826ccf85d4514609219725ba4a7abd569228c2c9f1968e8be05be366f68291ec", + "sha256:836d14eb53b500fd92bd5db2fc5894f7c72b634f9c2a28f546f75967503d8e25", + "sha256:85db8090ba94e22d964498a47fdd933b8875a1add6ebc514c7ac8703eb97bbf0", + "sha256:85e701a6c316b7067f1e8675c638036a796fe5116783a4c932e7eb8e305a3ffe", + "sha256:900589e19200be76dd7cbaa95e9771605b5ce3f62512d039fb3bc5da9014912a", + "sha256:9147868bb0cc01e6846606cd65cbf9c58598f187b96d14dd1ca17338b08793bb", + "sha256:9e7fdc775fe7403dbd8bc883ba59576a6232eac96dacb56512daacf7af5d618d", + "sha256:ab5ee15d3462198c794c49ccd31773d8a2b8c17d622aa184f669d2b98c2f0857", + "sha256:ad893d889bc700a5835e0a95a3e4f2c39e91577ab232a3dc03c262a0f8fc4b5c", + "sha256:b2e71c4670ebe1067fa8632f0d081e47254ee2d3d409de54168b43b0ba9147e0", + "sha256:b43b13e5622c5a53ab12f3272e6f42f1ce37cd5b6684b2676cb365403295cd40", + "sha256:b4ad84b156cf50529b8ac5cc1638c2cf8680490e3fccb6121316c8c02620a2e4", + "sha256:be5fd35e99970518547edc906efab29afd392319f020c3c58b0e1a158e16ed20", + "sha256:caa68c95bc1776d3521f81eeb4d5b9438be92514ec2a79fececda814099c8314", + "sha256:d144b350045c53c8ff09aa1cfa955012dd32f00c7e0862c199edcabb1a8b32da", + "sha256:d2c2d9b24d3c65b5a02cac12cbb4e4194e590314519ed49db2f67ef561c3cf58", + "sha256:e9e5fd6dbdf95d99bc03732ded1fc8ef22ebbc05999ac7e0c7bf57fe6e4e5ae2", + "sha256:ebf459a1c069f9866d8569439c06193c586e72c9330db1390af7c6a0a32c4afd", + "sha256:f31722f1c033c198aa4a39a01905951c00bd1c74f922e8afc1b1c62adbcdd56a", + "sha256:f68c352a68e5fdf1e97288d5cec9296664c590c25932a8476224124aaf90dbcd" + ], + "markers": "python_full_version >= '3.6.1'", + "version": "==9.1" + }, + "wheel": { + "hashes": [ + "sha256:4bdcd7d840138086126cd09254dc6195fb4fc6f01c050a1d7236f2630db1d22a", + "sha256:e9a504e793efbca1b8e0e9cb979a249cf4a0a7b5b8c9e8b65a5e39d49529c1c4" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==0.37.1" + }, + "wrapt": { + "hashes": [ + "sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3", + "sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b", + "sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4", + "sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2", + "sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656", + "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3", + "sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff", + "sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310", + "sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a", + "sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57", + "sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069", + "sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383", + "sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe", + "sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87", + "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d", + "sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b", + "sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907", + "sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f", + "sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0", + "sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28", + "sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1", + "sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853", + "sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc", + "sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3", + "sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3", + "sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164", + "sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1", + "sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c", + "sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1", + "sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7", + "sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1", + "sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320", + "sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed", + "sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1", + "sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248", + "sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c", + "sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456", + "sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77", + "sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef", + "sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1", + "sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7", + "sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86", + "sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4", + "sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d", + "sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d", + "sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8", + "sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5", + "sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471", + "sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00", + "sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68", + "sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3", + "sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d", + "sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735", + "sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d", + "sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569", + "sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7", + "sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59", + "sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5", + "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb", + "sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b", + "sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f", + "sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462", + "sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015", + "sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==1.14.1" + }, + "yarl": { + "hashes": [ + "sha256:076eede537ab978b605f41db79a56cad2e7efeea2aa6e0fa8f05a26c24a034fb", + "sha256:07b21e274de4c637f3e3b7104694e53260b5fc10d51fb3ec5fed1da8e0f754e3", + "sha256:0ab5a138211c1c366404d912824bdcf5545ccba5b3ff52c42c4af4cbdc2c5035", + "sha256:0c03f456522d1ec815893d85fccb5def01ffaa74c1b16ff30f8aaa03eb21e453", + "sha256:12768232751689c1a89b0376a96a32bc7633c08da45ad985d0c49ede691f5c0d", + "sha256:19cd801d6f983918a3f3a39f3a45b553c015c5aac92ccd1fac619bd74beece4a", + "sha256:1ca7e596c55bd675432b11320b4eacc62310c2145d6801a1f8e9ad160685a231", + "sha256:1e4808f996ca39a6463f45182e2af2fae55e2560be586d447ce8016f389f626f", + "sha256:205904cffd69ae972a1707a1bd3ea7cded594b1d773a0ce66714edf17833cdae", + "sha256:20df6ff4089bc86e4a66e3b1380460f864df3dd9dccaf88d6b3385d24405893b", + "sha256:21ac44b763e0eec15746a3d440f5e09ad2ecc8b5f6dcd3ea8cb4773d6d4703e3", + "sha256:29e256649f42771829974e742061c3501cc50cf16e63f91ed8d1bf98242e5507", + "sha256:2d800b9c2eaf0684c08be5f50e52bfa2aa920e7163c2ea43f4f431e829b4f0fd", + "sha256:2d93a049d29df172f48bcb09acf9226318e712ce67374f893b460b42cc1380ae", + "sha256:31a9a04ecccd6b03e2b0e12e82131f1488dea5555a13a4d32f064e22a6003cfe", + "sha256:3d1a50e461615747dd93c099f297c1994d472b0f4d2db8a64e55b1edf704ec1c", + "sha256:449c957ffc6bc2309e1fbe67ab7d2c1efca89d3f4912baeb8ead207bb3cc1cd4", + "sha256:4a88510731cd8d4befaba5fbd734a7dd914de5ab8132a5b3dde0bbd6c9476c64", + "sha256:4c322cbaa4ed78a8aac89b2174a6df398faf50e5fc12c4c191c40c59d5e28357", + "sha256:5395da939ffa959974577eff2cbfc24b004a2fb6c346918f39966a5786874e54", + "sha256:5587bba41399854703212b87071c6d8638fa6e61656385875f8c6dff92b2e461", + "sha256:56c11efb0a89700987d05597b08a1efcd78d74c52febe530126785e1b1a285f4", + "sha256:5999c4662631cb798496535afbd837a102859568adc67d75d2045e31ec3ac497", + "sha256:59ddd85a1214862ce7c7c66457f05543b6a275b70a65de366030d56159a979f0", + "sha256:6347f1a58e658b97b0a0d1ff7658a03cb79bdbda0331603bed24dd7054a6dea1", + "sha256:6628d750041550c5d9da50bb40b5cf28a2e63b9388bac10fedd4f19236ef4957", + "sha256:6afb336e23a793cd3b6476c30f030a0d4c7539cd81649683b5e0c1b0ab0bf350", + "sha256:6c8148e0b52bf9535c40c48faebb00cb294ee577ca069d21bd5c48d302a83780", + "sha256:76577f13333b4fe345c3704811ac7509b31499132ff0181f25ee26619de2c843", + "sha256:7c0da7e44d0c9108d8b98469338705e07f4bb7dab96dbd8fa4e91b337db42548", + "sha256:7de89c8456525650ffa2bb56a3eee6af891e98f498babd43ae307bd42dca98f6", + "sha256:7ec362167e2c9fd178f82f252b6d97669d7245695dc057ee182118042026da40", + "sha256:7fce6cbc6c170ede0221cc8c91b285f7f3c8b9fe28283b51885ff621bbe0f8ee", + "sha256:85cba594433915d5c9a0d14b24cfba0339f57a2fff203a5d4fd070e593307d0b", + "sha256:8b0af1cf36b93cee99a31a545fe91d08223e64390c5ecc5e94c39511832a4bb6", + "sha256:9130ddf1ae9978abe63808b6b60a897e41fccb834408cde79522feb37fb72fb0", + "sha256:99449cd5366fe4608e7226c6cae80873296dfa0cde45d9b498fefa1de315a09e", + "sha256:9de955d98e02fab288c7718662afb33aab64212ecb368c5dc866d9a57bf48880", + "sha256:a0fb2cb4204ddb456a8e32381f9a90000429489a25f64e817e6ff94879d432fc", + "sha256:a165442348c211b5dea67c0206fc61366212d7082ba8118c8c5c1c853ea4d82e", + "sha256:ab2a60d57ca88e1d4ca34a10e9fb4ab2ac5ad315543351de3a612bbb0560bead", + "sha256:abc06b97407868ef38f3d172762f4069323de52f2b70d133d096a48d72215d28", + "sha256:af887845b8c2e060eb5605ff72b6f2dd2aab7a761379373fd89d314f4752abbf", + "sha256:b19255dde4b4f4c32e012038f2c169bb72e7f081552bea4641cab4d88bc409dd", + "sha256:b3ded839a5c5608eec8b6f9ae9a62cb22cd037ea97c627f38ae0841a48f09eae", + "sha256:c1445a0c562ed561d06d8cbc5c8916c6008a31c60bc3655cdd2de1d3bf5174a0", + "sha256:d0272228fabe78ce00a3365ffffd6f643f57a91043e119c289aaba202f4095b0", + "sha256:d0b51530877d3ad7a8d47b2fff0c8df3b8f3b8deddf057379ba50b13df2a5eae", + "sha256:d0f77539733e0ec2475ddcd4e26777d08996f8cd55d2aef82ec4d3896687abda", + "sha256:d2b8f245dad9e331540c350285910b20dd913dc86d4ee410c11d48523c4fd546", + "sha256:dd032e8422a52e5a4860e062eb84ac94ea08861d334a4bcaf142a63ce8ad4802", + "sha256:de49d77e968de6626ba7ef4472323f9d2e5a56c1d85b7c0e2a190b2173d3b9be", + "sha256:de839c3a1826a909fdbfe05f6fe2167c4ab033f1133757b5936efe2f84904c07", + "sha256:e80ed5a9939ceb6fda42811542f31c8602be336b1fb977bccb012e83da7e4936", + "sha256:ea30a42dc94d42f2ba4d0f7c0ffb4f4f9baa1b23045910c0c32df9c9902cb272", + "sha256:ea513a25976d21733bff523e0ca836ef1679630ef4ad22d46987d04b372d57fc", + "sha256:ed19b74e81b10b592084a5ad1e70f845f0aacb57577018d31de064e71ffa267a", + "sha256:f5af52738e225fcc526ae64071b7e5342abe03f42e0e8918227b38c9aa711e28", + "sha256:fae37373155f5ef9b403ab48af5136ae9851151f7aacd9926251ab26b953118b" + ], + "markers": "python_version >= '3.7'", + "version": "==1.8.1" + } + }, + "develop": {} +} diff --git a/README.md b/README.md index e2d9e76..34c0bf7 100755 --- a/README.md +++ b/README.md @@ -1,18 +1,24 @@ # currency + Smart-contract templates for com-chain hosted currency -Those are free and open-source Smartcontracts to run an ethereum token based currency and barter system. -It was created and by Florian and Dominique on behalf of Monnaie Leman the Leman Lake Local Currency. Then maintained and used as templates for the other currency hosted by Com-Chain (see com-chain.org) +Those are free and open-source Smartcontracts to run an ethereum token +based currency and barter system. It was created and by Florian and +Dominique on behalf of Monnaie Leman the Leman Lake Local +Currency. Then maintained and used as templates for the other currency +hosted by Com-Chain (see com-chain.org) ## Features The smartContracts permit to do : + - Payments - Reverse Payment - Automatic approval of reverse payment - Payement on behalf of an other user Account management includes: + - Account activation/inactivation - Changing account type - Setting barter limits @@ -20,19 +26,93 @@ Account management includes: ## Configuration -- If you are planning to use the contract withing the Com-Chain framework, you must keep the function signature. -- Unused function can have their body replaced by a revert() statment. -- You should choose in the pledge function between two check: one is checking for overflow, the second also check for non-negative pledge. +- If you are planning to use the contract within the Com-Chain + framework, you must keep the function signature. + +- Unused function can have their body replaced by a revert() statement. + +- You should choose in the pledge function between two check: one is + checking for overflow, the second also check for non-negative + pledge. ## Our Philosophy -- Empower the people: Give people the ability to interact with the Ethereum blockchain easily, without having to run a full node. +- Empower the people: Give people the ability to interact with the + Ethereum blockchain easily, without having to run a full node. -- Make it easy & free: Everyone should be able to create a wallet and send Tokens without additional cost. -People are the Priority: People are the most important. +- Make it easy & free: Everyone should be able to create a wallet and + send Tokens without additional cost. People are the Priority: + People are the most important. -- If it can be hacked, it will be hacked: Never save, store, or transmit secret info, like passwords or keys. Open source & auditable. +- If it can be hacked, it will be hacked: Never save, store, or + transmit secret info, like passwords or keys. Open source & + auditable. ## Contact -If you can think of any other features or run into bugs, let us know. You can drop a line at it {at} monnaie {-} leman dot org. +If you can think of any other features or run into bugs, let us +know. You can drop a line at it {at} monnaie {-} leman dot org. + +## Install for developpement + +You should ensure you have a working `pipenv` [installed on your +system](https://github.com/pypa/pipenv#installation). + +First, clone this source code, and from the root of the project, run: + +```shell +pipenv install ## only to be run the first time +``` + +This will gather python dependency to setup `brownie`. + +## Usage + +Remember to hop into the python local environment before using `brownie`: + +```shell +pipenv shell ## from root of the project +``` + +## Test + +Run the tests with: + +```shell +brownie test +``` + +## Get the signatures of the functions + +You must compile first with: + +```shell +brownie compile +``` + +Then this will provide the list of all signatures + +```shell +cat build/contracts/cccur.json | + jq '.abi[] | select(.name != null) | + ( .name + "(" + ([ .inputs[].type ] | join(",")) + ")" )' +``` + +To provide the ethereum selector with the signature, you could: + +```shell + cat build/contracts/cccur.json | + jq -r '.abi[] | select(.name != null) | + ( .name + "(" + ([ .inputs[].type ] | join(",")) + ")" )' | + while read sig; do + echo "$sig:$(selector "$sig")" + done | sort > hashes +``` + +This will produce a `hashes` file in your current directory that you +can compare for `hashes.legacy`, the hashes of the legacy comchain +smartcontract. For instance: + +```shell +diff -u0 hashes.legacy hashes | grep -v '^@' | tail -n +3 +``` \ No newline at end of file diff --git a/currency.sol b/contracts/currency.sol similarity index 55% rename from currency.sol rename to contracts/currency.sol index 1f5f013..7a4c554 100755 --- a/currency.sol +++ b/contracts/currency.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.18; +pragma solidity >=0.4.18 <0.4.23; /******************************************************** @@ -13,7 +13,7 @@ The following functionality are implemented (details in the code): - Payement on behalf of an other user -Configuration: +Configuration: - pledge function: you have to define if it is possible to pledge negative amount by switchng between the two "check for overflow" lines @@ -30,31 +30,34 @@ contract owned { constructor() public{ owner = msg.sender; } - + function isOwner(address _user) public constant returns (bool) { return _user==owner; } modifier onlyOwner { - if (msg.sender != owner) revert(); + if (msg.sender != owner) + revert(); // dev: require to be owner _; } } /*********************************************** - Main contract. + Main contract. ***********************************************/ -contract _template_ is owned { +contract cccur is owned { /* Name and symbol (for ComChain internal use) */ - string public standard = '_template_'; - string public name = "_name_"; - string public symbol = "_symbol_"; - + string public name = ""; + string public symbol = ""; + string public version = "2.1"; + /* Total amount pledged (Money supply) */ int256 public amountPledged = 0; - + + bool public automaticUnlock = false; + /* Tax on the transactions */ /* payed to "Person" (0) account */ int16 public percent = 0; @@ -65,48 +68,55 @@ contract _template_ is owned { /* Ensure that the accounts have enough ether to pass transactions */ /* For this it define the limit bellow which ether is added to the account */ - uint256 minBalanceForAccounts = 1000000000000000000; - /* And the number of ether to be added */ - uint256 public refillSupply = 2; - - /* Panic button: allows to block any currency transfert */ + uint256 minBalanceForAccounts = 1 ether /100; + /* And the number of ether to be added */ + uint256 public refillSupply = 10; + + /* Panic button: allows to block any currency transfer */ bool public actif = true; - + /* For initialization purpose: */ bool firstAdmin = true; /* Account property: */ - mapping (address => int256) public accountType; // Account type 2 = special account 1 = Business 0 = Personal + mapping (address => int256) public accountType; // Account type 4 = Property Admin, 3 = Pledge Admin, 2 = Super Admin, 1 = Business, 0 = Personal mapping (address => bool) public accountStatus; // Account status + mapping (address => bool) public accountAlreadyUsed; // if False the account is new mapping (address => int256) public balanceEL; // Balance in coins mapping (address => int256) public balanceCM; // Balance in Mutual credit mapping (address => int256) public limitCredit; // Min limit (minimal accepted CM amount expected to be 0 or <0 ) mapping (address => int256) public limitDebit; // Max limit (maximal accepted CM amount expected to be 0 or >0 ) - + mapping (address => address) public requestReplacementFrom; // Pending replacement request the key is the Account to be replaced + mapping (address => address) public newAddress; // Address which replaces the current one + + + /* Transfert limitation */ + mapping(int256 => mapping(int256 => bool)) public preventTransferRules; // set which account type can pay to which account type + /* Allowance, Authorization and Request:*/ - + mapping (address => mapping (address => int256)) public allowed; // Array of allowed payements mapping (address => address[]) public allowMap; - + mapping (address => mapping (address => int256)) public requested; // Array of requested payments mapping (address => address[]) public reqMap; - + mapping (address => mapping (address => int256)) public delegated; // Array of authorized accounts mapping (address => address[]) public delegMap; - + mapping (address => mapping (address => int256)) public myAllowed; // Array of allowed payements mapping (address => address[]) public myAllowMap; - + mapping (address => mapping (address => int256)) public myRequested; // Array of requested payments mapping (address => address[]) public myReqMap; - + mapping (address => mapping (address => int256)) public myDelegated; // Array of authorized accounts mapping (address => address[]) public myDelegMap; - + /* Keep trace of accepted / rejected payment requests */ mapping (address => mapping (address => int256)) accepted; // Array of requested payments accepted mapping (address => address[]) public acceptedMap; - + mapping (address => mapping (address => int256)) rejected; // Array of requested payments rejected mapping (address => address[]) public rejectedMap; @@ -116,57 +126,67 @@ contract _template_ is owned { event CreditLimitChange(uint256 time, address target, int256 amount); event DebitLimitChange(uint256 time, address target, int256 amount); event Refilled(uint256 time, address target, uint256 balance, uint256 limit); - - /* Token transfert */ - event Pledge(uint256 time, address indexed to, int256 recieved); - event Transfer(uint256 time, address indexed from, address indexed to, int256 sent, int256 tax, int256 recieved); - event TransferCredit(uint256 time, address indexed from, address indexed to, int256 sent, int256 tax, int256 recieved); - + + /* Token transfer */ + event Pledge(uint256 time, address indexed to, int256 received); + event Transfer(uint256 time, address indexed from, address indexed to, int256 sent, int256 tax, int256 received); + event TransferCredit(uint256 time, address indexed from, address indexed to, int256 sent, int256 tax, int256 received); + /* Allowance and Authorization*/ event Approval(uint256 time, address indexed from, address indexed to, int256 value); event Delegation(uint256 time, address indexed from, address indexed to, int256 value); - + event Rejection(uint256 time, address indexed from, address indexed to, int256 value); - /****************************************************************************/ + /* Account being replaced by a new one */ + event AccountReplaced(uint256 time, address indexed oldAdd, address indexed newAdd, int256 indexed accstatus); + + /****************************************************************************/ /***** Contract creation *******/ /* Initializes contract */ - constructor(address taxAddress, int8 taxPercent, int8 taxPercentLeg) public { - txAddr = taxAddress; - percent = taxPercent; - percentLeg = taxPercentLeg; + constructor(string _name, string _symbol) public { + txAddr = msg.sender; + name = _name; + symbol = _symbol; setFirstAdmin(); } - - /* INTERNAL - Set the first admin and ensure that this account is of the good type and actif.*/ + + /* INTERNAL - Set the first super admin (2) and ensure that this account is of the good type and actif.*/ function setFirstAdmin() internal { if (firstAdmin == false) revert(); accountType[owner] = 2; accountStatus[owner] = true; + use(owner); firstAdmin = false; } - + /***** Ether handling *******/ - /* The contract dispatch Eth to the account: it must be able to recieve them */ - function () public payable{} + /* The contract dispatch Eth to the account: it must be able to receive them */ + function () public payable {} /* In the case we need to retrieve Eth from the contract. Sent it back to the Owner */ function repay(uint _amount) public onlyOwner { uint amount = _amount * 1 ether; - owner.transfer(amount); + owner.transfer(amount); } /***** Contract administration *******/ - /* Transfert ownership */ + /* Transfer ownership */ function transferOwnership(address newOwner) public onlyOwner { accountType[newOwner] = 2; accountStatus[newOwner] = true; + use(newOwner); owner = newOwner; } - - /* Set the threshold to refill an account (in ETH)*/ + + /* Manage the Automatic Unlock */ + function setAutomaticUnlock(bool newAutomaticUnlock) public onlyOwner { + automaticUnlock = newAutomaticUnlock; + } + + /* Set the threshold to refill an account (in 0.001 ETH - initial contract value is same as calling this function with 10)*/ function setRefillLimit(uint256 _minimumBalance) public onlyOwner { - minBalanceForAccounts = _minimumBalance * 1 ether; + minBalanceForAccounts = _minimumBalance * 1 ether / 1000; } /* Get the total amount of coin (Money supply) */ @@ -174,26 +194,31 @@ contract _template_ is owned { total = amountPledged; } - /* Panic button: allows to block any currency transfert */ + /* Panic button: allows to block any currency transfer */ function setContractStatus(bool _actif) public onlyOwner { actif=_actif; } - + + /* Manage the transfert rule */ + function setPreventTransferRules(int256 _senderType,int256 _recieverType, bool _newPreventTransferRules) public onlyOwner { + preventTransferRules[_senderType][_recieverType]=_newPreventTransferRules; + } + /* INTERNAL - Top up function: Check that an account has enough ETH if not send some to it */ function topUp(address _addr) internal { - uint amount = refillSupply * 1 ether; + uint amount = refillSupply * minBalanceForAccounts; if (_addr.balance < minBalanceForAccounts){ if(_addr.send(amount)) { emit Refilled(now, _addr, _addr.balance, minBalanceForAccounts); } } } - + /* INTERNAL - Call the Top up function for the message sender */ function refill() internal { topUp(msg.sender); } - + /****** Tax handling *******/ /* Get the account to which the tax is paid */ function getTaxAccount() public constant returns (address) { @@ -204,7 +229,7 @@ contract _template_ is owned { function setTaxAccount(address _target) public onlyOwner { txAddr = _target; } - + /* Get the tax percentage for transaction to a person (0) account */ function getTaxPercent() public constant returns (int16) { return percent; @@ -212,73 +237,399 @@ contract _template_ is owned { /* Set the tax percentage for transaction to a person (0) account */ function setTaxPercent(int16 _value) public onlyOwner { - if (_value < 0) revert(); - if (_value > 10000) revert(); + if (_value < 0) + revert(); // dev: amount should be greater than 0 + if (_value > 10000) + revert(); // dev: amount should be lower than 10000 percent = _value; } - + /* Get the tax percentage for transaction to a buisness (1) account */ function getTaxPercentLeg() public constant returns (int16) { return percentLeg; } - - /* Set the tax percentage for transaction to a buisness (1) account */ + + /* Set the tax percentage for transaction to a buisness (1) account */ function setTaxPercentLeg(int16 _value) public onlyOwner { - if (_value < 0) revert(); - if (_value > 10000) revert(); + if (_value < 0) + revert(); // dev: amount should be greater than 0 + if (_value > 10000) + revert(); // dev: amount should be lower than 10000 percentLeg = _value; } - + /****** Account handling *******/ /* Get the total balance of an account */ function balanceOf(address _from) public constant returns (int256 amount){ return balanceEL[_from] + balanceCM[_from]; } - - /* Change account's property */ + + function isActive(address target) public constant returns (bool result) { + if (requestReplacementFrom[msg.sender] != address(0)) + return false; + if (accountStatus[target]) { + return true; + } else if (automaticUnlock && !accountAlreadyUsed[target]) { + return true; + } else { + return false; + } + } + + /* change the accountAlreadyUsed */ + function use(address add) internal { + // unlock if needed + if (automaticUnlock && !accountAlreadyUsed[add]) { + accountStatus[add] = true; + } + + accountAlreadyUsed[add] = true; + } + + /* Change account's property */ function setAccountParams(address _targetAccount, bool _accountStatus, int256 _accountType, int256 _debitLimit, int256 _creditLimit) public { - - // Ensure that the sender is an admin and is not blocked + + // Ensure that the sender is a super admin or a property admin and is not blocked if (msg.sender!=owner){ - if (accountType[msg.sender] < 2 || !accountStatus[msg.sender]) revert(); + if (accountType[msg.sender] < 2 || accountType[msg.sender] == 3) + revert(); // dev: permission denied + if (!accountStatus[msg.sender]) + revert(); // dev: disabled accounts can't set account params } - + + if (newAddress[_targetAccount] != address(0)) + revert(); // dev: replaced account cannot be modified + accountStatus[_targetAccount] = _accountStatus; - - // Prevent changing the Type of an Admin (2) account + + // Prevent changing the Type of a super Admin (2) account if (accountType[_targetAccount] != 2){ limitDebit[_targetAccount] = _debitLimit; limitCredit[_targetAccount] = _creditLimit; - } - accountType[_targetAccount] = _accountType; - + + if (_targetAccount!=owner) { + accountType[_targetAccount] = _accountType; + } + + use(_targetAccount); + emit SetAccountParams(now, _targetAccount, _accountStatus, accountType[_targetAccount], limitDebit[_targetAccount], limitCredit[_targetAccount]); - + // ensure the ETH level of the account + refill(); topUp(_targetAccount); - topUp(msg.sender); } - - - /****** Coin and Barter transfert *******/ + + function allowReplaceBy(address target) public payable { + if (!actif) revert(); // dev: panic lock + if (newAddress[msg.sender] != address(0)) + revert(); // dev: already replaced account cannot be replaced again + if (!isActive(msg.sender)) + revert(); // dev: locked account cannot be replaced + if (accountAlreadyUsed[target] == true) + revert(); // dev: only new account can be target of a replacement + if (requestReplacementFrom[msg.sender] != address(0)) + revert(); // dev: replacement request ongoing from this account + + requestReplacementFrom[msg.sender] = target; // register the request + + topUp(target); // ensure targuet has eth to accept the request + } + + function CancelReplaceBy() public { + if (!actif) revert(); // dev: panic lock + if (requestReplacementFrom[msg.sender] == address(0)) + revert(); // dev: no replacement request ongoing to cancel + + requestReplacementFrom[msg.sender] = address(0); + refill(); + } + + + /* replace the current account by a new one transfering its content */ + function acceptReplaceAccount(address original_account) public { + if (!actif) revert(); // dev: panic lock + if (requestReplacementFrom[original_account] != msg.sender) + revert(); // dev: replacement request not initiated + if (accountAlreadyUsed[msg.sender] == true // only new account can be a replacement target + || newAddress[original_account] != address(0) // already replaced account cannot be replaced again + || !isActive(original_account)) { // locked account cannot be replaced + // YYYvlab: if it is already address(0) ? + requestReplacementFrom[original_account] = address(0); // cancel the outdated request + } else { + // transfert the type (and ownership if needed) + use(msg.sender); + accountStatus[msg.sender] = true; + if (original_account == owner) { // if the replaced account is the contract owner transfert the priviledge + accountType[msg.sender] = 2; + owner = msg.sender; + } else { + accountType[msg.sender] = accountType[original_account]; + } + + // transfert the values and limit + balanceEL[msg.sender] = balanceEL[original_account]; + balanceEL[original_account] = 0; + balanceCM[msg.sender] = balanceCM[original_account]; + balanceCM[original_account] = 0; + limitCredit[msg.sender] = limitCredit[original_account]; + limitCredit[original_account] = 0; + limitDebit[msg.sender] = limitDebit[original_account]; + limitDebit[original_account] = 0; + + bool found = false; + uint ii=0; + // transfert the allowance from the replaced account + uint map_length = allowMap[original_account].length; + for (uint index=0; index 0) { + allowMap[msg.sender].push(spender); + myAllowMap[spender].push(msg.sender); + allowed[msg.sender][spender] = amount; + allowed[original_account][spender] = 0; + myAllowed[spender][msg.sender] = amount; + myAllowed[spender][original_account] = 0; + + found = false; + for (ii = 0; ii 0) { + allowMap[allower].push(msg.sender); + myAllowMap[msg.sender].push(allower); + allowed[allower][msg.sender] = amount; + allowed[allower][original_account] = 0; + myAllowed[msg.sender][allower] = amount; + myAllowed[original_account][allower] = 0; + + found = false; + for (ii = 0; ii 0) { + delegMap[msg.sender].push(delegate); + myDelegMap[delegate].push(msg.sender); + delegated[msg.sender][delegate] = amount; + delegated[original_account][delegate] = 0; + myDelegated[delegate][msg.sender] = amount; + myDelegated[delegate][original_account] = 0; + + found = false; + for (ii = 0; ii 0) { + delegMap[delegetor].push(msg.sender); + myDelegMap[msg.sender].push(delegetor); + delegated[delegetor][msg.sender] = amount; + delegated[delegetor][original_account] = 0; + myDelegated[msg.sender][delegetor] = amount; + myDelegated[original_account][delegetor] = 0; + + found = false; + for (ii = 0; ii 0) { + reqMap[msg.sender].push(debitor); + myReqMap[debitor].push(msg.sender); + requested[msg.sender][debitor] = amount; + requested[original_account][debitor] = 0; + myRequested[debitor][msg.sender] = amount; + myRequested[debitor][original_account] = 0; + + found = false; + for (ii = 0; ii 0) { + reqMap[requestor].push(msg.sender); + myReqMap[msg.sender].push(requestor); + requested[requestor][msg.sender] = amount; + requested[requestor][original_account] = 0; + myRequested[msg.sender][requestor] = amount; + myRequested[original_account][requestor] = 0; + + found = false; + for (ii = 0; ii 3) + revert(); // dev: permission denied + if (!isActive(msg.sender)) + revert(); // dev: disabled accounts can't pledge + if (!isActive(_to)) revert(); // dev: disabled accounts can't receive pledge + // if (balanceEL[_to] + _value < 0) revert(); // Check for overflows + if (balanceEL[_to] + _value < balanceEL[_to] ) revert(); // Check for overflows & avoid negative pledge + // if (newAddress[_to]!=address(0)) revert(); // Replaced account cannot be pledged balanceEL[_to] += _value; // Add the amount to the recipient amountPledged += _value; // and to the Money supply - + use(_to); + emit Pledge(now, _to, _value); // ensure the ETH level of the account + refill(); topUp(_to); - topUp(msg.sender); } - - + + /* Make Direct payment in currency*/ function transfer(address _to, int256 _value) public { payNant(msg.sender,_to,_value); @@ -288,26 +639,26 @@ contract _template_ is owned { function transferCM(address _to, int256 _value) public { payCM(msg.sender,_to,_value); } - - /* Transfert "on behalf of" of Coin and Mutual Credit (delegation) */ - /* Make Transfert "on behalf of" in coins*/ + + /* Transfer "on behalf of" of Coin and Mutual Credit (delegation) */ + /* Make Transfer "on behalf of" in coins*/ function transferOnBehalfOf(address _from, address _to, int256 _value)public { - if (delegated[_from][msg.sender] < _value) revert(); + if (delegated[_from][msg.sender] < _value) revert(); // dev: value bigger than the delegation payNant(_from,_to,_value); } - - /* Make Transfert "on behalf of" in Mutual Credit */ + + /* Make Transfer "on behalf of" in Mutual Credit */ function transferCMOnBehalfOf(address _from, address _to, int256 _value)public { - if (delegated[_from][msg.sender] < _value) revert(); + if (delegated[_from][msg.sender] < _value) revert(); // dev: value bigger than the delegation payCM(_from,_to,_value); } - /* Transfert request of Coin and Mutual Credit (delegation & pay request)*/ + /* Transfer request of Coin and Mutual Credit (delegation & pay request)*/ // Send _value Coin from address _from to the sender function transferFrom(address _from, int256 _value) public { if (allowed[_from][msg.sender] >= _value && balanceEL[_from]>=_value) { - payNant(_from, msg.sender,_value); - + payNant(_from, msg.sender,_value); + // substract the value from the allowed updateAllowed(_from, msg.sender, -_value); @@ -315,91 +666,98 @@ contract _template_ is owned { insertRequest(_from, msg.sender, _value); // if allowed is not enough (or do not exist) create a request } } - + // Send _value Mutual Credit from address _from to the sender function transferCMFrom(address _from, int256 _value) public { if (allowed[_from][msg.sender] >= _value && balanceCM[_from]>=_value) { payCM(_from, msg.sender,_value); - + // substract the value from the allowed updateAllowed(_from, msg.sender, -_value); - + } else { insertRequest(_from, msg.sender, _value); // if allowed is not enough (or do not exist) create a request } } - - - - - - /* INTERNAL - Coin transfert */ + + + + + + /* INTERNAL - Coin transfer */ function payNant(address _from,address _to, int256 _value) internal { - if (!actif) revert(); // panic lock - if (!accountStatus[_from]) revert(); //Check neither of the Account are locked - if (!accountStatus[_to]) revert(); - + if (!actif) revert(); // dev: panic lock + + if (!isActive(_from)) revert(); // dev: Source account is locked + if (!isActive(_to)) revert(); // dev: Target account is locked + + if (preventTransferRules[accountType[_from]][accountType[_to]]) revert(); // dev: This transaction is not autorized by the preventTransferRules + // compute the tax int16 tax_percent = percent; if (accountType[_to] == 1){ tax_percent = percentLeg; } int256 tax = (_value * tax_percent) / 10000; - - // compute the recieved ammount + + // compute the received ammount int256 amount = _value - tax; - if (!checkEL(_from, amount + tax)) revert(); // check coin availability - if (balanceEL[_to] + amount < balanceEL[_to]) revert(); //overflow check - - // Do the transfert + if (!checkEL(_from, amount + tax)) revert(); // dev: Not enough balance + if (balanceEL[_to] + amount < balanceEL[_to]) revert(); // dev: overflow and negative check + + // Do the transfer balanceEL[_from] -= amount + tax; // Subtract from the sender - balanceEL[_to] += amount; + balanceEL[_to] += amount; balanceEL[txAddr] += tax; - + + use(_to); emit Transfer(now, _from, _to, amount+tax, tax, amount); // Notify anyone listening that this transfer took place // ensure the ETH level of the account topUp(_to); topUp(_from); - } - - /* INTERNAL - Mutual Credit (Barter) transfert */ + } + + /* INTERNAL - Mutual Credit (Barter) transfer */ function payCM(address _from, address _to, int256 _value) internal { - if (!actif) revert(); // panic lock - if (!accountStatus[_from]) revert(); //Check neither of the Account are locked - if (!accountStatus[_to]) revert(); - + if (!actif) revert(); // dev: panic lock + if (!isActive(_from)) revert(); // dev: Source account is locked + if (!isActive(_to)) revert(); // dev: Target account is locked + + if (preventTransferRules[accountType[_from]][accountType[_to]]) revert(); // dev: This transaction is not autorized by the preventTransferRules + // compute the tax int16 tax_percent = percent; if (accountType[_to] == 1){ tax_percent = percentLeg; } int256 tax = (_value * tax_percent) / 10000; - - // compute the recieved ammount + + // compute the received ammount int256 amount = _value - tax; - + // Check the limit & overflow if (!checkCMMin(_from, amount + tax)) revert(); if (!checkCMMax(_to, amount)) revert(); - if (balanceCM[_to] + amount < balanceCM[_to]) revert(); //overflow check - - // Do the transfert + if (balanceCM[_to] + amount < balanceCM[_to]) revert(); // dev: overflow and negative check + + // Do the transfer balanceCM[_from] -= amount + tax; // Subtract from the sender - balanceCM[_to] += amount; + balanceCM[_to] += amount; balanceCM[txAddr] += tax; - + + use(_to); emit TransferCredit(now, _from, _to, amount+tax, tax, amount); // Notify anyone listening that this transfer took place // ensure the ETH level of the account topUp(_to); topUp(_from); } - - /* INTERNAL - Check the sender has enough coin to do the transfert */ + + /* INTERNAL - Check the sender has enough coin to do the transfer */ function checkEL(address _addr, int256 _value) internal view returns (bool) { int256 checkBalance = balanceEL[_addr] - _value; if (checkBalance < 0) { - revert(); + revert(); // dev: Not enough balance } else { return true; } @@ -410,29 +768,31 @@ contract _template_ is owned { int256 checkBalance = balanceCM[_addr] - _value; int256 limitCM = limitCredit[_addr]; if (checkBalance < limitCM) { - revert(); + revert(); // dev: Inferior credit limit hit } else { return true; } } - + /* INTERNAL - Check that the reciever can recieve the CM amount */ function checkCMMax(address _addr, int256 _value) internal view returns (bool) { int256 checkBalance = balanceCM[_addr] + _value; int256 limitCM = limitDebit[_addr]; if (checkBalance > limitCM) { - revert(); + revert(); // dev: Supperior credit limit hit } else { return true; } } - - /****** Allowance *******/ + + /****** Allowance *******/ /* Allow _spender to withdraw from your account, multiple times, up to the _value amount. */ /* If called again the _amount is added to the allowance, if amount is negatif the allowance is deleted */ function approve(address _spender, int256 _amount) public returns (bool success) { - if (!accountStatus[msg.sender]) revert(); // Check the sender not to be blocked + if (!isActive(msg.sender)) revert(); // dev: sender account not actif + + if (_amount>=0){ if ( allowed[msg.sender][_spender] == 0 ) { allowMap[msg.sender].push(_spender); @@ -447,58 +807,60 @@ contract _template_ is owned { if (!found && allowMap[msg.sender][i] == _spender){ found=true; } - + if (found){ if (i < allowMap[msg.sender].length-1){ allowMap[msg.sender][i] = allowMap[msg.sender][i+1]; } } } - + if (found){ delete allowMap[msg.sender][allowMap[msg.sender].length-1]; // remove the last record from the mapping array - allowMap[msg.sender].length--; // adjust the length of the mapping array + allowMap[msg.sender].length--; // adjust the length of the mapping array allowed[msg.sender][_spender] = 0; // remove the record from the mapping } - + // delete my allowance found = false; for (i = 0; i 0) revert(); // Ensure that the allowance cannot de augmented if (allowed[_from][_to] + _value < 0) revert(); // Ensure that the resulting allowance is not <0 - allowed[_from][_to] += _value; + allowed[_from][_to] += _value; topUp(_to); topUp(_from); } - + /* Count the number of allowances define on the _owner account */ function allowanceCount(address _owner) public constant returns (uint256){ return allowMap[_owner].length; @@ -506,9 +868,9 @@ contract _template_ is owned { /* Count the number of allowance that the _spender can use */ function myAllowanceCount(address _spender) public constant returns (uint256){ - return allowMap[_spender].length; + return myAllowMap[_spender].length; } - + /** list the allowances define on a given _owner account **/ function allowance(address _owner, address _spender) public constant returns (int256 remaining) { return allowed[_owner][_spender]; @@ -519,26 +881,23 @@ contract _template_ is owned { } - - - /** list the allowances that a _spender account can use **/ function myAllowance(address _spender, address _owner) public constant returns (int256 remaining) { - return allowed[_spender][_owner]; + return myAllowed[_spender][_owner]; } function myGetAllowance(address _spender, uint index) public constant returns (address _to) { - return allowMap[_spender][index]; + return myAllowMap[_spender][index]; } - - - /****** Delegation *******/ + + + /****** Delegation *******/ /* Allow _spender to pay on behalf of you from your account, multiple times, each transaction bellow the limit. */ /* If called again the limit is replaced by the new _amount, if _amount is 0 the delegation is removed */ function delegate(address _spender, int256 _amount) public { - if (!accountStatus[msg.sender]) revert(); - + if (!isActive(msg.sender)) revert(); // dev: sender account not actif + if (_amount>0){ if (delegated[msg.sender][_spender] == 0) { delegMap[msg.sender].push(_spender); @@ -554,47 +913,46 @@ contract _template_ is owned { if (!found && delegMap[msg.sender][i] == _spender){ found=true; } - + if (found){ if (i < delegMap[msg.sender].length-1){ delegMap[msg.sender][i] = delegMap[msg.sender][i+1]; } } } - + if (found){ delete delegMap[msg.sender][delegMap[msg.sender].length-1]; // remove the last record from the mapping array - delegMap[msg.sender].length--; // adjust the length of the mapping array + delegMap[msg.sender].length--; // adjust the length of the mapping array delegated[msg.sender][_spender] = 0; // remove the record from the mapping } - + // delete my delegation found = false; for ( i = 0; i 0) revert(); // Ensure that the request cannot de augmented - if (requested[_from][_to] + _value < 0) revert(); // Ensure that the resulting request is not <0 + if (requested[_from][_to] + _value < 0) revert(); // dev: Ensure that the resulting request is not <0 requested[_from][_to] += _value; myRequested[_to][_from] += _value; topUp(_to); topUp(_from); } - + /* INTERNAL - Allow the account who pay to delete the request */ function clear_request(address _from, address _to) internal { - if (msg.sender != _from) revert(); // Ensure that the message come from the account who pay + if (msg.sender != _from) revert(); // dev: Ensure that the message come from the account who pay bool found; uint i; if (requested[_from][_to]<=0){ @@ -667,45 +1025,45 @@ contract _template_ is owned { if (!found && reqMap[_from][i] == _to){ found=true; } - + if (found){ if (i < reqMap[_from].length-1){ reqMap[_from][i] = reqMap[_from][i+1]; } } } - + if (found){ delete reqMap[_from][reqMap[_from].length-1]; // remove the last record from the mapping array - reqMap[_from].length--; // adjust the length of the mapping array + reqMap[_from].length--; // adjust the length of the mapping array requested[_from][_to] = 0 ; // remove the record from the mapping } } - + if (myRequested[_to][_from]<=0){ found = false; for (i = 0; i0){ if (rejected[_to][msg.sender] == 0) { rejectedMap[_to].push(msg.sender); } - + updateRequested(msg.sender, _to, -amount); rejected[_to][msg.sender] += amount; - + emit Rejection(now, msg.sender, _to, amount); clear_request(msg.sender, _to); } + + + refill(); } - - + + /* Discard acceptation information */ function discardAcceptedInfo(address _spender) public { - if (!accountStatus[msg.sender]) revert(); + if (!isActive(msg.sender)) revert(); bool found = false; for (uint i = 0; i=max_add){ + revert(); + } + + bool found = false; + uint i; + for (i = 0; i address(this).balance){ + amount= address(this).balance; + } + owner.transfer(amount); + } + + /***** Ether handling *******/ + /* The contract dispatch Eth: it must be able to recieve them */ + function () public payable { + + emit Recieved(now, msg.value/(1 ether)); + + uint add_number = target_addresses.length; + if (add_number>0) { + + uint256[] memory balances = new uint256[](add_number); + uint256 max_balance=0; + uint i; + for (i = 0; i address(this) + if (base_amount> 1 ether){ + for (i = 0; i100000000000000000 + + + ## edit account property + owner.setAccountParams(john, True, 0, 3000, -1000) + assert john.balance()==100000000000000000 + +def test_set_account_param_owner(Accounts, currency): + ''' Check admin is refilled when setting account param''' + Owner = Accounts[0] # for contract operation + owner = accounts[0] # for eth transfert + john = accounts[1] + joe = Accounts[2] + + owner.transfer(currency, owner.balance() - 10000000000000000) + assert owner.balance()==10000000000000000 + assert currency.balance()>100000000000000000 + + ## edit account property + Owner.setAccountParams(john, True, 0, 3000, -1000) + assert owner.balance()>10000000000000000 + +def test_pledge_and_pay(Accounts, currency): + ''' Check account is refilled when it recieve pledge or payment''' + Owner = Accounts[0] # for contract operation + owner = accounts[0] # for eth transfert + john = accounts[1] + joe = Accounts[2] + + accounts[3].transfer(currency, accounts[3].balance()-100000000000000000) + assert currency.balance()>100000000000000000 + + Owner.setAccountParams(john, True, 0, 3000, -1000) + john.transfer(currency, john.balance()) + assert john.balance()==0 + + ## pledge account + Owner.pledge(john, 100) + assert john.balance()==100000000000000000 + + ## pay account + john.transfer(currency, john.balance()) + Owner.setAccountParams(joe, True, 0, 3000, -1000) + Owner.pledge(joe, 100) + + joe.transfer(john,100) + assert john.balance()==100000000000000000 + + ## pay account CM + john.transfer(currency, john.balance()) + Owner.setAccountParams(joe, True, 0, 3000, -1000) + joe.transferCM(john,100) + assert john.balance()==100000000000000000 + +def test_pledge_admin(Accounts, currency): + ''' Check admin is refilled when pledging an account''' + Owner = Accounts[0] # for contract operation + owner = accounts[0] # for eth transfert + john = Accounts[1] + accounts[3].transfer(currency, accounts[3].balance()-100000000000000000) + assert currency.balance()>100000000000000000 + + Owner.setAccountParams(john, True, 0, 3000, -1000) + owner.transfer(currency, owner.balance() - 10000000000000000) + assert owner.balance()==10000000000000000 # limit for the refill + assert currency.balance()>100000000000000000 + Owner.pledge(john, 100) + assert owner.balance()>10000000000000000 + +def test_pay_sender(Accounts, currency): + ''' Check sender is refilled when transfering token''' + Owner = Accounts[0] + john = Accounts[1] + joe = accounts[2] # for eth transfert + Joe = Accounts[2] # for contract operation + + Owner.setAccountParams(john, True, 0, 3000, -1000) + Owner.setAccountParams(Joe, True, 0, 3000, -1000) + Owner.pledge(Joe, 100) + joe.transfer(currency, joe.balance() - 10000000000000000) + assert joe.balance()==10000000000000000 # limit for the refill + assert currency.balance()>100000000000000000 + Joe.transfer(john,100) + assert joe.balance()>10000000000000000 + + joe.transfer(currency, joe.balance() - 10000000000000000) + Joe.transferCM(john,100) + assert joe.balance()>10000000000000000 + + + +def test_pledge_and_pay(Accounts, currency): + ''' Check that the account designed to replace the account get gas, idem when cancelling a request ''' + owner = Accounts[0] + john1 = accounts[1] + John1 = Accounts[1] + john2 = accounts[2] + John2 = Accounts[2] + accounts[3].transfer(currency, accounts[3].balance()-100000000000000000) + assert currency.balance()>100000000000000000 + + #target account is new with no gas + john2.transfer(currency, john2.balance()) + assert john2.balance()==0 + + # account to replace has fund, is unlocked and has gas + owner.setAccountParams(john1, True, 1, 3000, -1000) + owner.pledge(john1, 100) + + # allow to replkace should refill John2 + John1.allowReplaceBy(John2) + assert john2.balance()==100000000000000000 + + # cancelling the request should refill John1 + john1.transfer(currency, john1.balance()-10000000000000000) + assert currency.balance()>100000000000000000 + John1.CancelReplaceBy() + assert john1.balance()>10000000000000000 + + + diff --git a/tests/test_pay.py b/tests/test_pay.py new file mode 100644 index 0000000..01824c5 --- /dev/null +++ b/tests/test_pay.py @@ -0,0 +1,235 @@ +# -*- coding: utf-8 -*- + +from .common import currency, Accounts, c, isolation + +from brownie import cccur, accounts, reverts + +def test_set_tax(Accounts, c): + owner = Accounts[0] + tax_recep = Accounts[1] + + # Contract Initial values: + assert c.getTaxAccount == accounts[0] + assert c.getTaxPercent == 0 + assert c.getTaxPercentLeg == 0 + + # Setup + owner.setTaxAccount(tax_recep) + owner.setTaxPercent(13) + owner.setTaxPercentLeg(17) + + # check + assert c.getTaxAccount == accounts[1] + assert c.getTaxPercent == 13 + assert c.getTaxPercentLeg == 17 + + # out of bound + owner.setTaxPercent(0) + owner.setTaxPercent(10000) + with reverts("dev: amount should be greater than 0"): + owner.setTaxPercent(-1) + with reverts("dev: amount should be lower than 10000"): + owner.setTaxPercent(10001) + + owner.setTaxPercentLeg(0) + owner.setTaxPercentLeg(10000) + with reverts("dev: amount should be greater than 0"): + owner.setTaxPercentLeg(-1) + with reverts("dev: amount should be lower than 10000"): + owner.setTaxPercentLeg(10001) + + +def test_pay_nant(Accounts, c): + owner = Accounts[0] + john = Accounts[1] + joe = Accounts[2] + + owner.setAccountParams(john, True, 1, 3000, -1000) + owner.setAccountParams(joe, True, 1, 3000, -1000) + owner.pledge(john,10000) + + assert c.balanceEL(john) == 10000 + assert c.balanceEL(joe) == 0 + assert c.getTaxPercent==0 + assert c.getTaxPercentLeg==0 + + john.transfer(joe,3000) + assert c.balanceEL(john) == 7000 + assert c.balanceEL(joe) == 3000 + assert c.balanceOf(john) == 7000 + assert c.balanceOf(joe) == 3000 + + + + + +def test_pay_nant_tax(Accounts, c): + owner = Accounts[0] + tax_recep = Accounts[1] + john = Accounts[2] + joe = Accounts[3] + inc = Accounts[4] + owner.setTaxAccount(tax_recep) + owner.setTaxPercent(1300) + owner.setTaxPercentLeg(1700) + + owner.setAccountParams(john, True, 1, 3000, -1000) + owner.pledge(john,10000) + + owner.setAccountParams(joe, True, 0, 3000, -1000) + assert c.accountType(joe) == 0 + assert c.getTaxPercent == 1300 + + john.transfer(joe, 3000) + assert c.balanceEL(john) == 7000 + assert c.balanceEL(joe) == 2610 # = -13% + assert c.balanceEL(tax_recep) == 390 + + + owner.setAccountParams(inc, True, 1, 3000, -1000) + john.transfer(inc, 3000) + assert c.balanceEL(john) == 4000 + assert c.balanceEL(inc) == 2490 # = -17% + assert c.balanceEL(tax_recep) == 390 + 510 + + + +def test_pay_nant_unsuccessfull(Accounts, c): + owner = Accounts[0] + john = Accounts[1] + joe = Accounts[2] + + owner.setAccountParams(john, False, 1, 3000, -1000) + owner.setAccountParams(joe, True, 1, 3000, -1000) + with reverts("dev: Source account is locked"): + john.transfer(joe,3000) + + owner.setAccountParams(john, True, 1, 3000, -1000) + owner.setAccountParams(joe, False, 1, 3000, -1000) + with reverts("dev: Target account is locked"): + john.transfer(joe,3000) + + owner.setAccountParams(joe, True, 1, 3000, -1000) + with reverts("dev: Not enough balance"): + john.transfer(joe,3000) + + owner.pledge(john,10000) + owner.setContractStatus(False) + with reverts("dev: panic lock"): + john.transfer(joe,3000) + + + owner.setContractStatus(True) + john.transfer(joe,3000) + + assert c.balanceEL(john) == 7000 + assert c.balanceEL(joe) == 3000 + + with reverts("dev: overflow and negative check"): + john.transfer(joe,-1) + + +def test_pay_cm(Accounts, c): + owner = Accounts[0] + john = Accounts[1] + joe = Accounts[2] + + owner.setAccountParams(john, True, 1, 30000, -10000) + owner.setAccountParams(joe, True, 1, 30000, -10000) + + + assert c.balanceCM(john) == 0 + assert c.balanceCM(joe) == 0 + assert c.getTaxPercent==0 + assert c.getTaxPercentLeg==0 + + john.transferCM(joe,3000) + assert c.balanceCM(john) == -3000 + assert c.balanceCM(joe) == 3000 + assert c.balanceOf(john) == -3000 + assert c.balanceOf(joe) == 3000 + + + +def test_pay_cm_tax(Accounts, c): + owner = Accounts[0] + tax_recep = Accounts[1] + john = Accounts[2] + joe = Accounts[3] + inc = Accounts[4] + owner.setTaxAccount(tax_recep) + owner.setTaxPercent(1300) + owner.setTaxPercentLeg(1700) + + owner.setAccountParams(john, True, 1, 30000, -10000) + owner.setAccountParams(joe, True, 0, 30000, -10000) + assert c.accountType(joe) == 0 + assert c.getTaxPercent == 1300 + + john.transferCM(joe, 3000) + assert c.balanceCM(john) == -3000 + assert c.balanceCM(joe) == 2610 # = -13% + assert c.balanceCM(tax_recep) == 390 + + + owner.setAccountParams(inc, True, 1, 30000, -10000) + john.transferCM(inc, 3000) + assert c.balanceCM(john) == -6000 + assert c.balanceCM(inc) == 2490 # = -17% + assert c.balanceCM(tax_recep) == 390 + 510 + + + +def test_pay_cm_unsuccessfull(Accounts, c): + owner = Accounts[0] + john = Accounts[1] + joe = Accounts[2] + + owner.setAccountParams(john, False, 1, 30000, -10000) + owner.setAccountParams(joe, True, 1, 30000, -10000) + with reverts("dev: Source account is locked"): + john.transferCM(joe,3000) + + owner.setAccountParams(john, True, 1, 30000, -10000) + owner.setAccountParams(joe, False, 1, 30000, -10000) + with reverts("dev: Target account is locked"): + john.transferCM(joe,3000) + + owner.setAccountParams(joe, True, 1, 30000, -10000) + with reverts("dev: Inferior credit limit hit"): + john.transferCM(joe,20000) + + owner.setAccountParams(joe, True, 1, 1000, -10000) + with reverts("dev: Supperior credit limit hit"): + john.transferCM(joe,10000) + + owner.setContractStatus(False) + with reverts("dev: panic lock"): + john.transferCM(joe,3000) + + + owner.setAccountParams(joe, True, 1, 30000, -10000) + owner.setAccountParams(joe, True, 1, 10000, -10000) + owner.setContractStatus(True) + john.transferCM(joe,10000) + + assert c.balanceCM(john) == -10000 + assert c.balanceCM(joe) == 10000 + + with reverts("dev: overflow and negative check"): + john.transferCM(joe,-1) + + +def test_balanceOf(Accounts, c): + owner = Accounts[0] + john = Accounts[1] + joe = Accounts[2] + owner.setAccountParams(john, True, 0, 30000, -10000) + owner.setAccountParams(joe, True, 0, 30000, -10000) + john.transferCM(joe,1000) + owner.pledge(joe,100) + assert c.balanceCM(joe) == 1000 + assert c.balanceEL(joe) == 100 + assert c.balanceOf(joe) == 1100 + + diff --git a/tests/test_pay_request.py b/tests/test_pay_request.py new file mode 100644 index 0000000..7bcd54e --- /dev/null +++ b/tests/test_pay_request.py @@ -0,0 +1,282 @@ +# -*- coding: utf-8 -*- + +from .common import currency, Accounts, c, isolation + +from brownie import cccur, accounts, reverts + +def test_request_NANT(Accounts, c): + owner = Accounts[0] + john = Accounts[1] + joe = Accounts[2] + + owner.setAccountParams(joe, True, 0, 3000, -1000) + assert c.allowanceCount(john) == 0 + assert c.myAllowanceCount(joe) == 0 + assert c.allowance(john,joe) == 0 + + with reverts("dev: Check the creator not to be blocked"): + john.transferFrom(joe, 100) + + owner.setAccountParams(john, True, 0, 3000, -1000) + + # setup Payment Request + john.transferFrom(joe, 100) + + assert c.myRequestCount(john) == 1 + assert c.myGetRequest(john,0) == accounts[2] + assert c.myRequest(john, joe) == 100 + + assert c.requestCount(joe) == 1 + assert c.getRequest(joe,0) == accounts[1] + assert c.request(joe, john) == 100 + +def test_request_CM(Accounts, c): + owner = Accounts[0] + john = Accounts[1] + joe = Accounts[2] + + owner.setAccountParams(joe, True, 0, 3000, -1000) + assert c.allowanceCount(john) == 0 + assert c.myAllowanceCount(joe) == 0 + assert c.allowance(john,joe) == 0 + + with reverts("dev: Check the creator not to be blocked"): + john.transferCMFrom(joe, 100) + + owner.setAccountParams(john, True, 0, 3000, -1000) + + # setup Payment Request + john.transferCMFrom(joe, 100) + + assert c.myRequestCount(john) == 1 + assert c.myGetRequest(john,0) == accounts[2] + assert c.myRequest(john, joe) == 100 + + assert c.requestCount(joe) == 1 + assert c.getRequest(joe,0) == accounts[1] + assert c.request(joe, john) == 100 + + + +def test_update_request(Accounts, c): + owner = Accounts[0] + john = Accounts[1] + joe = Accounts[2] + owner.setAccountParams(joe, True, 0, 3000, -1000) + owner.setAccountParams(john, True, 0, 3000, -1000) + + # setup Payment Request + john.transferFrom(joe, 100) + assert c.myRequestCount(john) == 1 + assert c.myGetRequest(john,0) == accounts[2] + assert c.myRequest(john, joe) == 100 + + assert c.requestCount(joe) == 1 + assert c.getRequest(joe,0) == accounts[1] + assert c.request(joe, john) == 100 + + + # update Request + john.transferFrom(joe, 100) + assert c.myRequestCount(john) == 1 + assert c.myGetRequest(john,0) == accounts[2] + assert c.myRequest(john, joe) == 200 + + assert c.requestCount(joe) == 1 + assert c.getRequest(joe,0) == accounts[1] + assert c.request(joe, john) == 200 + + john.transferCMFrom(joe, 100) + assert c.myRequestCount(john) == 1 + assert c.myGetRequest(john,0) == accounts[2] + assert c.myRequest(john, joe) == 300 + + assert c.requestCount(joe) == 1 + assert c.getRequest(joe,0) == accounts[1] + assert c.request(joe, john) == 300 + + #cannot lower the request + with reverts("dev: overflow and negative check"): + john.transferFrom(joe, -100) + + with reverts("dev: overflow and negative check"): + john.transferCMFrom(joe, -100) + +def test_refuse_request(Accounts, c): + owner = Accounts[0] + john = Accounts[1] + joe = Accounts[2] + owner.setAccountParams(joe, True, 0, 3000, -1000) + owner.setAccountParams(john, True, 0, 3000, -1000) + john.transferFrom(joe, 100) + assert c.myRequestCount(john) == 1 + assert c.myGetRequest(john,0) == accounts[2] + assert c.myRequest(john, joe) == 100 + assert c.requestCount(joe) == 1 + assert c.getRequest(joe,0) == accounts[1] + assert c.request(joe, john) == 100 + + joe.cancelRequest(john) + assert c.myRequestCount(john) == 0 + assert c.myRequest(john, joe) == 0 + assert c.requestCount(joe) == 0 + assert c.request(joe, john) == 0 + + + +def test_pay_request(Accounts, c): + owner = Accounts[0] + john = Accounts[1] + joe = Accounts[2] + owner.setAccountParams(joe, True, 0, 3000, -1000) + owner.setAccountParams(john, True, 0, 3000, -1000) + + # setup Payment Request + john.transferFrom(joe, 100) + assert c.myRequestCount(john) == 1 + assert c.myGetRequest(john,0) == accounts[2] + assert c.myRequest(john, joe) == 100 + + assert c.requestCount(joe) == 1 + assert c.getRequest(joe,0) == accounts[1] + assert c.request(joe, john) == 100 + + owner.setAccountParams(john, False, 0, 3000, -1000) + + + + with reverts("dev: Target account is locked"): + joe.payRequest(john,50) + with reverts("dev: Target account is locked"): + joe.payRequestCM(john,50) + + owner.setAccountParams(joe, False, 0, 3000, -1000) + owner.setAccountParams(john, True, 0, 3000, -1000) + with reverts("dev: Source account is locked"): + joe.payRequest(john,50) + with reverts("dev: Source account is locked"): + joe.payRequestCM(john,50) + + owner.setAccountParams(joe, True, 0, 3000, -1000) + with reverts("dev: Not enough balance"): + joe.payRequest(john,50) + + owner.pledge(joe,100) + + owner.setContractStatus(False) + with reverts("dev: panic lock"): + joe.payRequest(john,50) + with reverts("dev: panic lock"): + joe.payRequestCM(john,50) + owner.setContractStatus(True) + + + joe.payRequest(john,50) + assert c.myRequestCount(john) == 1 + assert c.myGetRequest(john,0) == accounts[2] + assert c.myRequest(john, joe) == 50 + + assert c.requestCount(joe) == 1 + assert c.getRequest(joe,0) == accounts[1] + assert c.request(joe, john) == 50 + + joe.payRequestCM(john,25) + assert c.myRequestCount(john) == 1 + assert c.myGetRequest(john,0) == accounts[2] + assert c.myRequest(john, joe) == 25 + + assert c.requestCount(joe) == 1 + assert c.getRequest(joe,0) == accounts[1] + assert c.request(joe, john) == 25 + + # Check more than expected + with reverts("dev: Ensure that the resulting request is not <0"): + joe.payRequest(john,50) + with reverts("dev: Ensure that the resulting request is not <0"): + joe.payRequestCM(john,50) + + # check cleaning + joe.payRequest(john,25) + assert c.myRequestCount(john) == 0 + assert c.myRequest(john, joe) == 0 + + assert c.requestCount(joe) == 0 + assert c.request(joe, john) == 0 + +def test_info_request(Accounts, c): + owner = Accounts[0] + john = Accounts[1] + joe = Accounts[2] + owner.setAccountParams(joe, True, 0, 3000, -1000) + owner.setAccountParams(john, True, 0, 3000, -1000) + john.transferFrom(joe, 100) + joe.cancelRequest(john) + + assert c.rejectedCount(john) == 1 + assert c.getRejected(john,0) == accounts[2] + assert c.rejectedAmount(john,joe) == 100 + + john.transferFrom(joe, 10) + + owner.setAccountParams(joe, False, 0, 3000, -1000) + with reverts(""): + joe.cancelRequest(john) + owner.setAccountParams(joe, True, 0, 3000, -1000) + + + joe.cancelRequest(john) + + assert c.rejectedCount(john) == 1 + assert c.getRejected(john,0) == accounts[2] + assert c.rejectedAmount(john,joe) == 110 + + + owner.setAccountParams(john, False, 0, 3000, -1000) + with reverts(""): + john.discardRejectedInfo(joe) + owner.setAccountParams(john, True, 0, 3000, -1000) + + john.discardRejectedInfo(joe) + assert c.rejectedCount(john) == 0 + assert c.rejectedAmount(john,joe) == 0 + + + + # Partial pay + owner.pledge(joe,100) + john.transferFrom(joe, 20) + joe.payRequest(john,11) + + assert c.myRequestCount(john) == 1 + assert c.myGetRequest(john,0) == accounts[2] + assert c.myRequest(john, joe) == 9 + + assert c.requestCount(joe) == 1 + assert c.getRequest(joe,0) == accounts[1] + assert c.request(joe, john) == 9 + + assert c.acceptedCount(john) == 1 + assert c.getAccepted(john,0) == accounts[2] + assert c.acceptedAmount(john,joe) == 11 + + # Full pay + joe.payRequest(john,9) + + assert c.acceptedCount(john) == 1 + assert c.getAccepted(john,0) == accounts[2] + assert c.acceptedAmount(john,joe) == 20 + + owner.setAccountParams(john, False, 0, 3000, -1000) + with reverts(""): + john.discardAcceptedInfo(joe) + owner.setAccountParams(john, True, 0, 3000, -1000) + + + john.discardAcceptedInfo(joe) + assert c.acceptedCount(john) == 0 + assert c.acceptedAmount(john,joe) == 0 + + + + + diff --git a/tests/test_pledge_admin.py b/tests/test_pledge_admin.py new file mode 100644 index 0000000..872efa8 --- /dev/null +++ b/tests/test_pledge_admin.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- + +from .common import currency, isolation + +from brownie import cccur, accounts, reverts + + +def test_pledge(currency): + + owner = accounts[0] + john = accounts[1] + + ## make john have roles that are not allowed to pledge + for t in [0, 1, 4]: + currency.setAccountParams(john, True, t, -1000, 3000) + + ## Do not have permission to pledge + with reverts("dev: permission denied"): + currency.pledge(owner, 100, {"from": john}) + + assert currency.balanceOf(owner) == 0 + + s = 0 + ## make john have roles that are allowed to pledge + for t in [2, 3]: + ## make john pledge + currency.setAccountParams(john, True, t, -1000, 3000) + + currency.pledge(owner, 100, {"from": john}) + s += 100 + + assert currency.balanceOf(owner) == s + + ## total amount pledged + assert currency.amountPledged() == s + + ## Make john a disabled pledge admin + currency.setAccountParams(john, False, 3, -1000, 3000) + with reverts("dev: disabled accounts can't pledge"): + currency.pledge(owner, 100, {"from": john}) + + ## Make john a enabled pledge admin + currency.setAccountParams(john, True, 3, -1000, 3000) + walter = accounts[2] + with reverts("dev: disabled accounts can't receive pledge"): + currency.pledge(walter, 100, {"from": john}) + + ## total amount pledged + assert currency.amountPledged() == s + + +def test_set_account_param(currency): + + owner = accounts[0] + john = accounts[1] + walter = accounts[2] + + ## make john a pledge admin + currency.setAccountParams(john, True, 3, -1000, 3000) + + ## john as a pledge admin can't setAccountParams + + for t in range(0, 5): + for a in [True, False]: + for u in [owner, john, walter]: + with reverts("dev: permission denied"): + currency.setAccountParams(u, a, t, -1000, 3000, {"from": john}) + diff --git a/tests/test_property_admin.py b/tests/test_property_admin.py new file mode 100644 index 0000000..06ee932 --- /dev/null +++ b/tests/test_property_admin.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- + +from .common import currency, isolation + +from brownie import cccur, accounts, reverts + + +def test_set_account_param(currency): + + owner = accounts[0] + john = accounts[1] + walter = accounts[2] + + ## make john have roles that are not allowed to setAccountsParams + for john_role in [0, 1, 3]: + currency.setAccountParams(john, True, john_role, -1000, 3000) + + ## Do not have permission to setAccountParams + for t in range(0, 5): + for a in [True, False]: + for u in [owner, john, walter]: + with reverts("dev: permission denied"): + currency.setAccountParams(u, a, t, -1000, 3000, {"from": john}) + + + ## make john have roles that are allowed to setAccountParams + for john_role in [2, 4]: + currency.setAccountParams(john, True, john_role, -1000, 3000) + + ## Can setAccountParams without restrictions + for t in range(0, 5): + for a in [True, False]: + currency.setAccountParams(walter, a, t, -1000, 3000, {"from": john}) + + ## Make john a disabled property admin + currency.setAccountParams(john, False, 4, -1000, 3000) + + ## Do not have permission to setAccountParams + for t in range(0, 5): + for a in [True, False]: + with reverts("dev: disabled accounts can't set account params"): + currency.setAccountParams(walter, a, t, -1000, 3000, {"from": john}) + + diff --git a/tests/test_replace_account.py b/tests/test_replace_account.py new file mode 100644 index 0000000..cc57a5d --- /dev/null +++ b/tests/test_replace_account.py @@ -0,0 +1,307 @@ +# -*- coding: utf-8 -*- + +from .common import currency, Accounts, c, isolation + +from brownie import cccur, accounts, reverts + + + +def test_replace_account_standard(Accounts, c): + + owner = Accounts[0] + john1 = Accounts[1] + john2 = Accounts[2] + john3 = Accounts[3] + joe1 = Accounts[4] + joe2 = Accounts[5] + joe3 = Accounts[6] + + owner.setAccountParams(john1, True, 1, 3000, -1000) + owner.pledge(john1, 100) + + # Create and check delegation + john1.delegate(joe1, 10) + assert c.delegationCount(john1) == 1 + assert c.myDelegationCount(joe1) == 1 + + # Create and check allowance + john1.approve(joe2, 11) + assert c.myAllowanceCount(joe2)==1 + assert c.myAllowance(joe2,john1) == 11 + assert c.allowanceCount(john1)==1 + + # Create and check a payement request + owner.setAccountParams(joe3, True, 1, 3000, -1000) + joe3.transferFrom(john1,13) + assert c.requestCount(john1)==1 + assert c.myRequestCount(joe3)==1 + assert c.myRequest(joe3,john1)==13 + + john1.allowReplaceBy(john2) + john2.acceptReplaceAccount(john1) + + assert c.accountType(john1) == 1 + assert c.accountType(john2) == 1 + + assert c.balanceOf(john2) == 100 + assert c.balanceOf(john1) == 0 + + assert c.accountStatus(john1) is False + assert c.accountStatus(john2) is True + + assert c.limitCredit(john1) == 0 + assert c.limitCredit(john2) == -1000 + + assert c.limitDebit(john1) == 0 + assert c.limitDebit(john2) == 3000 + + + assert c.delegationCount(john1) == 0 + assert c.delegationCount(john2) == 1 + assert c.myDelegationCount(joe1) == 1 + assert c.delegation(john1,joe1)==0 + assert c.delegation(john2,joe1)==10 + assert c.myDelegation(joe1,john1)==0 + assert c.myDelegation(joe1,john2)==10 + + assert c.allowanceCount(john1) == 0 + assert c.allowanceCount(john2) == 1 + assert c.myAllowanceCount(joe2) == 1 + assert c.myAllowance(joe2,john1)==0 + assert c.myAllowance(joe2,john2)==11 + assert c.allowance(john1,joe2)==0 + assert c.allowance(john2,joe2)==11 + + assert c.requestCount(john1)==0 + assert c.requestCount(john2)==1 + assert c.myRequestCount(joe3)==1 + assert c.request(john1,joe3)==0 + assert c.request(john2,joe3)==13 + assert c.myRequest(joe3,john1)==0 + assert c.myRequest(joe3,john2)==13 + + + with reverts("dev: already replaced account cannot be replaced again"): + john1.allowReplaceBy(john3) + + +def test_replace_account_standard_with_cancel(Accounts, c): + + owner = Accounts[0] + john1 = Accounts[1] + john2 = Accounts[2] + + owner.setAccountParams(john1, True, 1, 3000, -1000) + owner.pledge(john1, 100) + + john1.allowReplaceBy(john2) + john1.CancelReplaceBy() + + john1.allowReplaceBy(john2) + john2.acceptReplaceAccount(john1) + + assert c.accountType(john1) == 1 + assert c.accountType(john2) == 1 + + assert c.balanceOf(john2) == 100 + assert c.balanceOf(john1) == 0 + + assert c.accountStatus(john1) is False + assert c.accountStatus(john2) is True + + assert c.limitCredit(john1) == 0 + assert c.limitCredit(john2) == -1000 + + assert c.limitDebit(john1) == 0 + assert c.limitDebit(john2) == 3000 + + +def test_replace_account_two_request(Accounts, c): + + owner = Accounts[0] + john1 = Accounts[1] + john2 = Accounts[2] + + owner.setAccountParams(john1, True, 1, 3000, -1000) + owner.pledge(john1, 100) + + john1.allowReplaceBy(john2) + + with reverts("dev: locked account cannot be replaced"): + john1.allowReplaceBy(john2) + + +def test_replace_account_cancel_request(Accounts, c): + + owner = Accounts[0] + john1 = Accounts[1] + john2 = Accounts[2] + + owner.setAccountParams(john1, True, 1, 3000, -1000) + owner.pledge(john1, 100) + + john1.allowReplaceBy(john2) + john1.CancelReplaceBy() + + with reverts("dev: replacement request not initiated"): + john2.acceptReplaceAccount(john1) + + +def test_replace_account_no_previous_request(Accounts, c): + + owner = Accounts[0] + john1 = Accounts[1] + john2 = Accounts[2] + + owner.setAccountParams(john1, True, 1, 3000, -1000) + owner.pledge(john1, 100) + + with reverts("dev: replacement request not initiated"): + john2.acceptReplaceAccount(john1) + + +def test_replace_account_not_new_target(Accounts, c): + + owner = Accounts[0] + john = Accounts[1] + billy = Accounts[2] + walter = Accounts[3] + + owner.setAccountParams(john, True, 2, 3000, -1000) + owner.setAccountParams(billy, True, 0, 1000, -500) + owner.pledge(john, 100) + + ## Billy is already used account + with reverts("dev: only new account can be target of a replacement"): + john.allowReplaceBy(billy) + + ## Walter is not yet used + john.allowReplaceBy(walter) + ## .. but we'll use it + owner.setAccountParams(walter, True, 0, 1500, -750) + ## .. so on acceptReplace time, do nothing and remove request + walter.acceptReplaceAccount(john) + + ## YYYvlab: can we check directement requestReplacementFrom[john] array ? + + ## Nothing should have changed: + assert c.accountType(john) == 2 + assert c.accountType(walter) == 0 + + assert c.balanceOf(john) == 100 + assert c.balanceOf(walter) == 0 + + assert c.accountStatus(john) is True + assert c.accountStatus(walter) is True + + assert c.limitCredit(john) == -1000 + assert c.limitCredit(walter) == -750 + + assert c.limitDebit(john) == 3000 + assert c.limitDebit(walter) == 1500 + + + +def test_replace_account_crossover(Accounts, c): + + owner = Accounts[0] + john1 = Accounts[1] + john2 = Accounts[2] + walter = Accounts[3] + + owner.setAccountParams(john1, True, 2, 3000, -1000) + owner.setAccountParams(walter, True, 0, 1000, -500) + owner.pledge(john1, 100) + + john1.allowReplaceBy(john2) + walter.allowReplaceBy(john2) + + john2.acceptReplaceAccount(john1) + john2.acceptReplaceAccount(walter) + + assert c.accountType(john1) == 2 + assert c.accountType(john2) == 2 + + assert c.balanceOf(john2) == 100 + assert c.balanceOf(john1) == 0 + + assert c.accountStatus(john1) is False + assert c.accountStatus(john2) is True + + assert c.limitCredit(john1) == 0 + assert c.limitCredit(john2) == -1000 + + assert c.limitDebit(john1) == 0 + assert c.limitDebit(john2) == 3000 + + +def test_replace_account_to_non_new_account(Accounts, c): + + owner = Accounts[0] + john1 = Accounts[1] + john2 = Accounts[2] + walter = Accounts[3] + + owner.setAccountParams(john1, True, 1, 3000, -1000) + owner.pledge(john1, 100) + + with reverts("dev: only new account can be target of a replacement"): + john1.allowReplaceBy(owner) + + owner.setAccountParams(walter, True, 0, 3000, -1000) + with reverts("dev: only new account can be target of a replacement"): + john1.allowReplaceBy(walter) + + john1.allowReplaceBy(john2) + + + +def test_replaced_account_not_usable(Accounts, c): + + owner = Accounts[0] + john1 = Accounts[1] + john2 = Accounts[2] + walter = Accounts[3] + + owner.setAccountParams(john1, True, 1, 3000, -1000) + owner.pledge(john1, 100) + + john1.allowReplaceBy(john2) + john2.acceptReplaceAccount(john1) + + ## Can't set properties of a replaced account + with reverts("dev: replaced account cannot be modified"): + owner.setAccountParams(john1, True, 1, 3000, -1000) + + +def test_replace_account_panick_lock(Accounts, c): + owner = Accounts[0] + john1 = Accounts[1] + john2 = Accounts[2] + + owner.setAccountParams(john1, True, 1, 3000, -1000) + owner.pledge(john1, 100) + + owner.setContractStatus(False) + with reverts("dev: panic lock"): + john1.allowReplaceBy(john2) + owner.setContractStatus(True) + + john1.allowReplaceBy(john2) + owner.setContractStatus(False) + with reverts("dev: panic lock"): + john1.CancelReplaceBy() + with reverts("dev: panic lock"): + john2.acceptReplaceAccount(john1) + owner.setContractStatus(True) + + + + + + + + + + +