tx · FANvdUD69AmAbDDCwtvkxuKJzLMN9ehHWEFBEepVWrrp

3MuGfNhF98CNBCfthhoJEo6SYUv7zTgkK4J:  -0.04000000 Waves

2022.07.29 14:05 [2161025] smart account 3MuGfNhF98CNBCfthhoJEo6SYUv7zTgkK4J > SELF 0.00000000 Waves

{ "type": 13, "id": "FANvdUD69AmAbDDCwtvkxuKJzLMN9ehHWEFBEepVWrrp", "fee": 4000000, "feeAssetId": null, "timestamp": 1659092778489, "version": 1, "sender": "3MuGfNhF98CNBCfthhoJEo6SYUv7zTgkK4J", "senderPublicKey": "4DthuG3xjZV9WtZ34Y66AummdAr67wRzwWsVQL4y2bob", "proofs": [ "3Zsawxppaui4FhHAF6mjoja2BguJpHoTiyyzrR9CcVsmcnbADem6NdvdBsnrsMBJy2Mm6Z59QUduUv9yMT6pGgxq", "46yzSwutUWcA1uJLHYbMDyz4GgRoTZLoBSA5xxetV6Wa4AduCoMeoQYKBg2d1euhGphX26rtJkaKtgSPWk4epMwr", "2P4srFV7KZt66twwgKsKPWzGkme2UKyNFhmeXn6TgVh3FTk8EToU6jf44bMzVXGnGpFEdwGSF9cqW1aCPvsB1FR1" ], "script": "base64:AAIFAAAAAAAAACAIAhIHCgUICAEBCBIAEgMKAQESABIAEgMKAQgSAwoBCAAAAEYAAAAACXNlcGFyYXRvcgIAAAACX18AAAAAA1NFUAIAAAACX18AAAAABU1VTFQ2AAAAAAAAD0JAAAAAAAVNVUxUOAAAAAAABfXhAAAAAAAGTVVMVFg2CQABNgAAAAEFAAAABU1VTFQ2AAAAAAZNVUxUWDgJAAE2AAAAAQUAAAAFTVVMVDgAAAAAB01VTFRYMTgJAAE2AAAAAQAN4Lazp2QAAAAAAAAKV0FWRVNJRFNUUgIAAAAFV0FWRVMAAAAAB1dBVkVTSUQJAAJZAAAAAQUAAAAKV0FWRVNJRFNUUgAAAAAZSWR4Q29udHJvbENmZ05ldXRyaW5vRGFwcAAAAAAAAAAAAQAAAAAYSWR4Q29udHJvbENmZ0F1Y3Rpb25EYXBwAAAAAAAAAAACAAAAABRJZHhDb250cm9sQ2ZnUnBkRGFwcAAAAAAAAAAAAwAAAAAVSWR4Q29udHJvbENmZ01hdGhEYXBwAAAAAAAAAAAEAAAAABxJZHhDb250cm9sQ2ZnTGlxdWlkYXRpb25EYXBwAAAAAAAAAAAFAAAAABVJZHhDb250cm9sQ2ZnUmVzdERhcHAAAAAAAAAAAAYAAAAAHUlkeENvbnRyb2xDZmdOb2RlUmVnaXN0cnlEYXBwAAAAAAAAAAAHAAAAABxJZHhDb250cm9sQ2ZnTnNidFN0YWtpbmdEYXBwAAAAAAAAAAAIAAAAABlJZHhDb250cm9sQ2ZnTWVkaWF0b3JEYXBwAAAAAAAAAAAJAQAAAA9nZXRTdHJpbmdPckZhaWwAAAACAAAAB2FkZHJlc3MAAAADa2V5CQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAHYWRkcmVzcwUAAAADa2V5CQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAACm1hbmRhdG9yeSAJAAQlAAAAAQUAAAAHYWRkcmVzcwIAAAABLgUAAAADa2V5AgAAAA8gaXMgbm90IGRlZmluZWQBAAAAEWtleUNvbnRyb2xBZGRyZXNzAAAAAAIAAAAcJXMlc19fY29uZmlnX19jb250cm9sQWRkcmVzcwEAAAANa2V5Q29udHJvbENmZwAAAAACAAAAESVzX19jb250cm9sQ29uZmlnAQAAABRyZWFkQ29udHJvbENmZ09yRmFpbAAAAAEAAAAHY29udHJvbAkABLUAAAACCQEAAAAPZ2V0U3RyaW5nT3JGYWlsAAAAAgUAAAAHY29udHJvbAkBAAAADWtleUNvbnRyb2xDZmcAAAAABQAAAANTRVABAAAAGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAAAAAIAAAAKY29udHJvbENmZwAAAANpZHgJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABCYAAAABCQABkQAAAAIFAAAACmNvbnRyb2xDZmcFAAAAA2lkeAkAASwAAAACAgAAAC1Db250cm9sIGNmZyBkb2Vzbid0IGNvbnRhaW4gYWRkcmVzcyBhdCBpbmRleCAJAAGkAAAAAQUAAAADaWR4AAAAAA9jb250cm9sQ29udHJhY3QJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwkBAAAAEWtleUNvbnRyb2xBZGRyZXNzAAAAAAIAAAAjM040TlM3ZDRKbzlhNkYxNExpRlVLS1lWZFVra2YyZVA0WngAAAAACmNvbnRyb2xDZmcJAQAAABRyZWFkQ29udHJvbENmZ09yRmFpbAAAAAEFAAAAD2NvbnRyb2xDb250cmFjdAAAAAAMbWF0aENvbnRyYWN0CQEAAAAYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAAAAAgUAAAAKY29udHJvbENmZwUAAAAVSWR4Q29udHJvbENmZ01hdGhEYXBwAAAAABBuZXV0cmlub0NvbnRyYWN0CQEAAAAYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAAAAAgUAAAAKY29udHJvbENmZwUAAAAZSWR4Q29udHJvbENmZ05ldXRyaW5vRGFwcAAAAAAPYXVjdGlvbkNvbnRyYWN0CQEAAAAYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAAAAAgUAAAAKY29udHJvbENmZwUAAAAYSWR4Q29udHJvbENmZ0F1Y3Rpb25EYXBwAQAAAAxrZXlCb25kQXNzZXQAAAAAAgAAAA1ib25kX2Fzc2V0X2lkAQAAABprZXlOZXV0cmlub0NvbnRyYWN0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bW91bnQAAAAIb2xkU3RhcnQAAAAJbmV3QW1vdW50AAAACG5ld1N0YXJ0CQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAAQa2V5SGlzdG9yeVJlY29yZAAAAAMFAAAABHR5cGUFAAAAC3VzZXJBZGRyZXNzBQAAAAR0eElkCQEAAAATZm9ybWF0SGlzdG9yeVJlY29yZAAAAAQFAAAACW9sZEFtb3VudAUAAAAIb2xkU3RhcnQFAAAACW5ld0Ftb3VudAUAAAAIbmV3U3RhcnQBAAAAEUNsYWltSGlzdG9yeUVudHJ5AAAAAwAAAAt1c2VyQWRkcmVzcwAAAAR0eElkAAAADmNsYWltZWRSZXdhcmRzCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAAQa2V5SGlzdG9yeVJlY29yZAAAAAMCAAAABWNsYWltBQAAAAt1c2VyQWRkcmVzcwUAAAAEdHhJZAkBAAAAGGZvcm1hdENsYWltSGlzdG9yeVJlY29yZAAAAAIJAAQlAAAAAQUAAAALdXNlckFkZHJlc3MFAAAADmNsYWltZWRSZXdhcmRzAQAAAAtTdGF0c1Jlc3VsdAAAAAMAAAAOdG90YWxMb2NrZWRJbmMAAAAMbG9ja0NvdW50SW5jAAAADXVzZXJzQ291bnRJbmMEAAAACmxvY2tzQ291bnQJAQAAAAxnZXRJbnRPclplcm8AAAABCQEAAAASa2V5U3RhdHNMb2Nrc0NvdW50AAAAAAQAAAAKdXNlcnNDb3VudAkBAAAADGdldEludE9yWmVybwAAAAEJAQAAABJrZXlTdGF0c1VzZXJzQ291bnQAAAAABAAAAAt0b3RhbEFtb3VudAkBAAAADGdldEludE9yWmVybwAAAAEJAQAAABdrZXlMb2NrUGFyYW1Ub3RhbEFtb3VudAAAAAAEAAAADnRvdGFsQW1vdW50TmV3CQAAZAAAAAIFAAAAC3RvdGFsQW1vdW50BQAAAA50b3RhbExvY2tlZEluYwkABRUAAAADCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAASa2V5U3RhdHNMb2Nrc0NvdW50AAAAAAkAAGQAAAACBQAAAApsb2Nrc0NvdW50BQAAAAxsb2NrQ291bnRJbmMJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAABJrZXlTdGF0c1VzZXJzQ291bnQAAAAACQAAZAAAAAIFAAAACnVzZXJzQ291bnQFAAAADXVzZXJzQ291bnRJbmMJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAABdrZXlMb2NrUGFyYW1Ub3RhbEFtb3VudAAAAAAFAAAADnRvdGFsQW1vdW50TmV3BQAAAANuaWwFAAAAC3RvdGFsQW1vdW50BQAAAA50b3RhbEFtb3VudE5ldwEAAAAPTG9ja1BhcmFtc0VudHJ5AAAAAwAAAAt1c2VyQWRkcmVzcwAAAAZhbW91bnQAAAAFc3RhcnQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAABZrZXlMb2NrUGFyYW1Vc2VyQW1vdW50AAAAAQUAAAALdXNlckFkZHJlc3MFAAAABmFtb3VudAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAAFmtleUxvY2tQYXJhbVN0YXJ0QmxvY2sAAAABBQAAAAt1c2VyQWRkcmVzcwUAAAAFc3RhcnQFAAAAA25pbAEAAAAPZ2V0UGFyYW1zT3JGYWlsAAAAAAkABRUAAAADCQACWQAAAAEJAQAAABFAZXh0ck5hdGl2ZSgxMDUzKQAAAAIFAAAAEG5ldXRyaW5vQ29udHJhY3QJAQAAAAxrZXlCb25kQXNzZXQAAAAACQEAAAAMZ2V0SW50T3JGYWlsAAAAAQkBAAAAEGtleU1pbkxvY2tBbW91bnQAAAAACQEAAAAMZ2V0SW50T3JGYWlsAAAAAQkBAAAAC2tleUhhbGZMaWZlAAAAAAEAAAAMaXNBY3RpdmVVc2VyAAAAAQAAAAt1c2VyQWRkcmVzcwkAAGYAAAACCQEAAAAMZ2V0SW50T3JFbHNlAAAAAgkBAAAAFmtleUxvY2tQYXJhbVVzZXJBbW91bnQAAAABBQAAAAt1c2VyQWRkcmVzcwAAAAAAAAAAAAAAAAAAAAAAAAEAAAATZ2V0VXNlclBhcmFtc09yVW5pdAAAAAEAAAALdXNlckFkZHJlc3MDCQEAAAAMaXNBY3RpdmVVc2VyAAAAAQUAAAALdXNlckFkZHJlc3MJAAUVAAAAAwcJAQAAAAxnZXRJbnRPckZhaWwAAAABCQEAAAAWa2V5TG9ja1BhcmFtVXNlckFtb3VudAAAAAEFAAAAC3VzZXJBZGRyZXNzCQEAAAAMZ2V0SW50T3JGYWlsAAAAAQkBAAAAFmtleUxvY2tQYXJhbVN0YXJ0QmxvY2sAAAABBQAAAAt1c2VyQWRkcmVzcwUAAAAEdW5pdAEAAAATZ2V0VXNlclBhcmFtc09yRmFpbAAAAAEAAAALdXNlckFkZHJlc3MJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkBAAAAE2dldFVzZXJQYXJhbXNPclVuaXQAAAABBQAAAAt1c2VyQWRkcmVzcwkAASwAAAACCQABLAAAAAICAAAABVVzZXIgCQAEJQAAAAEFAAAAC3VzZXJBZGRyZXNzAgAAAA8gaXMgbm90IGRlZmluZWQAAAAAEnN1cHBvcnRlZEFzc2V0c1N0cgkBAAAADGdldFN0ck9yRWxzZQAAAAIJAQAAABhrZXlTdXBwb3J0ZWRSZXdhcmRBc3NldHMAAAAAAgAAAAAAAAAAE3N1cHBvcnRlZEFzc2V0c0xpc3QJAAS1AAAAAgUAAAASc3VwcG9ydGVkQXNzZXRzU3RyAgAAAAFfAQAAAApjYWxjUmV3YXJkAAAABQAAAAt1c2VyQWRkcmVzcwAAAAdhc3NldElkAAAADXN0YWtlZEFtb3VudFgAAAAOZGVwb3NpdE51bVVzZXIAAAAOZGVwb3NpdE51bUxhc3QEAAAAF3Jld2FyZFBlck5zYnRTdW1MYXN0S0VZCQEAAAAVa2V5UmV3YXJkUGVyTnNidFN1bUF0AAAAAgUAAAAOZGVwb3NpdE51bUxhc3QFAAAAB2Fzc2V0SWQEAAAACnN1bUxhc3RYMTgJAAGnAAAAAQkBAAAADGdldFN0ck9yRWxzZQAAAAIJAQAAABVrZXlSZXdhcmRQZXJOc2J0U3VtQXQAAAACBQAAAA5kZXBvc2l0TnVtTGFzdAUAAAAHYXNzZXRJZAIAAAABMAQAAAAKc3VtVXNlclgxOAkAAacAAAABCQEAAAAMZ2V0U3RyT3JFbHNlAAAAAgkBAAAAFWtleVJld2FyZFBlck5zYnRTdW1BdAAAAAIFAAAADmRlcG9zaXROdW1Vc2VyBQAAAAdhc3NldElkAgAAAAEwBAAAABFyZXdhcmREeW5hbWljUGFydAkAAaAAAAABCQABPAAAAAMJAAE4AAAAAgUAAAAKc3VtTGFzdFgxOAUAAAAKc3VtVXNlclgxOAUAAAANc3Rha2VkQW1vdW50WAUAAAAHTVVMVFgxOAQAAAATcmV3YXJkQ2FjaGVkUGFydEtFWQkBAAAACWtleVJld2FyZAAAAAIFAAAAC3VzZXJBZGRyZXNzBQAAAAdhc3NldElkBAAAABByZXdhcmRDYWNoZWRQYXJ0CQEAAAAMZ2V0SW50T3JFbHNlAAAAAgUAAAATcmV3YXJkQ2FjaGVkUGFydEtFWQAAAAAAAAAAAAkABRYAAAAECQAAZAAAAAIFAAAAEHJld2FyZENhY2hlZFBhcnQFAAAAEXJld2FyZER5bmFtaWNQYXJ0BQAAABByZXdhcmRDYWNoZWRQYXJ0BQAAABFyZXdhcmREeW5hbWljUGFydAUAAAATcmV3YXJkQ2FjaGVkUGFydEtFWQEAAAANUmV3YXJkRW50cmllcwAAAAMAAAAJaXNOZXdVc2VyAAAAC3VzZXJBZGRyZXNzAAAADHN0YWtlZEFtb3VudAQAAAANc3Rha2VkQW1vdW50WAkAATYAAAABBQAAAAxzdGFrZWRBbW91bnQEAAAAG3VzZXJSZXdhcmRGcm9tRGVwb3NpdE51bUtFWQkBAAAAG2tleVVzZXJSZXdhcmRGcm9tRGVwb3NpdE51bQAAAAEFAAAAC3VzZXJBZGRyZXNzBAAAAA5kZXBvc2l0TnVtVXNlcgkBAAAADGdldEludE9yRWxzZQAAAAIFAAAAG3VzZXJSZXdhcmRGcm9tRGVwb3NpdE51bUtFWQD//////////wQAAAAOZGVwb3NpdE51bUxhc3QJAQAAAAxnZXRJbnRPckVsc2UAAAACCQEAAAARa2V5RGVwb3NpdE51bUxhc3QAAAAAAP//////////CgEAAAAbZm9yRWFjaEFzc2V0Q2FjaGVVc2VyUmV3YXJkAAAAAgAAAAVhY2N1bQAAAAVhc3NldAQAAAALJHQwODQwOTg1NDQJAQAAAApjYWxjUmV3YXJkAAAABQUAAAALdXNlckFkZHJlc3MFAAAABWFzc2V0BQAAAA1zdGFrZWRBbW91bnRYBQAAAA5kZXBvc2l0TnVtVXNlcgUAAAAOZGVwb3NpdE51bUxhc3QEAAAAC3Jld2FyZFRvdGFsCAUAAAALJHQwODQwOTg1NDQAAAAC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AgkBAAAABSRmMF8xAAAAAgkBAAAABSRmMF8xAAAAAgkBAAAABSRmMF8xAAAAAgkBAAAABSRmMF8xAAAAAgkBAAAABSRmMF8xAAAAAgUAAAAFJGFjYzAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAIAAAAAAAAAAAMAAAAAAAAAAAQAAAAAAAAAAAUAAAAAAAAAAAYAAAAAAAAAAAcAAAAAAAAAAAgAAAAAAAAAAAkAAAAAAAAAAAoJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABt1c2VyUmV3YXJkRnJvbURlcG9zaXROdW1LRVkFAAAADmRlcG9zaXROdW1MYXN0CQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAJHVuY292ZXJlZCBjb25kaXRpb246IGRlcG9zaXROdW1MYXN0PQkAAaQAAAABBQAAAA5kZXBvc2l0TnVtTGFzdAIAAAAQIGRlcG9zaXROdW1Vc2VyPQkAAaQAAAABBQAAAA5kZXBvc2l0TnVtVXNlcgEAAAAiSW5jcmVtZW50Tm90RGlzdHJpYnV0ZWRSZXdhcmRFbnRyeQAAAAIAAAADdGtuAAAACWFtb3VudEluYwQAAAAXbm90RGlzdHJpYnV0ZWRSZXdhcmRLRVkJAQAAABdrZXlOb3REaXN0cmlidXRlZFJld2FyZAAAAAEFAAAAA3RrbgQAAAAUbm90RGlzdHJpYnV0ZWRSZXdhcmQJAQAAAAxnZXRJbnRPckVsc2UAAAACBQAAABdub3REaXN0cmlidXRlZFJld2FyZEtFWQAAAAAAAAAAAAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAXbm90RGlzdHJpYnV0ZWRSZXdhcmRLRVkJAABkAAAAAgUAAAAUbm90RGlzdHJpYnV0ZWRSZXdhcmQFAAAACWFtb3VudEluYwUAAAADbmlsAAAABwAAAAFpAQAAAAtjb25zdHJ1Y3RvcgAAAAUAAAAXbmV1dHJpbm9Db250cmFjdEFkZHJlc3MAAAATbWF0aENvbnRyYWN0QWRkcmVzcwAAAA1taW5Mb2NrQW1vdW50AAAACGhhbGZMaWZlAAAAFXN1cHBvcnRlZFJld2FyZEFzc2V0cwMJAQAAAAIhPQAAAAIIBQAAAAFpAAAABmNhbGxlcgUAAAAEdGhpcwkAAAIAAAABAgAAABFQZXJtaXNzaW9uIGRlbmllZAkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAAaa2V5TmV1dHJpbm9Db250cmFjdEFkZHJlc3MAAAAABQAAABduZXV0cmlub0NvbnRyYWN0QWRkcmVzcwkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAAWa2V5TWF0aENvbnRyYWN0QWRkcmVzcwAAAAAFAAAAE21hdGhDb250cmFjdEFkZHJlc3MJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAABBrZXlNaW5Mb2NrQW1vdW50AAAAAAUAAAANbWluTG9ja0Ftb3VudAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAAC2tleUhhbGZMaWZlAAAAAAUAAAAIaGFsZkxpZmUJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAGGtleVN1cHBvcnRlZFJld2FyZEFzc2V0cwAAAAAFAAAAFXN1cHBvcnRlZFJld2FyZEFzc2V0cwUAAAADbmlsAAAAAWkBAAAABXN0YWtlAAAAAAQAAAANJHQwMTIyMTgxMjI4MAkBAAAAD2dldFBhcmFtc09yRmFpbAAAAAAEAAAAC2JvbmRBc3NldElkCAUAAAANJHQwMTIyMTgxMjI4MAAAAAJfMQQAAAANbWluTG9ja0Ftb3VudAgFAAAADSR0MDEyMjE4MTIyODAAAAACXzIEAAAACGhhbGZMaWZlCAUAAAANJHQwMTIyMTgxMjI4MAAAAAJfMwMJAQAAAAIhPQAAAAIJAAGQAAAAAQgFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAEJAAACAAAAAQIAAAAVSW52YWxpZCBwYXltZW50cyBzaXplBAAAAAdwYXltZW50CQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAABAAAAAZhbW91bnQIBQAAAAdwYXltZW50AAAABmFtb3VudAQAAAATaW52YWxpZEFzc2V0TWVzc2FnZQkAASwAAAACCQABLAAAAAICAAAAD0ludmFsaWQgYXNzZXQuIAkAAlgAAAABBQAAAAtib25kQXNzZXRJZAIAAAAMIGlzIGV4cGVjdGVkBAAAAAdhc3NldElkCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIIBQAAAAdwYXltZW50AAAAB2Fzc2V0SWQFAAAAE2ludmFsaWRBc3NldE1lc3NhZ2UDCQEAAAACIT0AAAACBQAAAAdhc3NldElkBQAAAAtib25kQXNzZXRJZAkAAAIAAAABBQAAABNpbnZhbGlkQXNzZXRNZXNzYWdlBAAAAAt1c2VyQWRkcmVzcwgFAAAAAWkAAAAGY2FsbGVyBAAAAA51c2VyQWRkcmVzc1N0cgkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIEAAAADSR0MDEyODIyMTI5MjkJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAQAAABNnZXRVc2VyUGFyYW1zT3JVbml0AAAAAQUAAAALdXNlckFkZHJlc3MJAAUVAAAAAwYAAAAAAAAAAAAA//////////8EAAAACWlzTmV3VXNlcggFAAAADSR0MDEyODIyMTI5MjkAAAACXzEEAAAACmxvY2tBbW91bnQIBQAAAA0kdDAxMjgyMjEyOTI5AAAAAl8yBAAAAA9sb2NrU3RhcnRIZWlnaHQIBQAAAA0kdDAxMjgyMjEyOTI5AAAAAl8zBAAAAAxtZXJnZWRBbW91bnQDBQAAAAlpc05ld1VzZXIFAAAABmFtb3VudAkAAGQAAAACBQAAAAZhbW91bnQFAAAACmxvY2tBbW91bnQEAAAAEW1lcmdlZFN0YXJ0SGVpZ2h0AwUAAAAJaXNOZXdVc2VyBQAAAAZoZWlnaHQJAQAAAAVhc0ludAAAAAEJAAP8AAAABAUAAAAMbWF0aENvbnRyYWN0AgAAABNtZXJnZVN0YWtlc1JFQURPTkxZCQAETAAAAAIFAAAABmFtb3VudAkABEwAAAACBQAAAAZoZWlnaHQJAARMAAAAAgUAAAAKbG9ja0Ftb3VudAkABEwAAAACBQAAAA9sb2NrU3RhcnRIZWlnaHQJAARMAAAAAgUAAAAIaGFsZkxpZmUFAAAAA25pbAUAAAADbmlsAwkAAGYAAAACBQAAAA1taW5Mb2NrQW1vdW50BQAAAAxtZXJnZWRBbW91bnQJAAACAAAAAQkAASwAAAACAgAAABNNaW4gbG9jayBhbW91bnQgaXMgCQABpAAAAAEFAAAADW1pbkxvY2tBbW91bnQEAAAADSR0MDEzMjkwMTMzOTIJAQAAAAtTdGF0c1Jlc3VsdAAAAAMFAAAABmFtb3VudAAAAAAAAAAAAQMFAAAACWlzTmV3VXNlcgAAAAAAAAAAAQAAAAAAAAAAAAQAAAAMc3RhdHNFbnRyaWVzCAUAAAANJHQwMTMyOTAxMzM5MgAAAAJfMQQAAAALdG90YWxTdGFrZWQIBQAAAA0kdDAxMzI5MDEzMzkyAAAAAl8yBAAAAA50b3RhbFN0YWtlZE5ldwgFAAAADSR0MDEzMjkwMTMzOTIAAAACXzMJAAROAAAAAgkABE4AAAACCQAETgAAAAIJAARMAAAAAgkBAAAAEkhpc3RvcnlSZWNvcmRFbnRyeQAAAAcCAAAABXN0YWtlBQAAAAt1c2VyQWRkcmVzcwgFAAAAAWkAAAANdHJhbnNhY3Rpb25JZAUAAAAKbG9ja0Ftb3VudAUAAAAPbG9ja1N0YXJ0SGVpZ2h0BQAAAAxtZXJnZWRBbW91bnQFAAAAEW1lcmdlZFN0YXJ0SGVpZ2h0BQAAAANuaWwJAQAAAA1SZXdhcmRFbnRyaWVzAAAAAwUAAAAJaXNOZXdVc2VyBQAAAA51c2VyQWRkcmVzc1N0cgUAAAAKbG9ja0Ftb3VudAkBAAAAD0xvY2tQYXJhbXNFbnRyeQAAAAMFAAAAC3VzZXJBZGRyZXNzBQAAAAxtZXJnZWRBbW91bnQFAAAAEW1lcmdlZFN0YXJ0SGVpZ2h0BQAAAAxzdGF0c0VudHJpZXMAAAABaQEAAAAHdW5zdGFrZQAAAAEAAAAGYW1vdW50AwkBAAAAAiE9AAAAAgkAAZAAAAABCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAkAAAIAAAABAgAAACN1bnN0YWtlIGRvZXNuJ3QgcmVxdWlyZSBhbnkgcGF5bWVudAQAAAALdXNlckFkZHJlc3MIBQAAAAFpAAAABmNhbGxlcgQAAAAOdXNlckFkZHJlc3NTdHIJAAQlAAAAAQUAAAALdXNlckFkZHJlc3MEAAAADSR0MDEzODc4MTM5NDAJAQAAAA9nZXRQYXJhbXNPckZhaWwAAAAABAAAAAtib25kQXNzZXRJZAgFAAAADSR0MDEzODc4MTM5NDAAAAACXzEEAAAADW1pbkxvY2tBbW91bnQIBQAAAA0kdDAxMzg3ODEz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V0FWRVNJRAUAAAAGTVVMVFg4BQAAAAZNVUxUWDYEAAAAB2Ftb3VudFgJAAE2AAAAAQUAAAAGYW1vdW50BAAAAAt0b3RhbFN0YWtlZAkBAAAADGdldEludE9yRWxzZQAAAAIJAQAAABdrZXlMb2NrUGFyYW1Ub3RhbEFtb3VudAAAAAAAAAAAAAAAAAAEAAAADHRvdGFsU3Rha2VkWAkAATYAAAABBQAAAAt0b3RhbFN0YWtlZAMJAABmAAAAAgAAAAAAAAAAAAUAAAALdG90YWxTdGFrZWQJAAACAAAAAQIAAAAbVE9ETzogY2FzZSBpcyBub3Qgc3VwcG9ydGVkAwkAAAAAAAACBQAAAAt0b3RhbFN0YWtlZAAAAAAAAAAAAAkBAAAAIkluY3JlbWVudE5vdERpc3RyaWJ1dGVkUmV3YXJkRW50cnkAAAACBQAAAA1wbXRBc3NldElkU3RyBQAAAAZhbW91bnQEAAAAEHJld2FyZFBlck5zYnRYMTgJAAE8AAAAAwUAAAAHYW1vdW50WAUAAAAHTVVMVFgxOAUAAAAMdG90YWxTdGFrZWRYBAAAABFkZXBvc2l0TnVtTGFzdEtFWQkBAAAAEWtleURlcG9zaXROdW1MYXN0AAAAAAQAAAAOZGVwb3NpdE51bUxhc3QJAQAAAAxnZXRJbnRPckVsc2UAAAACBQAAABFkZXBvc2l0TnVtTGFzdEtFWQD//////////wQAAAANZGVwb3NpdE51bU5ldwkAAGQAAAACBQAAAA5kZXBvc2l0TnVtTGFzdAAAAAAAAAAAAQMJAQAAAAEhAAAAAQkBAAAACGNvbnRhaW5zAAAAAgUAAAASc3VwcG9ydGVkQXNzZXRzU3RyBQAAAA1wbXRBc3NldElkU3RyCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACBQAAABJzdXBwb3J0ZWRBc3NldHNTdHICAAAAESBkb2Vzbid0IGNvbnRhaW4gBQAAAA1wbXRBc3NldElkU3RyCgEAAAAXcmVmcmVzaFJld2FyZFBlck5zYnRTVU0AAAACAAAABWFjY3VtAAAACW5leHRBc3NldAQAAAAWcmV3YXJkUGVyTnNidFN1bU5ld0tFWQkBAAAAFWtleVJld2FyZFBlck5zYnRTdW1BdAAAAAIFAAAADWRlcG9zaXROdW1OZXcFAAAACW5leHRBc3NldAQAAAAKc3VtTGFzdFN0cgkBAAAADGdldFN0ck9yRWxzZQAAAAIJAQAAABVrZXlSZXdhcmRQZXJOc2J0U3VtQXQAAAACBQAAAA5kZXBvc2l0TnVtTGFzdAUAAAAJbmV4dEFzc2V0AgAAAAEwCQAETQAAAAIFAAAABWFjY3VtAwkAAAAAAAACBQAAAAluZXh0QXNzZXQFAAAADXBtdEFzc2V0SWRTdHIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAFnJld2FyZFBlck5zYnRTdW1OZXdLRVkJAAGmAAAAAQkAATcAAAACCQABpwAAAAEFAAAACnN1bUxhc3RTdHIFAAAAEHJld2FyZFBlck5zYnRYMTgJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAFnJld2FyZFBlck5zYnRTdW1OZXdLRVkFAAAACnN1bUxhc3RTdHIJAARNAAAAAgoAAAAAAiRsBQAAABNzdXBwb3J0ZWRBc3NldHNMaXN0CgAAAAACJHMJAAGQAAAAAQUAAAACJGwKAAAAAAUkYWNjMAUAAAADbmlsCgEAAAAFJGYwXzEAAAACAAAAAiRhAAAAAiRpAwkAAGcAAAACBQAAAAIkaQUAAAACJHMFAAAAAiRhCQEAAAAXcmVmcmVzaFJld2FyZFBlck5zYnRTVU0AAAACBQAAAAIkYQkAAZEAAAACBQAAAAIkbAUAAAACJGkKAQAAAAUkZjBfMgAAAAIAAAACJGEAAAACJGkDCQAAZwAAAAIFAAAAAiRpBQAAAAIkcwUAAAACJGEJAAACAAAAAQIAAAAUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQAAAAUkZjBfMgAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIFAAAABSRhY2MwAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAACAAAAAAAAAAADAAAAAAAAAAAEAAAAAAAAAAAFAAAAAAAAAAAGAAAAAAAAAAAHAAAAAAAAAAAIAAAAAAAAAAAJAAAAAAAAAAAKCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAARZGVwb3NpdE51bUxhc3RLRVkFAAAADWRlcG9zaXROdW1OZXcAAAABaQEAAAAMY2xhaW1SZXdhcmRzAAAAAAQAAAALdXNlckFkZHJlc3MIBQAAAAFpAAAABmNhbGxlcgQAAAAOdXNlckFkZHJlc3NTdHIJAAQlAAAAAQUAAAALdXNlckFkZHJlc3MDCQAAZgAAAAIJAAGQAAAAAQgFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAJAAACAAAAAQIAAAAZcGF5bWVudHMgYXJlIG5vdCBhY2NlcHRlZAQAAAANJHQwMTY3MzIxNjgzNwkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkBAAAAE2dldFVzZXJQYXJhbXNPclVuaXQAAAABBQAAAAt1c2VyQWRkcmVzcwkABRUAAAADBgAAAAAAAAAAAAAAAAAAAAAAAAQAAAAJaXNOZXdVc2VyCAUAAAANJHQwMTY3MzIxNjgzNwAAAAJfMQQAAAAMc3Rha2VkQW1vdW50CAUAAAANJHQwMTY3MzIxNjgzNwAAAAJfMgQAAAAMc3Rha2luZ1N0YXJ0CAUAAAANJHQwMTY3MzIxNjgzNwAAAAJfMwQAAAANc3Rha2VkQW1vdW50WAkAATYAAAABBQAAAAxzdGFrZWRBbW91bnQEAAAAG3VzZXJSZXdhcmRGcm9tRGVwb3NpdE51bUtFWQkBAAAAG2tleVVzZXJSZXdhcmRGcm9tRGVwb3NpdE51bQAAAAEFAAAADnVzZXJBZGRyZXNzU3RyBAAAAA5kZXBvc2l0TnVtVXNlcgkBAAAADGdldEludE9yRWxzZQAAAAIFAAAAG3VzZXJSZXdhcmRGcm9tRGVwb3NpdE51bUtFWQD//////////wQAAAAOZGVwb3NpdE51bUxhc3QJAQAAAAxnZXRJbnRPckVsc2UAAAACCQEAAAARa2V5RGVwb3NpdE51bUxhc3QAAAAAAP//////////CgEAAAAfZm9yRWFjaEFzc2V0Q2FsY1VuY2xhaW1lZFJld2FyZAAAAAIAAAAFYWNjdW0AAAAFYXNzZXQEAAAADSR0MDE3MjA4MTczNDYJAQAAAApjYWxjUmV3YXJkAAAABQUAAAAOdXNlckFkZHJlc3NTdHIF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AAAAAwAAAAAAAAAABAAAAAAAAAAABQAAAAAAAAAABgAAAAAAAAAABwAAAAAAAAAACAAAAAAAAAAACQAAAAAAAAAACgQAAAALdXNlckFkZHJlc3MJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEFAAAADnVzZXJBZGRyZXNzU3RyBAAAAA0kdDAxODcxNTE4ODIwCQEAAAALdmFsdWVPckVsc2UAAAACCQEAAAATZ2V0VXNlclBhcmFtc09yVW5pdAAAAAEFAAAAC3VzZXJBZGRyZXNzCQAFFQAAAAMGAAAAAAAAAAAAAAAAAAAAAAAABAAAAAlpc05ld1VzZXIIBQAAAA0kdDAxODcxNTE4ODIwAAAAAl8xBAAAAAxzdGFrZWRBbW91bnQIBQAAAA0kdDAxODcxNTE4ODIwAAAAAl8yBAAAAAxzdGFraW5nU3RhcnQIBQAAAA0kdDAxODcxNTE4ODIwAAAAAl8zBAAAAA1zdGFrZWRBbW91bnRYCQABNgAAAAEFAAAADHN0YWtlZEFtb3VudAQAAAAbdXNlclJld2FyZEZyb21EZXBvc2l0TnVtS0VZCQEAAAAba2V5VXNlclJld2FyZEZyb21EZXBvc2l0TnVtAAAAAQUAAAAOdXNlckFkZHJlc3NTdHIEAAAADmRlcG9zaXROdW1Vc2VyCQEAAAAMZ2V0SW50T3JFbHNlAAAAAgUAAAAbdXNlclJld2FyZEZyb21EZXBvc2l0TnVtS0VZAP//////////BAAAAA5kZXBvc2l0TnVtTGFzdAkBAAAADGdldEludE9yRWxzZQAAAAIJAQAAABFrZXlEZXBvc2l0TnVtTGFzdAAAAAAA//////////8KAQAAAB9mb3JFYWNoQXNzZXRDYWxjVW5jbGFpbWVkUmV3YXJkAAAAAgAAAAVhY2N1bQAAAAVhc3NldAQAAAANJHQwMTkxNjYxOTMwNAkBAAAACmNhbGNSZXdhcmQAAAAFBQAAAA51c2VyQWRkcmVzc1N0cgUAAAAFYXNzZXQFAAAADXN0YWtlZEFtb3VudFgFAAAADmRlcG9zaXROdW1Vc2VyBQAAAA5kZXBvc2l0TnVtTGFzdAQAAAALcmV3YXJkVG90YWwIBQAAAA0kdDAxOTE2NjE5MzA0AAAAAl8xBAAAAAZjYWNoZWQIBQAAAA0kdDAxOTE2NjE5MzA0AAAAAl8yBAAAAAdkeW5hbWljCAUAAAANJHQwMTkxNjYxOTMwNAAAAAJfMwQAAAATcmV3YXJkQ2FjaGVkUGFydEtFWQgFAAAADSR0MDE5MTY2MTkzMDQAAAACXzQEAAAAB2NsYWltZWQJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQfAAAAAQkBAAAACmtleUNsYWltZWQAAAACBQAAAA51c2VyQWRkcmVzc1N0cgUAAAAFYXNzZXQAAAAAAAAAAAAJAAEsAAAAAgkAASwAAAACBQAAAAVhY2N1bQkABLkAAAACCQAETAAAAAIFAAAABWFzc2V0CQAETAAAAAIJAAGkAAAAAQUAAAALcmV3YXJkVG90YWwJAARMAAAAAgkAAaQAAAABBQAAAAdjbGFpbWVkBQAAAANuaWwCAAAAAToCAAAAAV8KAAAAAAIkbAUAAAATc3VwcG9ydGVkQXNzZXRzTGlzdAoAAAAAAiRzCQABkAAAAAEFAAAAAiRsCgAAAAAFJGFjYzACAAAAAAoBAAAABSRmMF8xAAAAAgAAAAIkYQAAAAIkaQMJAABnAAAAAgUAAAACJGkFAAAAAiRzBQAAAAIkYQkBAAAAH2ZvckVhY2hBc3NldENhbGNVbmNsYWltZWRSZXdhcmQAAAACBQAAAAIkYQkAAZEAAAACBQAAAAIkbAUAAAACJGkKAQAAAAUkZjBfMgAAAAIAAAACJGEAAAACJGkDCQAAZwAAAAIFAAAAAiRpBQAAAAIkcwUAAAACJGEJAAACAAAAAQIAAAAUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQAAAAUkZjBfMgAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIFAAAABSRhY2MwAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAACAAAAAAAAAAADAAAAAAAAAAAEAAAAAAAAAAAFAAAAAAAAAAAGAAAAAAAAAAAHAAAAAAAAAAAIAAAAAAAAAAAJAAAAAAAAAAAKCQAFFAAAAAIFAAAAA25pbAkBAAAACWRyb3BSaWdodAAAAAIFAAAAEnVuY2xhaW1lZFJld2FyZFN0cgAAAAAAAAAAAQAAAAFpAQAAABZuc2J0U3Rha2luZ1NZU1JFQURPTkxZAAAAAQAAAA51c2VyQWRkcmVzc1N0cgQAAAAMdG90YWxOc2J0QW10CQEAAAAMZ2V0SW50T3JFbHNlAAAAAgkBAAAAF2tleUxvY2tQYXJhbVRvdGFsQW1vdW50AAAAAAAAAAAAAAAAAAMJAAAAAAAAAgUAAAAOdXNlckFkZHJlc3NTdHICAAAAAAkABRQAAAACBQAAAANuaWwJAARMAAAAAgAAAAAAAAAAAAkABEwAAAACBQAAAAx0b3RhbE5zYnRBbXQJAARMAAAAAgAAAAAAAAAAAAUAAAADbmlsBAAAAAt1c2VyQWRkcmVzcwkBAAAAD3RvQWRkcmVzc09yRmFpbAAAAAEFAAAADnVzZXJBZGRyZXNzU3RyBAAAAA0kdDAxOTk2OTIwMDczCQEAAAALdmFsdWVPckVsc2UAAAACCQEAAAATZ2V0VXNlclBhcmFtc09yVW5pdAAAAAEFAAAAC3VzZXJBZGRyZXNzCQAFFQAAAAMGAAAAAAAAAAAAAAAAAAAAAAAABAAAAAlpc05ld1VzZXIIBQAAAA0kdDAxOTk2OTIwMDczAAAAAl8xBAAAAAt1c2VyTnNidEFtdAgFAAAADSR0MDE5OTY5MjAwNzMAAAACXzIEAAAADHN0YWtpbmdTdGFydAgFAAAADSR0MDE5OTY5MjAwNzMAAAACXzMJAAUUAAAAAgUAAAADbmlsCQAETAAAAAIFAAAAC3VzZXJOc2J0QW10CQAETAAAAAIFAAAADHRvdGFsTnNidEFtdAkABEwAAAACBQAAAAxzdGFraW5nU3RhcnQFAAAAA25pbAAAAAEAAAACdHgBAAAABnZlcmlmeQAAAAAEAAAAE3B1YktleUFkbWluc0xpc3RTdHIJAAS5AAAAAgkABEwAAAACAgAAACxFeHRFRUsxOW5tS2o5bUNwbld5dkVFSkZZQVRMTWNWRU12b2hoVUhreUhObQkABEwAAAACAgAAACxFdjVweTVGZkJRWDljWnBZS25mUXJUQjQ5QnlmOFFtcFpXZURWUmltNHlWNwkABEwAAAACAgAAACxEVXV1TGpYdTk4bkJ3WmM3ZnF3Q1RqdEEzbm5Sd2dUYmtNU3I1U1UyTm1EUgkABEwAAAACAgAAACxEVXV1TGpYdTk4bkJ3WmM3ZnF3Q1RqdEEzbm5Sd2dUYmtNU3I1U1UyTm1EUgUAAAADbmlsBQAAAANTRVAEAAAAEHB1YktleUFkbWluc0xpc3QJAAS1AAAAAgkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABB0AAAACBQAAAA9jb250cm9sQ29udHJhY3QCAAAADCVzX19tdWx0aXNpZwUAAAATcHViS2V5QWRtaW5zTGlzdFN0cgUAAAADU0VQBAAAAAVjb3VudAkAAGQAAAACCQAAZAAAAAIJAABkAAAAAgMJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAAACQACWQAAAAEJAAGRAAAAAgUAAAAQcHViS2V5QWRtaW5zTGlzdAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAMJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAABCQACWQAAAAEJAAGRAAAAAgUAAAAQcHViS2V5QWRtaW5zTGlzdAAAAAAAAAAAAQAAAAAAAAAAAQAAAAAAAAAAAAMJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAACCQACWQAAAAEJAAGRAAAAAgUAAAAQcHViS2V5QWRtaW5zTGlzdAAAAAAAAAAAAgAAAAAAAAAAAQAAAAAAAAAAAAMJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAADCQACWQAAAAEJAAGRAAAAAgUAAAAQcHViS2V5QWRtaW5zTGlzdAAAAAAAAAAAAwAAAAAAAAAAAgAAAAAAAAAAAAkAAGcAAAACBQAAAAVjb3VudAAAAAAAAAAAAwsBW4E=", "chainId": 84, "height": 2161025, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 5WiKyA1KQfvsWUt4BFKaDJfAKLpeyhebAVsEceEqi5FU Next: 91K4ci1qHUfjVPBT8ESPr26haHhYEcQeLJLc4uESEbzJ Diff:
OldNewDifferences
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let separator = "__"
5+
6+let SEP = "__"
57
68 let MULT6 = 1000000
79
1719
1820 let WAVESID = fromBase58String(WAVESIDSTR)
1921
20-func keyBondAsset () = "bond_asset_id"
22+let IdxControlCfgNeutrinoDapp = 1
23+
24+let IdxControlCfgAuctionDapp = 2
25+
26+let IdxControlCfgRpdDapp = 3
27+
28+let IdxControlCfgMathDapp = 4
29+
30+let IdxControlCfgLiquidationDapp = 5
31+
32+let IdxControlCfgRestDapp = 6
33+
34+let IdxControlCfgNodeRegistryDapp = 7
35+
36+let IdxControlCfgNsbtStakingDapp = 8
37+
38+let IdxControlCfgMediatorDapp = 9
39+
40+func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), (((("mandatory " + toString(address)) + ".") + key) + " is not defined"))
2141
2242
23-func keyAuctionContractAddress () = "auction_contract"
43+func keyControlAddress () = "%s%s__config__controlAddress"
44+
45+
46+func keyControlCfg () = "%s__controlConfig"
47+
48+
49+func readControlCfgOrFail (control) = split(getStringOrFail(control, keyControlCfg()), SEP)
50+
51+
52+func getContractAddressOrFail (controlCfg,idx) = valueOrErrorMessage(addressFromString(controlCfg[idx]), ("Control cfg doesn't contain address at index " + toString(idx)))
53+
54+
55+let controlContract = addressFromStringValue(valueOrElse(getString(this, keyControlAddress()), "3N4NS7d4Jo9a6F14LiFUKKYVdUkkf2eP4Zx"))
56+
57+let controlCfg = readControlCfgOrFail(controlContract)
58+
59+let mathContract = getContractAddressOrFail(controlCfg, IdxControlCfgMathDapp)
60+
61+let neutrinoContract = getContractAddressOrFail(controlCfg, IdxControlCfgNeutrinoDapp)
62+
63+let auctionContract = getContractAddressOrFail(controlCfg, IdxControlCfgAuctionDapp)
64+
65+func keyBondAsset () = "bond_asset_id"
2466
2567
2668 func keyNeutrinoContractAddress () = "%s__neutrinoContractAddress"
92134 func getStrOrElse (key,defaultVal) = valueOrElse(getString(this, key), defaultVal)
93135
94136
95-func getStringOrFail (key) = valueOrErrorMessage(getString(this, key), (("Mandatory this." + key) + " is not defined"))
96-
97-
98137 func toAddressOrFail (addressStr) = valueOrErrorMessage(addressFromString(addressStr), ("couldn't parse passed addressStr=" + addressStr))
99138
100139
135174 func LockParamsEntry (userAddress,amount,start) = [IntegerEntry(keyLockParamUserAmount(userAddress), amount), IntegerEntry(keyLockParamStartBlock(userAddress), start)]
136175
137176
138-func getParamsOrFail () = {
139- let neutrinoContract = addressFromStringValue(getStringOrFail(keyNeutrinoContractAddress()))
140- $Tuple4(fromBase58String(getStringValue(neutrinoContract, keyAuctionContractAddress())), fromBase58String(getStringValue(neutrinoContract, keyBondAsset())), getIntOrFail(keyMinLockAmount()), getIntOrFail(keyHalfLife()))
141- }
177+func getParamsOrFail () = $Tuple3(fromBase58String(getStringValue(neutrinoContract, keyBondAsset())), getIntOrFail(keyMinLockAmount()), getIntOrFail(keyHalfLife()))
142178
143179
144180 func isActiveUser (userAddress) = (getIntOrElse(keyLockParamUserAmount(userAddress), 0) > 0)
173209 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
174210 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
175211 func forEachAssetCacheUserReward (accum,asset) = {
176- let $t074007535 = calcReward(userAddress, asset, stakedAmountX, depositNumUser, depositNumLast)
177- let rewardTotal = $t074007535._1
178- let cached = $t074007535._2
179- let dynamic = $t074007535._3
180- let rewardCachedPartKEY = $t074007535._4
212+ let $t084098544 = calcReward(userAddress, asset, stakedAmountX, depositNumUser, depositNumLast)
213+ let rewardTotal = $t084098544._1
214+ let cached = $t084098544._2
215+ let dynamic = $t084098544._3
216+ let rewardCachedPartKEY = $t084098544._4
181217 (accum :+ IntegerEntry(rewardCachedPartKEY, rewardTotal))
182218 }
183219
247283
248284 @Callable(i)
249285 func stake () = {
250- let $t01118911268 = getParamsOrFail()
251- let auctionContract = $t01118911268._1
252- let bondAssetId = $t01118911268._2
253- let minLockAmount = $t01118911268._3
254- let halfLife = $t01118911268._4
286+ let $t01221812280 = getParamsOrFail()
287+ let bondAssetId = $t01221812280._1
288+ let minLockAmount = $t01221812280._2
289+ let halfLife = $t01221812280._3
255290 if ((size(i.payments) != 1))
256291 then throw("Invalid payments size")
257292 else {
264299 else {
265300 let userAddress = i.caller
266301 let userAddressStr = toString(i.caller)
267- let $t01181011917 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, -1))
268- let isNewUser = $t01181011917._1
269- let lockAmount = $t01181011917._2
270- let lockStartHeight = $t01181011917._3
302+ let $t01282212929 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, -1))
303+ let isNewUser = $t01282212929._1
304+ let lockAmount = $t01282212929._2
305+ let lockStartHeight = $t01282212929._3
271306 let mergedAmount = if (isNewUser)
272307 then amount
273308 else (amount + lockAmount)
274309 let mergedStartHeight = if (isNewUser)
275310 then height
276- else {
277- let mathContract = addressFromStringValue(getStringOrFail(keyMathContractAddress()))
278- asInt(invoke(mathContract, "mergeStakesREADONLY", [amount, height, lockAmount, lockStartHeight, halfLife], nil))
279- }
311+ else asInt(invoke(mathContract, "mergeStakesREADONLY", [amount, height, lockAmount, lockStartHeight, halfLife], nil))
280312 if ((minLockAmount > mergedAmount))
281313 then throw(("Min lock amount is " + toString(minLockAmount)))
282314 else {
283- let $t01236712469 = StatsResult(amount, 1, if (isNewUser)
315+ let $t01329013392 = StatsResult(amount, 1, if (isNewUser)
284316 then 1
285317 else 0)
286- let statsEntries = $t01236712469._1
287- let totalStaked = $t01236712469._2
288- let totalStakedNew = $t01236712469._3
318+ let statsEntries = $t01329013392._1
319+ let totalStaked = $t01329013392._2
320+ let totalStakedNew = $t01329013392._3
289321 ((([HistoryRecordEntry("stake", userAddress, i.transactionId, lockAmount, lockStartHeight, mergedAmount, mergedStartHeight)] ++ RewardEntries(isNewUser, userAddressStr, lockAmount)) ++ LockParamsEntry(userAddress, mergedAmount, mergedStartHeight)) ++ statsEntries)
290322 }
291323 }
300332 else {
301333 let userAddress = i.caller
302334 let userAddressStr = toString(userAddress)
303- let $t01295513033 = getParamsOrFail()
304- let auctionAddress = $t01295513033._1
305- let bondAssetId = $t01295513033._2
306- let minLockAmount = $t01295513033._3
307- let halfLife = $t01295513033._4
308- let $t01303613110 = getUserParamsOrFail(userAddress)
309- let isNewUser = $t01303613110._1
310- let lockAmount = $t01303613110._2
311- let lockStart = $t01303613110._3
335+ let $t01387813940 = getParamsOrFail()
336+ let bondAssetId = $t01387813940._1
337+ let minLockAmount = $t01387813940._2
338+ let halfLife = $t01387813940._3
339+ let $t01394314017 = getUserParamsOrFail(userAddress)
340+ let isNewUser = $t01394314017._1
341+ let lockAmount = $t01394314017._2
342+ let lockStart = $t01394314017._3
312343 if ((0 >= lockAmount))
313344 then throw("Nothing to unstake")
314345 else if ((amount > lockAmount))
315346 then throw(((("Requested " + toString(amount)) + ", but staked only ") + toString(lockAmount)))
316347 else {
317- let mathContract = addressFromStringValue(getStringOrFail(keyMathContractAddress()))
318348 let comissionAmount = asInt(invoke(mathContract, "getUnstakeComissionAmountREADONLY", [amount, lockStart, halfLife], nil))
319- let $t01351113665 = StatsResult(-(amount), if ((amount == lockAmount))
349+ let $t01433114485 = StatsResult(-(amount), if ((amount == lockAmount))
320350 then -1
321351 else 0, if ((amount == lockAmount))
322352 then -1
323353 else 0)
324- let statsEntries = $t01351113665._1
325- let totalStaked = $t01351113665._2
326- let totalStakedNew = $t01351113665._3
327- ((([ScriptTransfer(userAddress, (amount - comissionAmount), bondAssetId), ScriptTransfer(Address(auctionAddress), comissionAmount, bondAssetId), HistoryRecordEntry("unstake", userAddress, i.transactionId, lockAmount, lockStart, (lockAmount - amount), lockStart)] ++ RewardEntries(false, userAddressStr, lockAmount)) ++ LockParamsEntry(userAddress, (lockAmount - amount), lockStart)) ++ statsEntries)
354+ let statsEntries = $t01433114485._1
355+ let totalStaked = $t01433114485._2
356+ let totalStakedNew = $t01433114485._3
357+ ((([ScriptTransfer(userAddress, (amount - comissionAmount), bondAssetId), ScriptTransfer(auctionContract, comissionAmount, bondAssetId), HistoryRecordEntry("unstake", userAddress, i.transactionId, lockAmount, lockStart, (lockAmount - amount), lockStart)] ++ RewardEntries(false, userAddressStr, lockAmount)) ++ LockParamsEntry(userAddress, (lockAmount - amount), lockStart)) ++ statsEntries)
328358 }
329359 }
330360
391421 if ((size(i.payments) > 0))
392422 then throw("payments are not accepted")
393423 else {
394- let $t01592116026 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
395- let isNewUser = $t01592116026._1
396- let stakedAmount = $t01592116026._2
397- let stakingStart = $t01592116026._3
424+ let $t01673216837 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
425+ let isNewUser = $t01673216837._1
426+ let stakedAmount = $t01673216837._2
427+ let stakingStart = $t01673216837._3
398428 let stakedAmountX = toBigInt(stakedAmount)
399429 let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddressStr)
400430 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
401431 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
402432 func forEachAssetCalcUnclaimedReward (accum,asset) = {
403- let $t01639716535 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
404- let rewardTotal = $t01639716535._1
405- let cached = $t01639716535._2
406- let dynamic = $t01639716535._3
407- let rewardCachedPartKEY = $t01639716535._4
433+ let $t01720817346 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
434+ let rewardTotal = $t01720817346._1
435+ let cached = $t01720817346._2
436+ let dynamic = $t01720817346._3
437+ let rewardCachedPartKEY = $t01720817346._4
408438 let claimedKEY = keyClaimed(userAddressStr, asset)
409- let $t01659516632 = accum
410- let data = $t01659516632._1
411- let claimedAmtByAsset = $t01659516632._2
439+ let $t01740617443 = accum
440+ let data = $t01740617443._1
441+ let claimedAmtByAsset = $t01740617443._2
412442 let newPart = makeString([asset, toString(rewardTotal)], ":")
413443 let claimedAmtByAssetNew = makeString([claimedAmtByAsset, newPart], "_")
414444 if ((0 >= rewardTotal))
416446 else $Tuple2((((data :+ ScriptTransfer(userAddress, rewardTotal, toAssetVect(asset))) :+ IntegerEntry(claimedKEY, (valueOrElse(getInteger(claimedKEY), 0) + rewardTotal))) :+ IntegerEntry(rewardCachedPartKEY, 0)), claimedAmtByAssetNew)
417447 }
418448
419- let $t01709217206 = {
449+ let $t01790318017 = {
420450 let $l = supportedAssetsList
421451 let $s = size($l)
422452 let $acc0 = $Tuple2(nil, "")
430460
431461 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
432462 }
433- let transfers = $t01709217206._1
434- let claimedAmtByAssetResult = $t01709217206._2
463+ let transfers = $t01790318017._1
464+ let claimedAmtByAssetResult = $t01790318017._2
435465 if ((0 >= size(transfers)))
436466 then throw("nothing to claim")
437467 else ((transfers :+ IntegerEntry(userRewardFromDepositNumKEY, depositNumLast)) :+ ClaimHistoryEntry(userAddress, i.transactionId, drop(claimedAmtByAssetResult, 1)))
461491 }
462492 else {
463493 let userAddress = addressFromStringValue(userAddressStr)
464- let $t01786517970 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
465- let isNewUser = $t01786517970._1
466- let stakedAmount = $t01786517970._2
467- let stakingStart = $t01786517970._3
494+ let $t01871518820 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
495+ let isNewUser = $t01871518820._1
496+ let stakedAmount = $t01871518820._2
497+ let stakingStart = $t01871518820._3
468498 let stakedAmountX = toBigInt(stakedAmount)
469499 let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddressStr)
470500 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
471501 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
472502 func forEachAssetCalcUnclaimedReward (accum,asset) = {
473- let $t01831618454 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
474- let rewardTotal = $t01831618454._1
475- let cached = $t01831618454._2
476- let dynamic = $t01831618454._3
477- let rewardCachedPartKEY = $t01831618454._4
503+ let $t01916619304 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
504+ let rewardTotal = $t01916619304._1
505+ let cached = $t01916619304._2
506+ let dynamic = $t01916619304._3
507+ let rewardCachedPartKEY = $t01916619304._4
478508 let claimed = valueOrElse(getInteger(keyClaimed(userAddressStr, asset)), 0)
479509 ((accum + makeString([asset, toString(rewardTotal), toString(claimed)], ":")) + "_")
480510 }
504534 then $Tuple2(nil, [0, totalNsbtAmt, 0])
505535 else {
506536 let userAddress = toAddressOrFail(userAddressStr)
507- let $t01905819162 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
508- let isNewUser = $t01905819162._1
509- let userNsbtAmt = $t01905819162._2
510- let stakingStart = $t01905819162._3
537+ let $t01996920073 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
538+ let isNewUser = $t01996920073._1
539+ let userNsbtAmt = $t01996920073._2
540+ let stakingStart = $t01996920073._3
511541 $Tuple2(nil, [userNsbtAmt, totalNsbtAmt, stakingStart])
512542 }
513543 }
515545
516546 @Verifier(tx)
517547 func verify () = {
518- let pubKeyAdminsList = ["ExtEEK19nmKj9mCpnWyvEEJFYATLMcVEMvohhUHkyHNm", "Ev5py5FfBQX9cZpYKnfQrTB49Byf8QmpZWeDVRim4yV7", "DUuuLjXu98nBwZc7fqwCTjtA3nnRwgTbkMSr5SU2NmDR", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"]
548+ let pubKeyAdminsListStr = makeString(["ExtEEK19nmKj9mCpnWyvEEJFYATLMcVEMvohhUHkyHNm", "Ev5py5FfBQX9cZpYKnfQrTB49Byf8QmpZWeDVRim4yV7", "DUuuLjXu98nBwZc7fqwCTjtA3nnRwgTbkMSr5SU2NmDR", "DUuuLjXu98nBwZc7fqwCTjtA3nnRwgTbkMSr5SU2NmDR"], SEP)
549+ let pubKeyAdminsList = split(valueOrElse(getString(controlContract, "%s__multisig"), pubKeyAdminsListStr), SEP)
519550 let count = ((((if (sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(pubKeyAdminsList[0])))
520551 then 1
521552 else 0) + (if (sigVerify(tx.bodyBytes, tx.proofs[1], fromBase58String(pubKeyAdminsList[1])))
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let separator = "__"
5+
6+let SEP = "__"
57
68 let MULT6 = 1000000
79
810 let MULT8 = 100000000
911
1012 let MULTX6 = toBigInt(MULT6)
1113
1214 let MULTX8 = toBigInt(MULT8)
1315
1416 let MULTX18 = toBigInt(1000000000000000000)
1517
1618 let WAVESIDSTR = "WAVES"
1719
1820 let WAVESID = fromBase58String(WAVESIDSTR)
1921
20-func keyBondAsset () = "bond_asset_id"
22+let IdxControlCfgNeutrinoDapp = 1
23+
24+let IdxControlCfgAuctionDapp = 2
25+
26+let IdxControlCfgRpdDapp = 3
27+
28+let IdxControlCfgMathDapp = 4
29+
30+let IdxControlCfgLiquidationDapp = 5
31+
32+let IdxControlCfgRestDapp = 6
33+
34+let IdxControlCfgNodeRegistryDapp = 7
35+
36+let IdxControlCfgNsbtStakingDapp = 8
37+
38+let IdxControlCfgMediatorDapp = 9
39+
40+func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), (((("mandatory " + toString(address)) + ".") + key) + " is not defined"))
2141
2242
23-func keyAuctionContractAddress () = "auction_contract"
43+func keyControlAddress () = "%s%s__config__controlAddress"
44+
45+
46+func keyControlCfg () = "%s__controlConfig"
47+
48+
49+func readControlCfgOrFail (control) = split(getStringOrFail(control, keyControlCfg()), SEP)
50+
51+
52+func getContractAddressOrFail (controlCfg,idx) = valueOrErrorMessage(addressFromString(controlCfg[idx]), ("Control cfg doesn't contain address at index " + toString(idx)))
53+
54+
55+let controlContract = addressFromStringValue(valueOrElse(getString(this, keyControlAddress()), "3N4NS7d4Jo9a6F14LiFUKKYVdUkkf2eP4Zx"))
56+
57+let controlCfg = readControlCfgOrFail(controlContract)
58+
59+let mathContract = getContractAddressOrFail(controlCfg, IdxControlCfgMathDapp)
60+
61+let neutrinoContract = getContractAddressOrFail(controlCfg, IdxControlCfgNeutrinoDapp)
62+
63+let auctionContract = getContractAddressOrFail(controlCfg, IdxControlCfgAuctionDapp)
64+
65+func keyBondAsset () = "bond_asset_id"
2466
2567
2668 func keyNeutrinoContractAddress () = "%s__neutrinoContractAddress"
2769
2870
2971 func keyMathContractAddress () = "%s__mathContract"
3072
3173
3274 func keyMinLockAmount () = "%s__minLockAmount"
3375
3476
3577 func keyHalfLife () = "%s__halfLife"
3678
3779
3880 func keyLockParamUserAmount (userAddress) = makeString(["%s%s%s", "paramByUser", toString(userAddress), "amount"], separator)
3981
4082
4183 func keyLockParamStartBlock (userAddress) = makeString(["%s%s%s", "paramByUser", toString(userAddress), "start"], separator)
4284
4385
4486 func keyHistoryRecord (type,userAddress,txId) = makeString(["%s%s%s%s", "history", type, toString(userAddress), toBase58String(txId)], separator)
4587
4688
4789 func keyLockParamTotalAmount () = makeString(["%s%s", "stats", "activeTotalLocked"], separator)
4890
4991
5092 func keyStatsLocksCount () = makeString(["%s%s", "stats", "locksCount"], separator)
5193
5294
5395 func keyStatsUsersCount () = makeString(["%s%s", "stats", "activeUsersCount"], separator)
5496
5597
5698 func keyNextPeriod () = "%s__nextPeriod"
5799
58100
59101 func keySupportedRewardAssets () = "supportedRewardAssets"
60102
61103
62104 func keyDepositNumLast () = makeString(["%s%s%s", "dep", "lastNum"], separator)
63105
64106
65107 func keyUserRewardFromDepositNum (userAddress) = makeString(["%s%s%s", "userRwdFromDepNum", userAddress], separator)
66108
67109
68110 func keyRewardPerNsbtSumAt (depositNum,tkn) = makeString(["%s%d", "rwdPerNsbtSumByDepNum", toString(depositNum), tkn], separator)
69111
70112
71113 func keyReward (userAddress,tkn) = makeString(["%s%s%s", "rwd", userAddress, tkn], separator)
72114
73115
74116 func keyClaimed (userAddress,tkn) = makeString(["%s%s%s", "clm", userAddress, tkn], separator)
75117
76118
77119 func keyNotDistributedReward (tkn) = makeString(["%s%s", "notDistributed", tkn], separator)
78120
79121
80122 func toX18 (origVal,origMult) = fraction(toBigInt(origVal), MULTX18, origMult)
81123
82124
83125 func getIntOrZero (key) = valueOrElse(getInteger(this, key), 0)
84126
85127
86128 func getIntOrElse (key,defaultVal) = valueOrElse(getInteger(this, key), defaultVal)
87129
88130
89131 func getIntOrFail (key) = valueOrErrorMessage(getInteger(this, key), (("Mandatory this." + key) + " is not defined"))
90132
91133
92134 func getStrOrElse (key,defaultVal) = valueOrElse(getString(this, key), defaultVal)
93135
94136
95-func getStringOrFail (key) = valueOrErrorMessage(getString(this, key), (("Mandatory this." + key) + " is not defined"))
96-
97-
98137 func toAddressOrFail (addressStr) = valueOrErrorMessage(addressFromString(addressStr), ("couldn't parse passed addressStr=" + addressStr))
99138
100139
101140 func toAssetVect (assetStr) = if ((assetStr == WAVESIDSTR))
102141 then unit
103142 else fromBase58String(assetStr)
104143
105144
106145 func asInt (val) = match val {
107146 case valInt: Int =>
108147 valInt
109148 case _ =>
110149 throw("fail to cast into Int")
111150 }
112151
113152
114153 func formatHistoryRecord (oldAmount,oldStart,newAmount,newStart) = makeString(["%d%d%d%d%d%d", toString(lastBlock.height), toString(lastBlock.timestamp), toString(oldAmount), toString(oldStart), toString(newAmount), toString(newStart)], separator)
115154
116155
117156 func formatClaimHistoryRecord (user,claimedRewards) = makeString(["%s%d%d%s", user, toString(lastBlock.height), toString(lastBlock.timestamp), claimedRewards], separator)
118157
119158
120159 func HistoryRecordEntry (type,userAddress,txId,oldAmount,oldStart,newAmount,newStart) = StringEntry(keyHistoryRecord(type, userAddress, txId), formatHistoryRecord(oldAmount, oldStart, newAmount, newStart))
121160
122161
123162 func ClaimHistoryEntry (userAddress,txId,claimedRewards) = StringEntry(keyHistoryRecord("claim", userAddress, txId), formatClaimHistoryRecord(toString(userAddress), claimedRewards))
124163
125164
126165 func StatsResult (totalLockedInc,lockCountInc,usersCountInc) = {
127166 let locksCount = getIntOrZero(keyStatsLocksCount())
128167 let usersCount = getIntOrZero(keyStatsUsersCount())
129168 let totalAmount = getIntOrZero(keyLockParamTotalAmount())
130169 let totalAmountNew = (totalAmount + totalLockedInc)
131170 $Tuple3([IntegerEntry(keyStatsLocksCount(), (locksCount + lockCountInc)), IntegerEntry(keyStatsUsersCount(), (usersCount + usersCountInc)), IntegerEntry(keyLockParamTotalAmount(), totalAmountNew)], totalAmount, totalAmountNew)
132171 }
133172
134173
135174 func LockParamsEntry (userAddress,amount,start) = [IntegerEntry(keyLockParamUserAmount(userAddress), amount), IntegerEntry(keyLockParamStartBlock(userAddress), start)]
136175
137176
138-func getParamsOrFail () = {
139- let neutrinoContract = addressFromStringValue(getStringOrFail(keyNeutrinoContractAddress()))
140- $Tuple4(fromBase58String(getStringValue(neutrinoContract, keyAuctionContractAddress())), fromBase58String(getStringValue(neutrinoContract, keyBondAsset())), getIntOrFail(keyMinLockAmount()), getIntOrFail(keyHalfLife()))
141- }
177+func getParamsOrFail () = $Tuple3(fromBase58String(getStringValue(neutrinoContract, keyBondAsset())), getIntOrFail(keyMinLockAmount()), getIntOrFail(keyHalfLife()))
142178
143179
144180 func isActiveUser (userAddress) = (getIntOrElse(keyLockParamUserAmount(userAddress), 0) > 0)
145181
146182
147183 func getUserParamsOrUnit (userAddress) = if (isActiveUser(userAddress))
148184 then $Tuple3(false, getIntOrFail(keyLockParamUserAmount(userAddress)), getIntOrFail(keyLockParamStartBlock(userAddress)))
149185 else unit
150186
151187
152188 func getUserParamsOrFail (userAddress) = valueOrErrorMessage(getUserParamsOrUnit(userAddress), (("User " + toString(userAddress)) + " is not defined"))
153189
154190
155191 let supportedAssetsStr = getStrOrElse(keySupportedRewardAssets(), "")
156192
157193 let supportedAssetsList = split(supportedAssetsStr, "_")
158194
159195 func calcReward (userAddress,assetId,stakedAmountX,depositNumUser,depositNumLast) = {
160196 let rewardPerNsbtSumLastKEY = keyRewardPerNsbtSumAt(depositNumLast, assetId)
161197 let sumLastX18 = parseBigIntValue(getStrOrElse(keyRewardPerNsbtSumAt(depositNumLast, assetId), "0"))
162198 let sumUserX18 = parseBigIntValue(getStrOrElse(keyRewardPerNsbtSumAt(depositNumUser, assetId), "0"))
163199 let rewardDynamicPart = toInt(fraction((sumLastX18 - sumUserX18), stakedAmountX, MULTX18))
164200 let rewardCachedPartKEY = keyReward(userAddress, assetId)
165201 let rewardCachedPart = getIntOrElse(rewardCachedPartKEY, 0)
166202 $Tuple4((rewardCachedPart + rewardDynamicPart), rewardCachedPart, rewardDynamicPart, rewardCachedPartKEY)
167203 }
168204
169205
170206 func RewardEntries (isNewUser,userAddress,stakedAmount) = {
171207 let stakedAmountX = toBigInt(stakedAmount)
172208 let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddress)
173209 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
174210 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
175211 func forEachAssetCacheUserReward (accum,asset) = {
176- let $t074007535 = calcReward(userAddress, asset, stakedAmountX, depositNumUser, depositNumLast)
177- let rewardTotal = $t074007535._1
178- let cached = $t074007535._2
179- let dynamic = $t074007535._3
180- let rewardCachedPartKEY = $t074007535._4
212+ let $t084098544 = calcReward(userAddress, asset, stakedAmountX, depositNumUser, depositNumLast)
213+ let rewardTotal = $t084098544._1
214+ let cached = $t084098544._2
215+ let dynamic = $t084098544._3
216+ let rewardCachedPartKEY = $t084098544._4
181217 (accum :+ IntegerEntry(rewardCachedPartKEY, rewardTotal))
182218 }
183219
184220 if (if ((depositNumLast == -1))
185221 then (depositNumUser == -1)
186222 else false)
187223 then nil
188224 else if (if ((depositNumLast == -1))
189225 then (depositNumUser > -1)
190226 else false)
191227 then throw("invalid depositNumLast and depositNumUser state")
192228 else if (if ((depositNumLast > -1))
193229 then (depositNumUser == -1)
194230 else false)
195231 then if (isNewUser)
196232 then [IntegerEntry(userRewardFromDepositNumKEY, depositNumLast)]
197233 else ({
198234 let $l = supportedAssetsList
199235 let $s = size($l)
200236 let $acc0 = nil
201237 func $f0_1 ($a,$i) = if (($i >= $s))
202238 then $a
203239 else forEachAssetCacheUserReward($a, $l[$i])
204240
205241 func $f0_2 ($a,$i) = if (($i >= $s))
206242 then $a
207243 else throw("List size exceeds 10")
208244
209245 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
210246 } :+ IntegerEntry(userRewardFromDepositNumKEY, depositNumLast))
211247 else if (if ((depositNumLast > -1))
212248 then (depositNumUser > -1)
213249 else false)
214250 then if (isNewUser)
215251 then [IntegerEntry(userRewardFromDepositNumKEY, depositNumLast)]
216252 else ({
217253 let $l = supportedAssetsList
218254 let $s = size($l)
219255 let $acc0 = nil
220256 func $f0_1 ($a,$i) = if (($i >= $s))
221257 then $a
222258 else forEachAssetCacheUserReward($a, $l[$i])
223259
224260 func $f0_2 ($a,$i) = if (($i >= $s))
225261 then $a
226262 else throw("List size exceeds 10")
227263
228264 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
229265 } :+ IntegerEntry(userRewardFromDepositNumKEY, depositNumLast))
230266 else throw(((("uncovered condition: depositNumLast=" + toString(depositNumLast)) + " depositNumUser=") + toString(depositNumUser)))
231267 }
232268
233269
234270 func IncrementNotDistributedRewardEntry (tkn,amountInc) = {
235271 let notDistributedRewardKEY = keyNotDistributedReward(tkn)
236272 let notDistributedReward = getIntOrElse(notDistributedRewardKEY, 0)
237273 [IntegerEntry(notDistributedRewardKEY, (notDistributedReward + amountInc))]
238274 }
239275
240276
241277 @Callable(i)
242278 func constructor (neutrinoContractAddress,mathContractAddress,minLockAmount,halfLife,supportedRewardAssets) = if ((i.caller != this))
243279 then throw("Permission denied")
244280 else [StringEntry(keyNeutrinoContractAddress(), neutrinoContractAddress), StringEntry(keyMathContractAddress(), mathContractAddress), IntegerEntry(keyMinLockAmount(), minLockAmount), IntegerEntry(keyHalfLife(), halfLife), StringEntry(keySupportedRewardAssets(), supportedRewardAssets)]
245281
246282
247283
248284 @Callable(i)
249285 func stake () = {
250- let $t01118911268 = getParamsOrFail()
251- let auctionContract = $t01118911268._1
252- let bondAssetId = $t01118911268._2
253- let minLockAmount = $t01118911268._3
254- let halfLife = $t01118911268._4
286+ let $t01221812280 = getParamsOrFail()
287+ let bondAssetId = $t01221812280._1
288+ let minLockAmount = $t01221812280._2
289+ let halfLife = $t01221812280._3
255290 if ((size(i.payments) != 1))
256291 then throw("Invalid payments size")
257292 else {
258293 let payment = i.payments[0]
259294 let amount = payment.amount
260295 let invalidAssetMessage = (("Invalid asset. " + toBase58String(bondAssetId)) + " is expected")
261296 let assetId = valueOrErrorMessage(payment.assetId, invalidAssetMessage)
262297 if ((assetId != bondAssetId))
263298 then throw(invalidAssetMessage)
264299 else {
265300 let userAddress = i.caller
266301 let userAddressStr = toString(i.caller)
267- let $t01181011917 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, -1))
268- let isNewUser = $t01181011917._1
269- let lockAmount = $t01181011917._2
270- let lockStartHeight = $t01181011917._3
302+ let $t01282212929 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, -1))
303+ let isNewUser = $t01282212929._1
304+ let lockAmount = $t01282212929._2
305+ let lockStartHeight = $t01282212929._3
271306 let mergedAmount = if (isNewUser)
272307 then amount
273308 else (amount + lockAmount)
274309 let mergedStartHeight = if (isNewUser)
275310 then height
276- else {
277- let mathContract = addressFromStringValue(getStringOrFail(keyMathContractAddress()))
278- asInt(invoke(mathContract, "mergeStakesREADONLY", [amount, height, lockAmount, lockStartHeight, halfLife], nil))
279- }
311+ else asInt(invoke(mathContract, "mergeStakesREADONLY", [amount, height, lockAmount, lockStartHeight, halfLife], nil))
280312 if ((minLockAmount > mergedAmount))
281313 then throw(("Min lock amount is " + toString(minLockAmount)))
282314 else {
283- let $t01236712469 = StatsResult(amount, 1, if (isNewUser)
315+ let $t01329013392 = StatsResult(amount, 1, if (isNewUser)
284316 then 1
285317 else 0)
286- let statsEntries = $t01236712469._1
287- let totalStaked = $t01236712469._2
288- let totalStakedNew = $t01236712469._3
318+ let statsEntries = $t01329013392._1
319+ let totalStaked = $t01329013392._2
320+ let totalStakedNew = $t01329013392._3
289321 ((([HistoryRecordEntry("stake", userAddress, i.transactionId, lockAmount, lockStartHeight, mergedAmount, mergedStartHeight)] ++ RewardEntries(isNewUser, userAddressStr, lockAmount)) ++ LockParamsEntry(userAddress, mergedAmount, mergedStartHeight)) ++ statsEntries)
290322 }
291323 }
292324 }
293325 }
294326
295327
296328
297329 @Callable(i)
298330 func unstake (amount) = if ((size(i.payments) != 0))
299331 then throw("unstake doesn't require any payment")
300332 else {
301333 let userAddress = i.caller
302334 let userAddressStr = toString(userAddress)
303- let $t01295513033 = getParamsOrFail()
304- let auctionAddress = $t01295513033._1
305- let bondAssetId = $t01295513033._2
306- let minLockAmount = $t01295513033._3
307- let halfLife = $t01295513033._4
308- let $t01303613110 = getUserParamsOrFail(userAddress)
309- let isNewUser = $t01303613110._1
310- let lockAmount = $t01303613110._2
311- let lockStart = $t01303613110._3
335+ let $t01387813940 = getParamsOrFail()
336+ let bondAssetId = $t01387813940._1
337+ let minLockAmount = $t01387813940._2
338+ let halfLife = $t01387813940._3
339+ let $t01394314017 = getUserParamsOrFail(userAddress)
340+ let isNewUser = $t01394314017._1
341+ let lockAmount = $t01394314017._2
342+ let lockStart = $t01394314017._3
312343 if ((0 >= lockAmount))
313344 then throw("Nothing to unstake")
314345 else if ((amount > lockAmount))
315346 then throw(((("Requested " + toString(amount)) + ", but staked only ") + toString(lockAmount)))
316347 else {
317- let mathContract = addressFromStringValue(getStringOrFail(keyMathContractAddress()))
318348 let comissionAmount = asInt(invoke(mathContract, "getUnstakeComissionAmountREADONLY", [amount, lockStart, halfLife], nil))
319- let $t01351113665 = StatsResult(-(amount), if ((amount == lockAmount))
349+ let $t01433114485 = StatsResult(-(amount), if ((amount == lockAmount))
320350 then -1
321351 else 0, if ((amount == lockAmount))
322352 then -1
323353 else 0)
324- let statsEntries = $t01351113665._1
325- let totalStaked = $t01351113665._2
326- let totalStakedNew = $t01351113665._3
327- ((([ScriptTransfer(userAddress, (amount - comissionAmount), bondAssetId), ScriptTransfer(Address(auctionAddress), comissionAmount, bondAssetId), HistoryRecordEntry("unstake", userAddress, i.transactionId, lockAmount, lockStart, (lockAmount - amount), lockStart)] ++ RewardEntries(false, userAddressStr, lockAmount)) ++ LockParamsEntry(userAddress, (lockAmount - amount), lockStart)) ++ statsEntries)
354+ let statsEntries = $t01433114485._1
355+ let totalStaked = $t01433114485._2
356+ let totalStakedNew = $t01433114485._3
357+ ((([ScriptTransfer(userAddress, (amount - comissionAmount), bondAssetId), ScriptTransfer(auctionContract, comissionAmount, bondAssetId), HistoryRecordEntry("unstake", userAddress, i.transactionId, lockAmount, lockStart, (lockAmount - amount), lockStart)] ++ RewardEntries(false, userAddressStr, lockAmount)) ++ LockParamsEntry(userAddress, (lockAmount - amount), lockStart)) ++ statsEntries)
328358 }
329359 }
330360
331361
332362
333363 @Callable(i)
334364 func deposit () = if ((size(i.payments) != 1))
335365 then throw("exact 1 payment is allowed only")
336366 else {
337367 let pmt = i.payments[0]
338368 let amount = pmt.amount
339369 let pmtAssetId = valueOrElse(pmt.assetId, WAVESID)
340370 let pmtAssetIdStr = toBase58String(pmtAssetId)
341371 let pmtMultX = if ((pmtAssetId == WAVESID))
342372 then MULTX8
343373 else MULTX6
344374 let amountX = toBigInt(amount)
345375 let totalStaked = getIntOrElse(keyLockParamTotalAmount(), 0)
346376 let totalStakedX = toBigInt(totalStaked)
347377 if ((0 > totalStaked))
348378 then throw("TODO: case is not supported")
349379 else if ((totalStaked == 0))
350380 then IncrementNotDistributedRewardEntry(pmtAssetIdStr, amount)
351381 else {
352382 let rewardPerNsbtX18 = fraction(amountX, MULTX18, totalStakedX)
353383 let depositNumLastKEY = keyDepositNumLast()
354384 let depositNumLast = getIntOrElse(depositNumLastKEY, -1)
355385 let depositNumNew = (depositNumLast + 1)
356386 if (!(contains(supportedAssetsStr, pmtAssetIdStr)))
357387 then throw(((supportedAssetsStr + " doesn't contain ") + pmtAssetIdStr))
358388 else {
359389 func refreshRewardPerNsbtSUM (accum,nextAsset) = {
360390 let rewardPerNsbtSumNewKEY = keyRewardPerNsbtSumAt(depositNumNew, nextAsset)
361391 let sumLastStr = getStrOrElse(keyRewardPerNsbtSumAt(depositNumLast, nextAsset), "0")
362392 (accum :+ (if ((nextAsset == pmtAssetIdStr))
363393 then StringEntry(rewardPerNsbtSumNewKEY, toString((parseBigIntValue(sumLastStr) + rewardPerNsbtX18)))
364394 else StringEntry(rewardPerNsbtSumNewKEY, sumLastStr)))
365395 }
366396
367397 ({
368398 let $l = supportedAssetsList
369399 let $s = size($l)
370400 let $acc0 = nil
371401 func $f0_1 ($a,$i) = if (($i >= $s))
372402 then $a
373403 else refreshRewardPerNsbtSUM($a, $l[$i])
374404
375405 func $f0_2 ($a,$i) = if (($i >= $s))
376406 then $a
377407 else throw("List size exceeds 10")
378408
379409 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
380410 } :+ IntegerEntry(depositNumLastKEY, depositNumNew))
381411 }
382412 }
383413 }
384414
385415
386416
387417 @Callable(i)
388418 func claimRewards () = {
389419 let userAddress = i.caller
390420 let userAddressStr = toString(userAddress)
391421 if ((size(i.payments) > 0))
392422 then throw("payments are not accepted")
393423 else {
394- let $t01592116026 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
395- let isNewUser = $t01592116026._1
396- let stakedAmount = $t01592116026._2
397- let stakingStart = $t01592116026._3
424+ let $t01673216837 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
425+ let isNewUser = $t01673216837._1
426+ let stakedAmount = $t01673216837._2
427+ let stakingStart = $t01673216837._3
398428 let stakedAmountX = toBigInt(stakedAmount)
399429 let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddressStr)
400430 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
401431 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
402432 func forEachAssetCalcUnclaimedReward (accum,asset) = {
403- let $t01639716535 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
404- let rewardTotal = $t01639716535._1
405- let cached = $t01639716535._2
406- let dynamic = $t01639716535._3
407- let rewardCachedPartKEY = $t01639716535._4
433+ let $t01720817346 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
434+ let rewardTotal = $t01720817346._1
435+ let cached = $t01720817346._2
436+ let dynamic = $t01720817346._3
437+ let rewardCachedPartKEY = $t01720817346._4
408438 let claimedKEY = keyClaimed(userAddressStr, asset)
409- let $t01659516632 = accum
410- let data = $t01659516632._1
411- let claimedAmtByAsset = $t01659516632._2
439+ let $t01740617443 = accum
440+ let data = $t01740617443._1
441+ let claimedAmtByAsset = $t01740617443._2
412442 let newPart = makeString([asset, toString(rewardTotal)], ":")
413443 let claimedAmtByAssetNew = makeString([claimedAmtByAsset, newPart], "_")
414444 if ((0 >= rewardTotal))
415445 then $Tuple2(data, claimedAmtByAssetNew)
416446 else $Tuple2((((data :+ ScriptTransfer(userAddress, rewardTotal, toAssetVect(asset))) :+ IntegerEntry(claimedKEY, (valueOrElse(getInteger(claimedKEY), 0) + rewardTotal))) :+ IntegerEntry(rewardCachedPartKEY, 0)), claimedAmtByAssetNew)
417447 }
418448
419- let $t01709217206 = {
449+ let $t01790318017 = {
420450 let $l = supportedAssetsList
421451 let $s = size($l)
422452 let $acc0 = $Tuple2(nil, "")
423453 func $f0_1 ($a,$i) = if (($i >= $s))
424454 then $a
425455 else forEachAssetCalcUnclaimedReward($a, $l[$i])
426456
427457 func $f0_2 ($a,$i) = if (($i >= $s))
428458 then $a
429459 else throw("List size exceeds 10")
430460
431461 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
432462 }
433- let transfers = $t01709217206._1
434- let claimedAmtByAssetResult = $t01709217206._2
463+ let transfers = $t01790318017._1
464+ let claimedAmtByAssetResult = $t01790318017._2
435465 if ((0 >= size(transfers)))
436466 then throw("nothing to claim")
437467 else ((transfers :+ IntegerEntry(userRewardFromDepositNumKEY, depositNumLast)) :+ ClaimHistoryEntry(userAddress, i.transactionId, drop(claimedAmtByAssetResult, 1)))
438468 }
439469 }
440470
441471
442472
443473 @Callable(i)
444474 func unclaimedRewardsREADONLY (userAddressStr) = {
445475 func forEachAssetZeroReward (accum,asset) = ((accum + makeString([asset, "0", "0"], ":")) + "_")
446476
447477 let unclaimedRewardStr = if ((userAddressStr == ""))
448478 then {
449479 let $l = supportedAssetsList
450480 let $s = size($l)
451481 let $acc0 = ""
452482 func $f0_1 ($a,$i) = if (($i >= $s))
453483 then $a
454484 else forEachAssetZeroReward($a, $l[$i])
455485
456486 func $f0_2 ($a,$i) = if (($i >= $s))
457487 then $a
458488 else throw("List size exceeds 10")
459489
460490 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
461491 }
462492 else {
463493 let userAddress = addressFromStringValue(userAddressStr)
464- let $t01786517970 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
465- let isNewUser = $t01786517970._1
466- let stakedAmount = $t01786517970._2
467- let stakingStart = $t01786517970._3
494+ let $t01871518820 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
495+ let isNewUser = $t01871518820._1
496+ let stakedAmount = $t01871518820._2
497+ let stakingStart = $t01871518820._3
468498 let stakedAmountX = toBigInt(stakedAmount)
469499 let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddressStr)
470500 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
471501 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
472502 func forEachAssetCalcUnclaimedReward (accum,asset) = {
473- let $t01831618454 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
474- let rewardTotal = $t01831618454._1
475- let cached = $t01831618454._2
476- let dynamic = $t01831618454._3
477- let rewardCachedPartKEY = $t01831618454._4
503+ let $t01916619304 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
504+ let rewardTotal = $t01916619304._1
505+ let cached = $t01916619304._2
506+ let dynamic = $t01916619304._3
507+ let rewardCachedPartKEY = $t01916619304._4
478508 let claimed = valueOrElse(getInteger(keyClaimed(userAddressStr, asset)), 0)
479509 ((accum + makeString([asset, toString(rewardTotal), toString(claimed)], ":")) + "_")
480510 }
481511
482512 let $l = supportedAssetsList
483513 let $s = size($l)
484514 let $acc0 = ""
485515 func $f0_1 ($a,$i) = if (($i >= $s))
486516 then $a
487517 else forEachAssetCalcUnclaimedReward($a, $l[$i])
488518
489519 func $f0_2 ($a,$i) = if (($i >= $s))
490520 then $a
491521 else throw("List size exceeds 10")
492522
493523 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
494524 }
495525 $Tuple2(nil, dropRight(unclaimedRewardStr, 1))
496526 }
497527
498528
499529
500530 @Callable(i)
501531 func nsbtStakingSYSREADONLY (userAddressStr) = {
502532 let totalNsbtAmt = getIntOrElse(keyLockParamTotalAmount(), 0)
503533 if ((userAddressStr == ""))
504534 then $Tuple2(nil, [0, totalNsbtAmt, 0])
505535 else {
506536 let userAddress = toAddressOrFail(userAddressStr)
507- let $t01905819162 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
508- let isNewUser = $t01905819162._1
509- let userNsbtAmt = $t01905819162._2
510- let stakingStart = $t01905819162._3
537+ let $t01996920073 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
538+ let isNewUser = $t01996920073._1
539+ let userNsbtAmt = $t01996920073._2
540+ let stakingStart = $t01996920073._3
511541 $Tuple2(nil, [userNsbtAmt, totalNsbtAmt, stakingStart])
512542 }
513543 }
514544
515545
516546 @Verifier(tx)
517547 func verify () = {
518- let pubKeyAdminsList = ["ExtEEK19nmKj9mCpnWyvEEJFYATLMcVEMvohhUHkyHNm", "Ev5py5FfBQX9cZpYKnfQrTB49Byf8QmpZWeDVRim4yV7", "DUuuLjXu98nBwZc7fqwCTjtA3nnRwgTbkMSr5SU2NmDR", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"]
548+ let pubKeyAdminsListStr = makeString(["ExtEEK19nmKj9mCpnWyvEEJFYATLMcVEMvohhUHkyHNm", "Ev5py5FfBQX9cZpYKnfQrTB49Byf8QmpZWeDVRim4yV7", "DUuuLjXu98nBwZc7fqwCTjtA3nnRwgTbkMSr5SU2NmDR", "DUuuLjXu98nBwZc7fqwCTjtA3nnRwgTbkMSr5SU2NmDR"], SEP)
549+ let pubKeyAdminsList = split(valueOrElse(getString(controlContract, "%s__multisig"), pubKeyAdminsListStr), SEP)
519550 let count = ((((if (sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(pubKeyAdminsList[0])))
520551 then 1
521552 else 0) + (if (sigVerify(tx.bodyBytes, tx.proofs[1], fromBase58String(pubKeyAdminsList[1])))
522553 then 1
523554 else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[2], fromBase58String(pubKeyAdminsList[2])))
524555 then 1
525556 else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[3], fromBase58String(pubKeyAdminsList[3])))
526557 then 2
527558 else 0))
528559 (count >= 3)
529560 }
530561

github/deemru/w8io/169f3d6 
82.14 ms