diff --git a/algorand/.gitignore b/algorand/.gitignore index b8ede2915..928e2d65d 100644 --- a/algorand/.gitignore +++ b/algorand/.gitignore @@ -1,3 +1,4 @@ __pycache__ _sandbox genesis.json +artifacts diff --git a/algorand/Dockerfile.build b/algorand/Dockerfile.build new file mode 100644 index 000000000..6254fbdb7 --- /dev/null +++ b/algorand/Dockerfile.build @@ -0,0 +1,17 @@ +FROM docker.io/python:3.10@sha256:eeed7cac682f9274d183f8a7533ee1360a26acb3616aa712b2be7896f80d8c5f as algorand-contracts-build + +RUN python3 -m pip install virtualenv +COPY Pipfile.lock Pipfile.lock +COPY Pipfile Pipfile + +RUN python3 -m pip install pipenv +RUN pipenv install +RUN mkdir teal +COPY *.py . + +RUN pipenv run python3 admin.py --mainnet --genTeal + +FROM scratch AS algorand-contracts-export +COPY --from=algorand-contracts-build /teal/* . + + diff --git a/algorand/Makefile b/algorand/Makefile index b4895512b..8bb4386fb 100644 --- a/algorand/Makefile +++ b/algorand/Makefile @@ -2,3 +2,14 @@ test: ./runPythonUnitTests.sh + +.PHONY: artifacts +artifacts: + rm -rf $@ + mkdir -p $@ + @echo "Building artifacts for algorand" + DOCKER_BUILDKIT=1 docker build -f Dockerfile.build -t algorand-builder -o type=local,dest=$@ . + ../scripts/contract-upgrade-governance.sh -m token_bridge -c algorand -a `cat artifacts/token_approve.teal.hash` -o artifacts + ../scripts/contract-upgrade-governance.sh -m core -c algorand -a `cat artifacts/core_approve.teal.hash` -o artifacts + + diff --git a/algorand/Pipfile.lock b/algorand/Pipfile.lock index 94dcc74dc..6f34036f4 100644 --- a/algorand/Pipfile.lock +++ b/algorand/Pipfile.lock @@ -1,11 +1,11 @@ { "_meta": { "hash": { - "sha256": "d57ff41afd46f1f82ef8cfa680858a40bda1d72482b073dba8666ac42275264f" + "sha256": "6571270ba10a2ef56432b1e20a02692ad00845c3faa0afa08ea0bcdc4e0ec185" }, "pipfile-spec": 6, "requires": { - "python_version": "3.9" + "python_version": "3.10" }, "sources": [ { @@ -148,25 +148,93 @@ }, "cytoolz": { "hashes": [ - "sha256:ea23663153806edddce7e4153d1d407d62357c05120a4e8485bddf1bd5ab22b4" + "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.11.2" - }, - "dataclasses": { - "hashes": [ - "sha256:0201d89fa866f68c8ebd9d08ee6ff50c0b255f8ec63a71c16fda7af82bb887bf", - "sha256:8479067f342acf957dc82ec415d355ab5edb7e7646b90dc6e2fd1d96ad084c97" - ], - "markers": "python_version < '3.7'", - "version": "==0.8" - }, - "decorator": { - "hashes": [ - "sha256:41fa54c2a0cc4ba648be4fd43cff00aedf5b9465c9bf18d64325bc225f08f760", - "sha256:e3a62f0520172440ca0dcc823749319382e377f37f140a0b99ef45fecb84bfe7" - ], - "version": "==4.4.2" + "version": "==0.12.0" }, "eth-abi": { "hashes": [ @@ -178,11 +246,11 @@ }, "eth-hash": { "hashes": [ - "sha256:3f40cecd5ead88184aa9550afc19d057f103728108c5102f592f8415949b5a76", - "sha256:de7385148a8e0237ba1240cddbc06d53f56731140f8593bdb8429306f6b42271" + "sha256:3c884e4f788b38cc92cff05c4e43bc6b82686066f04ecfae0e11cdcbe5a283bd", + "sha256:8cde211519ff1a98b46e9057cb909f12ab62e263eb30a0a94e2f7e1f46ac67a0" ], "markers": "python_version >= '3.5' and python_version < '4'", - "version": "==0.3.2" + "version": "==0.3.3" }, "eth-typing": { "hashes": [ @@ -216,14 +284,6 @@ "index": "pypi", "version": "==1.2.0" }, - "importlib-metadata": { - "hashes": [ - "sha256:65a9576a5b2d58ca44d133c42a241905cc45e34d2c06fd5ba2bafa221e5d7b5e", - "sha256:766abffff765960fcc18003801f7044eb6755ffae4521c8e8ce8e83b9c9b0668" - ], - "markers": "python_version < '3.8'", - "version": "==4.8.3" - }, "iniconfig": { "hashes": [ "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3", @@ -274,11 +334,11 @@ }, "networkx": { "hashes": [ - "sha256:0635858ed7e989f4c574c2328380b452df892ae85084144c73d8cd819f0c4e06", - "sha256:109cd585cac41297f71103c3c42ac6ef7379f29788eb54cb751be5a663bb235a" + "sha256:2a30822761f34d56b9a370d96a4bf4827a535f5591a4078a453425caeba0c5bb", + "sha256:bd2b7730300860cbd2dafe8e5af89ff5c9a65c3975b352799d87a6238b4301a6" ], - "markers": "python_version >= '3.6'", - "version": "==2.5.1" + "markers": "python_version >= '3.8'", + "version": "==2.8.6" }, "packaging": { "hashes": [ @@ -429,11 +489,11 @@ }, "pyteal": { "hashes": [ - "sha256:6c140db6ac365f438dc979c7de4153686ef97b762b9c4efe23bba0db4ff699e5", - "sha256:a72d1f0859f2248459bbcdbdfcd8cf09023ea003b121f0dbaf58289b8167d20c" + "sha256:29198b1e76121380430d9feaac4135c27b03b38e410b1c03f2c055feb9e533d6", + "sha256:937440d9562a425d53e1d4a74c357443435d1e74a407d5f4f87143767b4d4588" ], "index": "pypi", - "version": "==v0.10.0" + "version": "==v0.11.1" }, "pytest": { "hashes": [ @@ -469,6 +529,7 @@ }, "pyyaml": { "hashes": [ + "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf", "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293", "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b", "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57", @@ -480,26 +541,32 @@ "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287", "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513", "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0", + "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782", "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0", "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92", "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f", "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2", "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc", + "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1", "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c", "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86", "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4", "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c", "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34", "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b", + "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d", "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c", "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb", + "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7", "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737", "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3", "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d", + "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358", "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53", "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78", "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803", "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a", + "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f", "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174", "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5" ], @@ -524,11 +591,11 @@ }, "toolz": { "hashes": [ - "sha256:6b312d5e15138552f1bda8a4e66c30e236c831b612b2bf0005f8a1df10a4bc33", - "sha256:a5700ce83414c64514d82d60bcda8aabfde092d1c1a8663f9200c07fdcc6da8f" + "sha256:2059bd4148deb1884bb0eb770a3cde70e7f954cfbbdc2285f1f2de01fd21eb6f", + "sha256:88c570861c440ee3f2f6037c4654613228ff40c93a6c25e0eba70d17282c6194" ], "markers": "python_version >= '3.5'", - "version": "==0.11.2" + "version": "==0.12.0" }, "typing-extensions": { "hashes": [ @@ -545,14 +612,6 @@ ], "index": "pypi", "version": "==1.2.0" - }, - "zipp": { - "hashes": [ - "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832", - "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc" - ], - "markers": "python_version >= '3.6'", - "version": "==3.6.0" } }, "develop": {} diff --git a/algorand/admin.py b/algorand/admin.py index 591ff8365..7a35d7288 100644 --- a/algorand/admin.py +++ b/algorand/admin.py @@ -283,12 +283,8 @@ class PortalCore: # helper function to read app global state def read_global_state(self, client, addr, app_id): - results = client.account_info(addr) - apps_created = results['created-apps'] - for app in apps_created: - if app['id'] == app_id and 'global-state' in app['params']: - return self.format_state(app['params']['global-state']) - return {} + results = self.client.application_info(app_id) + return self.format_state(results['params']['global-state']) def read_state(self, client, addr, app_id): results = client.account_info(addr) @@ -355,8 +351,13 @@ class PortalCore: return -1 def genUpgradePayload(self): - approval, clear = getCoreContracts(False, self.args.core_approve, self.args.core_clear, self.client, seed_amt=self.seed_amt, tmpl_sig=self.tsig, devMode = self.devnet or self.args.testnet) + approval1, clear1 = getCoreContracts(False, self.args.core_approve, self.args.core_clear, self.client, seed_amt=self.seed_amt, tmpl_sig=self.tsig, devMode = self.devnet or self.args.testnet) + approval2, clear2 = get_token_bridge(False, self.args.token_approve, self.args.token_clear, self.client, seed_amt=self.seed_amt, tmpl_sig=self.tsig, devMode = self.devnet or self.args.testnet) + + return self.genUpgradePayloadBody(approval1, approval2) + + def genUpgradePayloadBody(self, approval1, approval2): b = self.zeroPadBytes[0:(28*2)] b += self.encoder("uint8", ord("C")) b += self.encoder("uint8", ord("o")) @@ -365,14 +366,11 @@ class PortalCore: b += self.encoder("uint8", 1) b += self.encoder("uint16", 8) - b += decode_address(approval["hash"]).hex() - print("core hash: " + decode_address(approval["hash"]).hex()) + b += decode_address(approval1["hash"]).hex() + print("core hash: " + decode_address(approval1["hash"]).hex()) ret = [b] - approval, clear = get_token_bridge(False, self.args.token_approve, self.args.token_clear, self.client, seed_amt=self.seed_amt, tmpl_sig=self.tsig, devMode = self.devnet or self.args.testnet) - - b = self.zeroPadBytes[0:((32 -11)*2)] b += self.encoder("uint8", ord("T")) b += self.encoder("uint8", ord("o")) @@ -388,8 +386,8 @@ class PortalCore: b += self.encoder("uint8", 2) # action b += self.encoder("uint16", 8) # target chain - b += decode_address(approval["hash"]).hex() - print("token hash: " + decode_address(approval["hash"]).hex()) + b += decode_address(approval2["hash"]).hex() + print("token hash: " + decode_address(approval2["hash"]).hex()) ret.append(b) return ret @@ -1282,9 +1280,18 @@ class PortalCore: def updateCore(self) -> None: print("Updating the core contracts") - approval, clear = getCoreContracts(False, self.args.core_approve, self.args.core_clear, self.client, seed_amt=self.seed_amt, tmpl_sig=self.tsig, devMode = self.devnet or self.args.testnet) - - print("core " + decode_address(approval["hash"]).hex()) + if self.args.approve == "" and self.args.clear == "": + approval, clear = getCoreContracts(False, self.args.core_approve, self.args.core_clear, self.client, seed_amt=self.seed_amt, tmpl_sig=self.tsig, devMode = self.devnet or self.args.testnet) + print("core approval " + decode_address(approval["hash"]).hex()) + print("core clear " + decode_address(clear["hash"]).hex()) + else: + pprint.pprint([self.args.approve, self.args.clear]) + with open(self.args.approve, encoding = 'utf-8') as f: + approval = {"result": f.readlines()[0]} + pprint.pprint(approval) + with open(self.args.clear, encoding = 'utf-8') as f: + clear = {"result": f.readlines()[0]} + pprint.pprint(clear) txn = transaction.ApplicationUpdateTxn( index=self.coreid, @@ -1299,6 +1306,7 @@ class PortalCore: print("sending transaction") self.client.send_transaction(signedTxn) resp = self.waitForTransaction(self.client, signedTxn.get_txid()) + pprint.pprint(resp) for x in resp.__dict__["logs"]: print(x.hex()) print("complete") @@ -1329,10 +1337,30 @@ class PortalCore: def genTeal(self) -> None: print((True, self.args.core_approve, self.args.core_clear, self.client, self.seed_amt, self.tsig, self.devnet or self.args.testnet)) - approval, clear = getCoreContracts(True, self.args.core_approve, self.args.core_clear, self.client, seed_amt=self.seed_amt, tmpl_sig=self.tsig, devMode = self.devnet or self.args.testnet) + devmode = (self.devnet or self.args.testnet) and not self.args.prodTeal + approval1, clear1 = getCoreContracts(True, self.args.core_approve, self.args.core_clear, self.client, seed_amt=self.seed_amt, tmpl_sig=self.tsig, devMode = devmode) print("Generating the teal for the core contracts") - approval, clear = get_token_bridge(True, self.args.token_approve, self.args.token_clear, self.client, seed_amt=self.seed_amt, tmpl_sig=self.tsig, devMode = self.devnet or self.args.testnet) - print("Generating the teal for the token contracts: " + str(len(b64decode(approval["result"])))) + approval2, clear2 = get_token_bridge(True, self.args.token_approve, self.args.token_clear, self.client, seed_amt=self.seed_amt, tmpl_sig=self.tsig, devMode = devmode) + print("Generating the teal for the token contracts: " + str(len(b64decode(approval2["result"])))) + + if self.devnet: + v = self.genUpgradePayloadBody(approval1, approval2) + if self.gt == None: + self.gt = GenTest(False) + + emitter = bytes.fromhex(self.zeroPadBytes[0:(31*2)] + "04") + + guardianSet = 0 + + nonce = int(random.random() * 20000) + coreVAA = self.gt.createSignedVAA(guardianSet, self.gt.guardianPrivKeys, int(time.time()), nonce, 1, emitter, int(random.random() * 20000), 32, 8, v[0]) + tokenVAA = self.gt.createSignedVAA(guardianSet, self.gt.guardianPrivKeys, int(time.time()), nonce, 1, emitter, int(random.random() * 20000), 32, 8, v[1]) + + with open("teal/core_devnet.vaa", "w") as fout: + fout.write(coreVAA) + + with open("teal/token_devnet.vaa", "w") as fout: + fout.write(tokenVAA) def testnet(self): self.ALGOD_ADDRESS = self.args.algod_address = "https://testnet-api.algonode.cloud" @@ -1343,8 +1371,12 @@ class PortalCore: def mainnet(self): self.ALGOD_ADDRESS = self.args.algod_address = "https://mainnet-api.algonode.cloud" self.INDEXER_ADDRESS = "https://mainnet-idx.algonode.cloud" - self.coreid = self.args.coreid - self.tokenid = self.args.tokenid + self.coreid = 842125965 + self.tokenid = 842126029 + if self.args.coreid != 4: + self.coreid = self.args.coreid + if self.args.coreid != 6: + self.tokenid = self.args.tokenid def setup_args(self) -> None: parser = argparse.ArgumentParser(description='algorand setup') @@ -1384,6 +1416,7 @@ class PortalCore: parser.add_argument('--upgradeVAA', action='store_true', help='generate a upgrade vaa for devnet') parser.add_argument('--print', action='store_true', help='print') parser.add_argument('--genParts', action='store_true', help='Get tssig parts') + parser.add_argument('--prodTeal', action='store_true', help='use Production Deal') parser.add_argument('--genTeal', action='store_true', help='Generate all the teal from the pyteal') parser.add_argument('--fund', action='store_true', help='Generate some accounts and fund them') parser.add_argument('--testnet', action='store_true', help='Connect to testnet') @@ -1392,6 +1425,8 @@ class PortalCore: parser.add_argument('--rpc', type=str, help='RPC address', default="") parser.add_argument('--guardianKeys', type=str, help='GuardianKeys', default="") parser.add_argument('--guardianPrivKeys', type=str, help='guardianPrivKeys', default="") + parser.add_argument('--approve', type=str, help='compiled approve contract', default="") + parser.add_argument('--clear', type=str, help='compiled clear contract', default="") args = parser.parse_args() self.init(args) @@ -1413,6 +1448,7 @@ class PortalCore: self.ALGOD_ADDRESS = self.args.rpc self.client = self.getAlgodClient() + if self.devnet or self.args.testnet: self.vaa_verify = self.client.compile(get_vaa_verify()) else: @@ -1485,12 +1521,31 @@ class PortalCore: ret = self.devnetUpgradeVAA() pprint.pprint(ret) if (args.submit) : - print("submitting vaa to upgrade core") + print("submitting vaa to upgrade core: " + str(self.coreid)) + state = self.read_global_state(self.client, self.foundation.addr, self.coreid) + pprint.pprint( { + "validUpdateApproveHash": b64decode(state["validUpdateApproveHash"]).hex(), + "validUpdateClearHash": b64decode(state["validUpdateClearHash"]).hex() + }) self.submitVAA(bytes.fromhex(ret[0]), self.client, self.foundation, self.coreid) - pprint.pprint(self.read_global_state(self.client, self.foundation.addr, self.coreid)) - print("submitting vaa to upgrade token") + state = self.read_global_state(self.client, self.foundation.addr, self.coreid) + pprint.pprint( { + "validUpdateApproveHash": b64decode(state["validUpdateApproveHash"]).hex(), + "validUpdateClearHash": b64decode(state["validUpdateClearHash"]).hex() + }) + + print("submitting vaa to upgrade token: " + str(self.tokenid)) + state = self.read_global_state(self.client, self.foundation.addr, self.tokenid) + pprint.pprint( { + "validUpdateApproveHash": b64decode(state["validUpdateApproveHash"]).hex(), + "validUpdateClearHash": b64decode(state["validUpdateClearHash"]).hex() + }) self.submitVAA(bytes.fromhex(ret[1]), self.client, self.foundation, self.tokenid) - pprint.pprint(self.read_global_state(self.client, self.foundation.addr, self.tokenid)) + state = self.read_global_state(self.client, self.foundation.addr, self.tokenid) + pprint.pprint( { + "validUpdateApproveHash": b64decode(state["validUpdateApproveHash"]).hex(), + "validUpdateClearHash": b64decode(state["validUpdateClearHash"]).hex() + }) if args.boot: self.boot() diff --git a/algorand/teal/README b/algorand/teal/README deleted file mode 100644 index d0e549899..000000000 --- a/algorand/teal/README +++ /dev/null @@ -1,8 +0,0 @@ - -While these are generated files, due to the non-deterministic behavior -of the pyteal compiler based on what has been done before, we cannot -reliably recreate the exact same teal file from the exact same pyteal -source. - -As a result, we need to check the generated files in so that we can -verify the hash of the compiled code while generating upgrade vaa's diff --git a/algorand/teal/core_approve.teal b/algorand/teal/core_approve.teal index b317a7ded..35334eb0a 100644 --- a/algorand/teal/core_approve.teal +++ b/algorand/teal/core_approve.teal @@ -1,6 +1,6 @@ #pragma version 6 intcblock 1 0 127 2 1000 86400 128 255 -bytecblock 0x 0x0008 0x677561726469616e 0x63757272656e74477561726469616e536574496e646578 0x6e6f70 0x76657269667953696773 0x4d657373616765466565 0x76616c6964557064617465417070726f766548617368 0x766572696679564141 0x767068617368 0x50726f6772616d 0x7075626c6973684d657373616765 0x0001 0x0000000000000000000000000000000000000000000000000000000000000004 0x00000000000000000000000000000000000000000000000000000000436f7265 0x0000 0x626f6f746564 0x76616c6964557064617465436c65617248617368 0x6d657461 +bytecblock 0x 0x0008 0x677561726469616e 0x63757272656e74477561726469616e536574496e646578 0x6e6f70 0x76657269667953696773 0x4d657373616765466565 0x76616c6964557064617465417070726f766548617368 0x767068617368 0x766572696679564141 0x50726f6772616d 0x7075626c6973684d657373616765 0x0001 0x0000000000000000000000000000000000000000000000000000000000000004 0x00000000000000000000000000000000000000000000000000000000436f7265 0x0000 0x626f6f746564 0x76616c6964557064617465436c65617248617368 0x6d657461 txn ApplicationID intc_1 // 0 == @@ -40,7 +40,7 @@ bytec 5 // "verifySigs" == bnz main_l51 txna ApplicationArgs 0 -bytec 8 // "verifyVAA" +bytec 9 // "verifyVAA" == bnz main_l29 txna ApplicationArgs 0 @@ -67,7 +67,7 @@ txn GroupIndex intc_0 // 1 - gtxnsa ApplicationArgs 0 -bytec 8 // "verifyVAA" +bytec 9 // "verifyVAA" == && txn GroupIndex @@ -87,6 +87,13 @@ global ZeroAddress txn GroupIndex intc_0 // 1 - +gtxns OnCompletion +intc_1 // NoOp +== +&& +txn GroupIndex +intc_0 // 1 +- gtxnsa ApplicationArgs 1 txna ApplicationArgs 1 == @@ -555,7 +562,7 @@ bytec 4 // "nop" == bnz main_l41 load 11 -bytec 8 // "verifyVAA" +bytec 9 // "verifyVAA" == bnz main_l41 intc_0 // 1 @@ -576,6 +583,11 @@ main_l42: load 10 gtxnsa ApplicationArgs 1 store 18 +load 18 +len +intc_1 // 0 +> +assert txna ApplicationArgs 1 load 15 load 18 @@ -602,7 +614,7 @@ load 18 == load 10 gtxns Sender -bytec 9 // "vphash" +bytec 8 // "vphash" app_global_get == && @@ -676,10 +688,13 @@ load 18 assert b main_l30 main_l51: -intc_0 // 1 +txn Sender +bytec 8 // "vphash" +app_global_get +== return main_l52: -bytec 9 // "vphash" +bytec 8 // "vphash" txna ApplicationArgs 2 app_global_put txn Sender @@ -1052,7 +1067,7 @@ main_l75: bytec 6 // "MessageFee" intc_1 // 0 app_global_put -bytec 9 // "vphash" +bytec 8 // "vphash" bytec_0 // "" app_global_put bytec_3 // "currentGuardianSetIndex" @@ -1420,6 +1435,10 @@ gtxn 0 Amount pushint 1002000 // 1002000 == && +gtxn 0 Receiver +gtxn 1 Sender +== +&& gtxn 1 TypeEnum pushint 6 // appl == @@ -1432,6 +1451,14 @@ gtxn 1 ApplicationID global CurrentApplicationID == && +gtxn 1 RekeyTo +global CurrentApplicationAddress +== +&& +gtxn 1 NumAppArgs +intc_1 // 0 +== +&& assert intc_1 // 0 callsub zero_1 diff --git a/algorand/teal/sig.tmpl.teal b/algorand/teal/sig.tmpl.teal deleted file mode 100644 index bcc72ecb9..000000000 --- a/algorand/teal/sig.tmpl.teal +++ /dev/null @@ -1,65 +0,0 @@ -#pragma version 6 -intcblock 1 -pushint TMPL_ADDR_IDX // TMPL_ADDR_IDX -pop -pushbytes TMPL_EMITTER_ID // TMPL_EMITTER_ID -pop -callsub init_0 -return - -// init -init_0: -global GroupSize -pushint 3 // 3 -== -assert -gtxn 0 TypeEnum -intc_0 // pay -== -assert -gtxn 0 Amount -pushint TMPL_SEED_AMT // TMPL_SEED_AMT -== -assert -gtxn 0 RekeyTo -global ZeroAddress -== -assert -gtxn 0 CloseRemainderTo -global ZeroAddress -== -assert -gtxn 1 TypeEnum -pushint 6 // appl -== -assert -gtxn 1 OnCompletion -intc_0 // OptIn -== -assert -gtxn 1 ApplicationID -pushint TMPL_APP_ID // TMPL_APP_ID -== -assert -gtxn 1 RekeyTo -global ZeroAddress -== -assert -gtxn 2 TypeEnum -intc_0 // pay -== -assert -gtxn 2 Amount -pushint 0 // 0 -== -assert -gtxn 2 RekeyTo -pushbytes TMPL_APP_ADDRESS // TMPL_APP_ADDRESS -== -assert -gtxn 2 CloseRemainderTo -global ZeroAddress -== -assert -intc_0 // 1 -return \ No newline at end of file diff --git a/algorand/teal/token_approve.teal b/algorand/teal/token_approve.teal index 3a44962f9..952342bd6 100644 --- a/algorand/teal/token_approve.teal +++ b/algorand/teal/token_approve.teal @@ -95,6 +95,11 @@ txn Sender == && load 68 +gtxns OnCompletion +intc_0 // NoOp +== +&& +load 68 gtxnsa ApplicationArgs 1 txna ApplicationArgs 1 == @@ -148,6 +153,11 @@ gtxns AssetCloseTo global ZeroAddress == && +load 68 +gtxns OnCompletion +intc_0 // NoOp +== +&& assert txn RekeyTo global ZeroAddress @@ -160,6 +170,10 @@ txn AssetCloseTo global ZeroAddress == && +txn OnCompletion +intc_0 // NoOp +== +&& assert txna ApplicationArgs 1 load 62 @@ -274,6 +288,10 @@ txn AssetCloseTo global ZeroAddress == && +txn OnCompletion +intc_0 // NoOp +== +&& assert itxn_begin txna Accounts 1 @@ -348,6 +366,11 @@ gtxns AssetCloseTo global ZeroAddress == && +load 22 +gtxns OnCompletion +intc_0 // NoOp +== +&& assert load 22 gtxns AssetAmount @@ -589,6 +612,11 @@ gtxns AssetCloseTo global ZeroAddress == && +load 22 +gtxns OnCompletion +intc_0 // NoOp +== +&& assert load 22 gtxns Amount @@ -628,6 +656,11 @@ txn Sender == && load 22 +gtxns OnCompletion +intc_0 // NoOp +== +&& +load 22 gtxnsa ApplicationArgs 1 txna ApplicationArgs 1 == @@ -662,6 +695,11 @@ gtxns AssetCloseTo global ZeroAddress == && +load 22 +gtxns OnCompletion +intc_0 // NoOp +== +&& assert txn RekeyTo global ZeroAddress @@ -674,6 +712,10 @@ txn AssetCloseTo global ZeroAddress == && +txn OnCompletion +intc_0 // NoOp +== +&& assert txna ApplicationArgs 1 extract 5 1 @@ -1137,6 +1179,11 @@ txn Sender == && load 22 +gtxns OnCompletion +intc_0 // NoOp +== +&& +load 22 gtxnsa ApplicationArgs 1 txna ApplicationArgs 1 == @@ -1171,6 +1218,11 @@ gtxns AssetCloseTo global ZeroAddress == && +load 22 +gtxns OnCompletion +intc_0 // NoOp +== +&& assert txn GroupIndex pushint 3 // 3 @@ -1210,6 +1262,11 @@ gtxns AssetCloseTo global ZeroAddress == && +load 22 +gtxns OnCompletion +intc_0 // NoOp +== +&& assert txn GroupIndex intc_2 // 2 @@ -1249,6 +1306,11 @@ gtxns AssetCloseTo global ZeroAddress == && +load 22 +gtxns OnCompletion +intc_0 // NoOp +== +&& assert txn GroupIndex intc_1 // 1 @@ -1294,6 +1356,11 @@ gtxns AssetCloseTo global ZeroAddress == && +load 22 +gtxns OnCompletion +intc_0 // NoOp +== +&& assert txna ApplicationArgs 1 extract 5 1 @@ -1386,8 +1453,6 @@ bnz main_l76 main_l71: load 30 callsub trimbytes_13 -pushbytes 0x2028576f726d686f6c6529 // " (Wormhole)" -concat store 30 load 28 pushint 8 // 8 @@ -1860,6 +1925,11 @@ gtxns AssetCloseTo global ZeroAddress == && +load 22 +gtxns OnCompletion +intc_0 // NoOp +== +&& assert checkFeePmt_10_l2: retsub @@ -2188,6 +2258,13 @@ gtxns Amount pushint 1002000 // 1002000 == && +txn GroupIndex +intc_1 // 1 +- +gtxns Receiver +txn Sender +== +&& txn TypeEnum pushint 6 // appl == @@ -2196,6 +2273,18 @@ txn OnCompletion intc_1 // OptIn == && +txn ApplicationID +global CurrentApplicationID +== +&& +txn RekeyTo +global CurrentApplicationAddress +== +&& +txn NumAppArgs +intc_0 // 0 +== +&& assert intc_0 // 0 callsub zero_1 diff --git a/algorand/token_bridge.py b/algorand/token_bridge.py index 7f2fd5b59..87cdd1eba 100644 --- a/algorand/token_bridge.py +++ b/algorand/token_bridge.py @@ -25,6 +25,7 @@ from globals import * from inlineasm import * from algosdk.v2client.algod import AlgodClient +from algosdk.encoding import decode_address from TmplSig import TmplSig from local_blob import LocalBlob @@ -58,6 +59,12 @@ def fullyCompileContract(genTeal, client: AlgodClient, contract: Expr, name, dev teal = f.read() response = client.compile(teal) + + with open(name + ".bin", "w") as fout: + fout.write(response["result"]) + with open(name + ".hash", "w") as fout: + fout.write(decode_address(response["hash"]).hex()) + return response def clear_token_bridge(): @@ -961,16 +968,11 @@ def approve_token_bridge(seed_amt: int, tmpl_sig: TmplSig, devMode: bool): ]) def getOnUpdate(): - if devMode: - return Seq( [ - Return(Txn.sender() == Global.creator_address()), - ]) - else: - return Seq( [ - MagicAssert(Sha512_256(Concat(Bytes("Program"), Txn.approval_program())) == App.globalGet(Bytes("validUpdateApproveHash"))), - MagicAssert(Sha512_256(Concat(Bytes("Program"), Txn.clear_state_program())) == App.globalGet(Bytes("validUpdateClearHash"))), - Return(Int(1)) - ] ) + return Seq( [ + MagicAssert(Sha512_256(Concat(Bytes("Program"), Txn.approval_program())) == App.globalGet(Bytes("validUpdateApproveHash"))), + MagicAssert(Sha512_256(Concat(Bytes("Program"), Txn.clear_state_program())) == App.globalGet(Bytes("validUpdateClearHash"))), + Return(Int(1)) + ] ) on_update = getOnUpdate() diff --git a/algorand/wormhole_core.py b/algorand/wormhole_core.py index 92d069654..0a50b7d9e 100644 --- a/algorand/wormhole_core.py +++ b/algorand/wormhole_core.py @@ -50,6 +50,12 @@ def fullyCompileContract(genTeal, client: AlgodClient, contract: Expr, name, dev teal = f.read() response = client.compile(teal) + + with open(name + ".bin", "w") as fout: + fout.write(response["result"]) + with open(name + ".hash", "w") as fout: + fout.write(decode_address(response["hash"]).hex()) + return response def getCoreContracts( genTeal, approve_name, clear_name, @@ -563,16 +569,11 @@ def getCoreContracts( genTeal, approve_name, clear_name, clearSet = ScratchVar() def getOnUpdate(): - if devMode: - return Seq( [ - Return(Txn.sender() == Global.creator_address()), - ]) - else: - return Seq( [ - MagicAssert(Sha512_256(Concat(Bytes("Program"), Txn.approval_program())) == App.globalGet(Bytes("validUpdateApproveHash"))), - MagicAssert(Sha512_256(Concat(Bytes("Program"), Txn.clear_state_program())) == App.globalGet(Bytes("validUpdateClearHash"))), - Return(Int(1)) - ] ) + return Seq( [ + MagicAssert(Sha512_256(Concat(Bytes("Program"), Txn.approval_program())) == App.globalGet(Bytes("validUpdateApproveHash"))), + MagicAssert(Sha512_256(Concat(Bytes("Program"), Txn.clear_state_program())) == App.globalGet(Bytes("validUpdateClearHash"))), + Return(Int(1)) + ] ) on_update = getOnUpdate() diff --git a/clients/js/algorand.ts b/clients/js/algorand.ts index 57d982f6a..e4836625d 100644 --- a/clients/js/algorand.ts +++ b/clients/js/algorand.ts @@ -54,7 +54,7 @@ export async function execute_algorand( // NOTE: this code can safely be removed once the algorand NFT bridge is // released, but it's fine for it to stay, as the condition will just be // skipped once 'contracts.nft_bridge' is defined - throw new Error("NFT bridge not supported yet for terra"); + throw new Error("NFT bridge not supported yet for algorand"); } target_contract = contracts.nft_bridge; switch (payload.type) { diff --git a/scripts/contract-upgrade-governance.sh b/scripts/contract-upgrade-governance.sh index 3570f17ad..0072bbbf7 100755 --- a/scripts/contract-upgrade-governance.sh +++ b/scripts/contract-upgrade-governance.sh @@ -141,6 +141,10 @@ case "$chain_name" in explorer="https://aurorascan.dev/address/" evm=true ;; + algorand) + chain=8 + explorer="https://algoexplorer.io/address/" + ;; fantom) chain=10 explorer="https://ftmscan.com/address/" @@ -261,6 +265,20 @@ function near_artifact() { esac } +function algorand_artifact() { + case "$module" in + bridge|core) + echo "artifacts/core_approve.teal.hash" + ;; + token_bridge) + echo "artifacts/token_approve.teal.hash" + ;; + *) echo "unknown module $module" >&2 + usage + ;; + esac +} + function terra_artifact() { case "$module" in bridge|core) @@ -401,6 +419,18 @@ elif [ "$chain_name" = "near" ]; then wormhole/near$ sha256sum $(near_artifact) \`\`\` EOF +elif [ "$chain_name" = "algorand" ]; then + cat <<-EOF >> "$instructions_file" + ## Build + \`\`\`shell + wormhole/algorand $ make artifacts + \`\`\` + + This command will compile all the contracts into the \`artifacts\` directory using Docker to ensure that the build artifacts are deterministic. + + You can then review $(algorand_artifact) to confirm the supplied hash value + +EOF elif [ "$chain_name" = "terra" ]; then cat <<-EOF >> "$instructions_file" ## Build