2022.06.26 11:38 [3178764] smart account 3P8w8NXZUtYdCA13tHbDY5sW4mC27ZFJgG3 > SELF 0.00000000 Waves

{ "type": 13, "id": "7NDg2qJaEmtDnrgaqnPDCZd9D97yrsXjbkeT1jhpUbDr", "fee": 14000000, "feeAssetId": null, "timestamp": 1656233094711, "version": 1, "sender": "3P8w8NXZUtYdCA13tHbDY5sW4mC27ZFJgG3", "senderPublicKey": "6uKJV5r5qjqG9uVK4Q24W7zG5KZtGtKXz3NWRMwfZbB7", "proofs": [ "2UGLHJ2NVijv2Cu9mUcF4EHEXnkeGhnuJx7BsHyXRSKrvWnjnTcCyJTDUqNAgCmCzj4bauJqvAy58HiiHWSNSNgY", "3bHdgsGQDbiXkWctdZogE82JPgYqbWWkGSUHChR36o3uDwZrqb8nrP2U13DQpUvrTiEFiScATDz5KboJPY3eFS5W", "44JK3pu5Gk69xSeiy3NmFchcVXSCRtwFJDzcwUpwjoupTZgh9NqfgDKZPGLgYiW8Sz93K6MUQ1uUVo3huZ6sxx9b", "3FpQ1FnERsFGU31RpmMA9twMTyzau2GBncvRRrogqSYYap5jtaW6j1Kr9N5s3oSeBeiMYaYeouvgoFtvgstQ9RCZ" ], "script": "base64:AAIFAAAAAAAAACAIAhIHCgUICAEBCBIAEgMKAQESABIAEgMKAQgSAwoBCAAAADkAAAAAC3JldmlzaW9uTnVtAgAAAChiM2ZmNzQ3MmExZDU0YTlmMGM4ZjZkNjY2NWM0NDU4YzM2YTMxZTQ4AAAAAAlzZXBhcmF0b3ICAAAAAl9fAAAAAANTRVACAAAAAl9fAAAAAAVNVUxUNgAAAAAAAA9CQAAAAAAFTVVMVDgAAAAAAAX14QAAAAAABk1VTFRYNgkAATYAAAABBQAAAAVNVUxUNgAAAAAGTVVMVFg4CQABNgAAAAEFAAAABU1VTFQ4AAAAAAdNVUxUWDE4CQABNgAAAAEADeC2s6dkAAAAAAAACldBVkVTSURTVFICAAAABVdBVkVTAAAAAAdXQVZFU0lECQACWQAAAAEFAAAACldBVkVTSURTVFIBAAAADGtleUJvbmRBc3NldAAAAAACAAAADWJvbmRfYXNzZXRfaWQBAAAAGWtleUF1Y3Rpb25Db250cmFjdEFkZHJlc3MAAAAAAgAAABBhdWN0aW9uX2NvbnRyYWN0AQAAABprZXlOZXV0cmlub0NvbnRyYWN0QWRkcmVzcwAAAAACAAAAGyVzX19uZXV0cmlub0NvbnRyYWN0QWRkcmVzcwEAAAAWa2V5TWF0aENvbnRyYWN0QWRkcmVzcwAAAAACAAAAECVzX19tYXRoQ29udHJhY3QBAAAAEGtleU1pbkxvY2tBbW91bnQAAAAAAgAAABElc19fbWluTG9ja0Ftb3VudAEAAAALa2V5SGFsZkxpZmUAAAAAAgAAAAwlc19faGFsZkxpZmUBAAAAFmtleUxvY2tQYXJhbVVzZXJBbW91bnQAAAABAAAAC3VzZXJBZGRyZXNzCQAEuQAAAAIJAARMAAAAAgIAAAAGJXMlcyVzCQAETAAAAAICAAAAC3BhcmFtQnlVc2VyCQAETAAAAAIJAAQlAAAAAQUAAAALdXNlckFkZHJlc3MJAARMAAAAAgIAAAAGYW1vdW50BQAAAANuaWwFAAAACXNlcGFyYXRvcgEAAAAWa2V5TG9ja1BhcmFtU3RhcnRCbG9jawAAAAEAAAALdXNlckFkZHJlc3MJAAS5AAAAAgkABEwAAAACAgAAAAYlcyVzJXMJAARMAAAAAgIAAAALcGFyYW1CeVVzZXIJAARMAAAA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aXN0b3J5UmVjb3JkAAAAAwIAAAAFY2xhaW0FAAAAC3VzZXJBZGRyZXNzBQAAAAR0eElkCQEAAAAYZm9ybWF0Q2xhaW1IaXN0b3J5UmVjb3JkAAAAAgkABCUAAAABBQAAAAt1c2VyQWRkcmVzcwUAAAAOY2xhaW1lZFJld2FyZHMBAAAAC1N0YXRzUmVzdWx0AAAAAwAAAA50b3RhbExvY2tlZEluYwAAAAxsb2NrQ291bnRJbmMAAAANdXNlcnNDb3VudEluYwQAAAAKbG9ja3NDb3VudAkBAAAADGdldEludE9yWmVybwAAAAEJAQAAABJrZXlTdGF0c0xvY2tzQ291bnQAAAAABAAAAAp1c2Vyc0NvdW50CQEAAAAMZ2V0SW50T3JaZXJvAAAAAQkBAAAAEmtleVN0YXRzVXNlcnNDb3VudAAAAAAEAAAAC3RvdGFsQW1vdW50CQEAAAAMZ2V0SW50T3JaZXJvAAAAAQkBAAAAF2tleUxvY2tQYXJhbVRvdGFsQW1vdW50AAAAAAQAAAAOdG90YWxBbW91bnROZXcJAABkAAAAAgUAAAALdG90YWxBbW91bnQFAAAADnRvdGFsTG9ja2VkSW5jCQAFFQAAAAMJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAABJrZXlTdGF0c0xvY2tzQ291bnQAAAAACQAAZAAAAAIFAAAACmxvY2tzQ291bnQFAAAADGxvY2tDb3VudEluYwkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAAEmtleVN0YXRzVXNlcnNDb3VudAAAAAAJAABkAAAAAgUAAAAKdXNlcnNDb3VudAUAAAANdXNlcnNDb3VudEluYwkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAAF2tleUxvY2tQYXJhbVRvdGFsQW1vdW50AAAAAAUAAAAOdG90YWxBbW91bnROZXcFAAAAA25pbAUAAAALdG90YWxBbW91bnQFAAAADnRvdGFsQW1vdW50TmV3AQAAAA9Mb2NrUGFyYW1zRW50cnkAAAADAAAAC3VzZXJBZGRyZXNzAAAABmFtb3VudAAAAAVzdGFydAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAAFmtleUxvY2tQYXJhbVVzZXJBbW91bnQAAAABBQAAAAt1c2VyQWRkcmVzcwUAAAAGYW1vdW50CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAAWa2V5TG9ja1BhcmFtU3RhcnRCbG9jawAAAAEFAAAAC3VzZXJBZGRyZXNzBQAAAAVzdGFydAUAAAADbmlsAQAAAA9nZXRQYXJhbXNPckZhaWwAAAAABAAAABBuZXV0cmlub0NvbnRyYWN0CQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABCQEAAAAPZ2V0U3RyaW5nT3JGYWlsAAAAAQkBAAAAGmtleU5ldXRyaW5vQ29udHJhY3RBZGRyZXNzAAAAAAkABRYAAAAECQACWQAAAAEJAQAAABFAZXh0ck5hdGl2ZSgxMDUzKQAAAAIFAAAAEG5ldXRyaW5vQ29udHJhY3QJAQAAABlrZXlBdWN0aW9uQ29udHJhY3RBZGRyZXNzAAAAAAkAAlkAAAABCQEAAAARQGV4dHJOYXRpdmUoMTA1MykAAAACBQAAABBuZXV0cmlub0NvbnRyYWN0CQEAAAAMa2V5Qm9uZEFzc2V0AAAAAAkBAAAADGdldEludE9yRmFpbAAAAAEJAQAAABBrZXlNaW5Mb2NrQW1vdW50AAAAAAkBAAAADGdldEludE9yRmFpbAAAAAEJAQAAAAtrZXlIYWxmTGlmZQAAAAABAAAADGlzQWN0aXZlVXNlcgAAAAEAAAALdXNlckFkZHJlc3MJAABmAAAAAgkBAAAADGdldEludE9yRWxzZQAAAAIJAQAAABZrZXlMb2NrUGFyYW1Vc2VyQW1vdW50AAAAAQUAAAALdXNlckFkZHJlc3MAAAAAAAAAAAAAAAAAAAAAAAABAAAAE2dldFVzZXJQYXJhbXNPclVuaXQAAAABAAAAC3VzZXJBZGRyZXNzAwkBAAAADGlzQWN0aXZlVXNlcgAAAAEFAAAAC3VzZXJBZGRyZXNzCQAFFQAAAAMHCQEAAAAMZ2V0SW50T3JGYWlsAAAAAQkBAAAAFmtleUxvY2tQYXJhbVVzZXJBbW91bnQAAAABBQAAAAt1c2VyQWRkcmVzcwkBAAAADGdldEludE9yRmFpbAAAAAEJAQAAABZrZXlMb2NrUGFyYW1TdGFydEJsb2NrAAAAAQUAAAALdXNlckFkZHJlc3MFAAAABHVuaXQBAAAAE2dldFVzZXJQYXJhbXNPckZhaWwAAAABAAAAC3VzZXJBZGRyZXNzCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAQAAABNnZXRVc2VyUGFyYW1zT3JVbml0AAAAAQUAAAALdXNlckFkZHJlc3MJAAEsAAAAAgkAASwAAAACAgAAAAVVc2VyIAkABCUAAAABBQAAAAt1c2VyQWRkcmVzcwIAAAAPIGlzIG5vdCBkZWZpbmVkAAAAABJzdXBwb3J0ZWRBc3NldHNTdHIJAQAAAAxnZXRTdHJPckVsc2UAAAACCQEAAAAYa2V5U3VwcG9ydGVkUmV3YXJkQXNzZXRzAAAAAAIAAAAAAAAAABNzdXBwb3J0ZWRBc3NldHNMaXN0CQAEtQAAAAIFAAAAEnN1cHBvcnRlZEFzc2V0c1N0cgIAAAABXwEAAAAKY2FsY1Jld2FyZAAAAAUAAAALdXNlckFkZHJlc3MAAAAHYXNzZXRJZAAAAA1zdGFrZWRBbW91bnRYAAAADmRlcG9zaXROdW1Vc2VyAAAADmRlcG9zaXROdW1MYXN0BAAAABdyZXdhcmRQZXJOc2J0U3VtTGFzdEtFWQkBAAAAFWtleVJld2FyZFBlck5zYnRTdW1BdAAAAAIFAAAADmRlcG9zaXROdW1MYXN0BQAAAAdhc3NldElkBAAAAApzdW1MYXN0WDE4CQABpwAAAAEJAQAAAAxnZXRTdHJPckVsc2UAAAACCQEAAAAVa2V5UmV3YXJkUGVyTnNidFN1bUF0AAAAAgUAAAAOZGVwb3NpdE51bUxhc3QFAAAAB2Fzc2V0SWQCAAAAATAEAAAACnN1bVVzZXJYMTgJAAGnAAAAAQkBAAAADGdldFN0ck9yRWxzZQAAAAIJAQAAABVrZXlSZXdhcmRQZXJOc2J0U3VtQXQAAAACBQAAAA5kZXBvc2l0TnVtVXNlcgUAAAAHYXNzZXRJZAIAAAABMAQAAAARcmV3YXJkRHluYW1pY1BhcnQJAAGgAAAAAQkAATwAAAADCQABOAAAAAIFAAAACnN1bUxhc3RYMTgFAAAACnN1bVVzZXJYMTgFAAAADXN0YWtlZEFtb3VudFgFAAAAB01VTFRYMTgEAAAAE3Jld2FyZENhY2hlZFBhcnRLRVkJAQAAAAlrZXlSZXdhcmQAAAACBQAAAAt1c2VyQWRkcmVzcwUAAAAHYXNzZXRJZAQAAAAQcmV3YXJkQ2FjaGVkUGFydAkBAAAADGdldEludE9yRWxzZQAAAAIFAAAAE3Jld2FyZENhY2hlZFBhcnRLRVkAAAAAAAAAAAAJAAUWAAAABAkAAGQAAAACBQAAABByZXdhcmRDYWNoZWRQYXJ0BQAAABFyZXdhcmREeW5hbWljUGFydAUAAAAQcmV3YXJkQ2FjaGVkUGFydAUAAAARcmV3YXJkRHluYW1pY1BhcnQFAAAAE3Jld2FyZENhY2hlZFBhcnRLRVkBAAAADVJld2FyZEVudHJpZXMAAAADAAAACWlzTmV3VXNlcgAAAAt1c2VyQWRkcmVzcwAAAAxzdGFrZWRBbW91bnQEAAAADXN0YWtlZEFtb3VudFgJAAE2AAAAAQUAAAAMc3Rha2VkQW1vdW50BAAAABt1c2VyUmV3YXJkRnJvbURlcG9zaXROdW1LRVkJAQAAABtrZXlVc2VyUmV3YXJkRnJvbURlcG9zaXROdW0AAAABBQAAAAt1c2VyQWRkcmVzcwQAAAAOZGVwb3NpdE51bVVzZXIJAQAAAAxnZXRJbnRPckVsc2UAAAACBQAAABt1c2VyUmV3YXJkRnJvbURlcG9zaXROdW1LRVkA//////////8EAAAADmRlcG9zaXROdW1MYXN0CQEAAAAMZ2V0SW50T3JFbHNlAAAAAgkBAAAAEWtleURlcG9zaXROdW1MYXN0AAAAAAD//////////woBAAAAG2ZvckVhY2hBc3NldENhY2hlVXNlclJld2FyZAAAAAIAAAAFYWNjdW0AAAAFYXNzZXQEAAAACyR0MDc0MTY3NTUxCQEAAAAKY2FsY1Jld2FyZAAAAAUFAAAAC3VzZXJBZGRyZXNzBQAAAAVhc3NldAUAAAANc3Rha2VkQW1vdW50WAUAAAAOZGVwb3NpdE51bVVzZXIFAAAADmRlcG9zaXROdW1MYXN0BAAAAAtyZXdhcmRUb3RhbAgFAAAACyR0MDc0MTY3NTUxAAAAAl8xBAAAAAZjYWNoZWQIBQAAAAskdDA3NDE2NzU1MQAAAAJfMgQAAAAHZHluYW1pYwgFAAAACyR0MDc0MTY3NTUxAAAAAl8zBAAAABNyZXdhcmRDYWNoZWRQYXJ0S0VZCAUAAAALJHQw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AAAAAAAAAAACAAAAAAAAAAADAAAAAAAAAAAEAAAAAAAAAAAFAAAAAAAAAAAGAAAAAAAAAAAHAAAAAAAAAAAIAAAAAAAAAAAJAAAAAAAAAAAKCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAbdXNlclJld2FyZEZyb21EZXBvc2l0TnVtS0VZBQAAAA5kZXBvc2l0TnVtTGFzdAkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAACR1bmNvdmVyZWQgY29uZGl0aW9uOiBkZXBvc2l0TnVtTGFzdD0JAAGkAAAAAQUAAAAOZGVwb3NpdE51bUxhc3QCAAAAECBkZXBvc2l0TnVtVXNlcj0JAAGkAAAAAQUAAAAOZGVwb3NpdE51bVVzZXIBAAAAIkluY3JlbWVudE5vdERpc3RyaWJ1dGVkUmV3YXJkRW50cnkAAAACAAAAA3RrbgAAAAlhbW91bnRJbmMEAAAAF25vdERpc3RyaWJ1dGVkUmV3YXJkS0VZCQEAAAAXa2V5Tm90RGlzdHJpYnV0ZWRSZXdhcmQAAAABBQAAAAN0a24EAAAAFG5vdERpc3RyaWJ1dGVkUmV3YXJkCQEAAAAMZ2V0SW50T3JFbHNlAAAAAgUAAAAXbm90RGlzdHJpYnV0ZWRSZXdhcmRLRVkAAAAAAAAAAAAJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAF25vdERpc3RyaWJ1dGVkUmV3YXJkS0VZCQAAZAAAAAIFAAAAFG5vdERpc3RyaWJ1dGVkUmV3YXJkBQAAAAlhbW91bnRJbmMFAAAAA25pbAAAAAARQ29udG9sQ29udHJhY3RLZXkCAAAAEGNvbnRyb2xfY29udHJhY3QAAAAAEG5ldXRyaW5vQ29udHJhY3QJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEJAQAAAA9nZXRTdHJpbmdPckZhaWwAAAABCQEAAAAaa2V5TmV1dHJpbm9Db250cmFjdEFkZHJlc3MAAAAAAAAAAA9jb250cm9sQ29udHJhY3QJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEJAQAAABFAZXh0ck5hdGl2ZSgxMDUzKQAAAAIFAAAAEG5ldXRyaW5vQ29udHJhY3QFAAAAEUNvbnRvbENvbnRyYWN0S2V5AAAABwAAAAFpAQAAAAtjb25zdHJ1Y3RvcgAAAAUAAAAXbmV1dHJpbm9Db250cmFjdEFkZHJlc3MAAAATbWF0aENvbnRyYWN0QWRkcmVzcwAAAA1taW5Mb2NrQW1vdW50AAAACGhhbGZMaWZlAAAAFXN1cHBvcnRlZFJld2FyZEFzc2V0cwMJAQAAAAIhPQAAAAIIBQAAAAFpAAAABmNhbGxlcgUAAAAEdGhpcwkAAAIAAAABAgAAABFQZXJtaXNzaW9uIGRlbmllZAkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAAaa2V5TmV1dHJpbm9Db250cmFjdEFkZHJlc3MAAAAABQAAABduZXV0cmlub0NvbnRyYWN0QWRkcmVzcwkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAAWa2V5TWF0aENvbnRyYWN0QWRkcmVzcwAAAAAFAAAAE21hdGhDb250cmFjdEFkZHJlc3MJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAABBrZXlNaW5Mb2NrQW1vdW50AAAAAAUAAAANbWluTG9ja0Ftb3VudAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAAC2tleUhhbGZMaWZlAAAAAAUAAAAIaGFsZkxpZmUJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAGGtleVN1cHBvcnRlZFJld2FyZEFzc2V0cwAAAAAFAAAAFXN1cHBvcnRlZFJld2FyZEFzc2V0cwUAAAADbmlsAAAAAWkBAAAABXN0YWtlAAAAAAQAAAANJHQwMTE0NDIxMTUyMQkBAAAAD2dldFBhcmFtc09yRmFpbAAAAAAEAAAAD2F1Y3Rpb25Db250cmFjdAgFAAAADSR0MDExNDQyMTE1MjEAAAACXzEEAAAAC2JvbmRBc3NldElkCAUAAAANJHQwMTE0NDIxMTUyMQAAAAJfMgQAAAANbWluTG9ja0Ftb3VudAgFAAAADSR0MDExNDQyMTE1MjEAAAACXzMEAAAACGhhbGZMaWZlCAUAAAANJHQwMTE0NDIxMTUyMQAAAAJfNAMJAQAAAAIhPQAAAAIJAAGQAAAAAQgFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAEJAAACAAAAAQIAAAAVSW52YWxpZCBwYXltZW50cyBzaXplBAAAAAdwYXltZW50CQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAABAAAAAZhbW91bnQIBQAAAAdwYXltZW50AAAABmFtb3VudAQAAAATaW52YWxpZEFzc2V0TWVzc2FnZQkAASwAAAACCQABLAAAAAICAAAAD0ludmFsaWQgYXNzZXQuIAkAAlgAAAABBQAAAAtib25kQXNzZXRJZAIAAAAMIGlzIGV4cGVjdGVkBAAAAAdhc3NldElkCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIIBQAAAAdwYXltZW50AAAAB2Fzc2V0SWQFAAAAE2ludmFsaWRBc3NldE1lc3NhZ2UDCQEAAAACIT0AAAACBQAAAAdhc3NldElkBQAAAAtib25kQXNzZXRJZAkAAAIAAAABBQAAABNpbnZhbGlkQXNzZXRNZXNzYWdlBAAAAAt1c2VyQWRkcmVzcwgFAAAAAWkAAAAGY2FsbGVyBAAAAA51c2VyQWRkcmVzc1N0cgkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIEAAAADSR0MDEyMDYzMTIxNzAJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAQAAABNnZXRVc2VyUGFyYW1zT3JVbml0AAAAAQUAAAALdXNlckFkZHJlc3MJAAUVAAAAAwYAAAAAAAAAAAAA//////////8EAAAACWlzTmV3VXNlcggFAAAADSR0MDEyMDYzMTIxNzAAAAACXzEEAAAACmxvY2tBbW91bnQIBQAAAA0kdDAxMjA2MzEyMTcwAAAAAl8yBAAAAA9sb2NrU3RhcnRIZWlnaHQIBQAAAA0kdDAxMjA2MzEyMTcwAAAAAl8zBAAAAAxtZXJnZWRBbW91bnQDBQAAAAlpc05ld1VzZXIFAAAABmFtb3VudAkAAGQAAAACBQAAAAZhbW91bnQFAAAACmxvY2tBbW91bnQEAAAAEW1lcmdlZFN0YXJ0SGVpZ2h0AwUAAAAJaXNOZXdVc2VyBQAAAAZoZWlnaHQEAAAADG1hdGhDb250cmFjdAkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQkBAAAAD2dldFN0cmluZ09yRmFpbAAAAAEJAQAAABZrZXlNYXRoQ29udHJhY3RBZGRyZXNzAAAAAAkBAAAABWFzSW50AAAAAQkAA/wAAAAEBQAAAAxtYXRoQ29udHJhY3QCAAAAE21lcmdlU3Rha2VzUkVBRE9OTFkJAARMAAAAAgUAAAAGYW1vdW50CQAETAAAAAIFAAAABmhlaWdodAkABEwAAAACBQAAAApsb2NrQW1vdW50CQAETAAAAAIFAAAAD2xvY2tTdGFydEhlaWdodAkABEwAAAACBQAAAAhoYWxmTGlmZQUAAAADbmlsBQAAAANuaWwDCQAAZgAAAAIFAAAADW1pbkxvY2tBbW91bnQFAAAADG1lcmdlZEFtb3VudAkAAAIAAAABCQABLAAAAAICAAAAE01pbiBsb2NrIGFtb3VudCBpcyAJAAGkAAAAAQUAAAANbWluTG9ja0Ftb3VudAQAAAANJHQwMTI2MjAxMjcyMgkBAAAAC1N0YXRzUmVzdWx0AAAAAwUAAAAGYW1vdW50AAAAAAAAAAABAwUAAAAJaXNOZXdVc2VyAAAAAAAAAAABAAAAAAAAAAAABAAAAAxzdGF0c0VudHJpZXMIBQAAAA0kdDAxMjYyMDEyNzIyAAAAAl8xBAAAAAt0b3RhbFN0YWtlZAgFAAAADSR0MDEyNjIwMTI3MjIAAAACXzIEAAAADnRvdGFsU3Rha2VkTmV3CAUAAAANJHQwMTI2MjAxMjcyMgAAAAJfMwkABE4AAAACCQAETgAAAAIJAAROAAAAAgkABEwAAAACCQEAAAASSGlzdG9yeVJlY29yZEVudHJ5AAAABwIAAAAFc3Rha2UFAAAAC3VzZXJBZGRyZXNzCAUAAAABaQAAAA10cmFuc2FjdGlvbklkBQAAAApsb2NrQW1vdW50BQAAAA9sb2NrU3RhcnRIZWlnaHQFAAAADG1lcmdlZEFtb3VudAUAAAARbWVyZ2VkU3RhcnRIZWlnaHQFAAAAA25pbAkBAAAADVJld2FyZEVudHJpZXMAAAADBQAAAAlpc05ld1VzZXIFAAAADnVzZXJBZGRyZXNzU3RyBQAAAApsb2NrQW1vdW50CQEAAAAPTG9ja1BhcmFtc0VudHJ5AAAAAwUAAAALdXNlckFkZHJlc3MFAAAADG1lcmdlZEFtb3VudAUAAAARbWVyZ2VkU3RhcnRIZWlnaHQFAAAADHN0YXRzRW50cmllcwAAAAFpAQAAAAd1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a2VkWAQAAAARZGVwb3NpdE51bUxhc3RLRVkJAQAAABFrZXlEZXBvc2l0TnVtTGFzdAAAAAAEAAAADmRlcG9zaXROdW1MYXN0CQEAAAAMZ2V0SW50T3JFbHNlAAAAAgUAAAARZGVwb3NpdE51bUxhc3RLRVkA//////////8EAAAADWRlcG9zaXROdW1OZXcJAABkAAAAAgUAAAAOZGVwb3NpdE51bUxhc3QAAAAAAAAAAAEDCQEAAAABIQAAAAEJAQAAAAhjb250YWlucwAAAAIFAAAAEnN1cHBvcnRlZEFzc2V0c1N0cgUAAAANcG10QXNzZXRJZFN0cgkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgUAAAASc3VwcG9ydGVkQXNzZXRzU3RyAgAAABEgZG9lc24ndCBjb250YWluIAUAAAANcG10QXNzZXRJZFN0cgoBAAAAF3JlZnJlc2hSZXdhcmRQZXJOc2J0U1VNAAAAAgAAAAVhY2N1bQAAAAluZXh0QXNzZXQEAAAAFnJld2FyZFBlck5zYnRTdW1OZXdLRVkJAQAAABVrZXlSZXdhcmRQZXJOc2J0U3VtQXQAAAACBQAAAA1kZXBvc2l0TnVtTmV3BQAAAAluZXh0QXNzZXQEAAAACnN1bUxhc3RTdHIJAQAAAAxnZXRTdHJPckVsc2UAAAACCQEAAAAVa2V5UmV3YXJkUGVyTnNidFN1bUF0AAAAAgUAAAAOZGVwb3NpdE51bUxhc3QFAAAACW5leHRBc3NldAIAAAABMAkABE0AAAACBQAAAAVhY2N1bQMJAAAAAAAAAgUAAAAJbmV4dEFzc2V0BQAAAA1wbXRBc3NldElkU3RyCQEAAAALU3RyaW5nRW50cnkAAAACBQAAABZyZXdhcmRQZXJOc2J0U3VtTmV3S0VZCQABpgAAAAEJAAE3AAAAAgkAAacAAAABBQAAAApzdW1MYXN0U3RyBQAAABByZXdhcmRQZXJOc2J0WDE4CQEAAAALU3RyaW5nRW50cnkAAAACBQAAABZyZXdhcmRQZXJOc2J0U3VtTmV3S0VZBQAAAApzdW1MYXN0U3RyCQAETQAAAAIKAAAAAAIkbAUAAAATc3VwcG9ydGVkQXNzZXRzTGlzdAoAAAAAAiRzCQABkAAAAAEFAAAAAiRsCgAAAAAFJGFjYzAFAAAAA25pbAoBAAAABSRmMF8xAAAAAgAAAAIkYQAAAAIkaQMJAABnAAAAAgUAAAACJGkFAAAAAiRzBQAAAAIkYQkBAAAAF3JlZnJlc2hSZXdhcmRQZXJOc2J0U1VNAAAAAgUAAAACJGEJAAGRAAAAAgUAAAACJGwFAAAAAiRpCgEAAAAFJGYwXzIAAAACAAAAAiRhAAAAAiRpAwkAAGcAAAACBQAAAAIkaQUAAAACJHMFAAAAAiRhCQAAAgAAAAECAAAAFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEAAAAFJGYwXzIAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACBQAAAAUkYWNjMAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAgAAAAAAAAAAAwAAAAAAAAAABAAAAAAAAAAABQAAAAAAAAAABgAAAAAAAAAABwAAAAAAAAAACAAAAAAAAAAACQAAAAAAAAAACgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAEWRlcG9zaXROdW1MYXN0S0VZBQAAAA1kZXBvc2l0TnVtTmV3AAAAAWkBAAAADGNsYWltUmV3YXJkcwAAAAAEAAAAC3VzZXJBZGRyZXNzCAUAAAABaQAAAAZjYWxsZXIEAAAADnVzZXJBZGRyZXNzU3RyCQAEJQAAAAEFAAAAC3VzZXJBZGRyZXNzAwkAAGYAAAACCQABkAAAAAEIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAACQAAAgAAAAECAAAAGXBheW1lbnRzIGFyZSBub3QgYWNjZXB0ZWQEAAAADSR0MDE2MTc0MTYyNzkJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAQAAABNnZXRVc2VyUGFyYW1zT3JVbml0AAAAAQUAAAALdXNlckFkZHJlc3MJAAUVAAAAAwYAAAAAAAAAAAAAAAAAAAAAAAAEAAAACWlzTmV3VXNlcggFAAAADSR0MDE2MTc0MTYyNzkAAAACXzEEAAAADHN0YWtlZEFtb3VudAgFAAAADSR0MDE2MTc0MTYyNzkAAAACXzIEAAAADHN0YWtpbmdTdGFydAgFAAAADSR0MDE2MTc0MTYyNzkAAAACXzMEAAAADXN0YWtlZEFtb3VudFgJAAE2AAAAAQUAAAAMc3Rha2VkQW1vdW50BAAAABt1c2VyUmV3YXJkRnJvbURlcG9zaXROdW1LRVkJAQAAABtrZXlVc2VyUmV3YXJkRnJvbURlcG9zaXROdW0AAAABBQAAAA51c2VyQWRkcmVzc1N0cgQAAAAOZGVwb3NpdE51bVVzZXIJAQAAAAxnZXRJbnRPckVsc2UAAAACBQAAABt1c2VyUmV3YXJkRnJvbURlcG9zaXROdW1LRVkA//////////8EAAAADmRlcG9zaXROdW1MYXN0CQEAAAAMZ2V0SW50T3JFbHNlAAAAAgkBAAAAEWtleURlcG9zaXROdW1MYXN0AAAAAAD//////////woBAAAAH2ZvckVhY2hBc3NldENhbGNVbmNsYWltZWRSZXdhcmQAAAACAAAABWFjY3VtAAAABWFzc2V0BAAAAA0kdDAxNjY1MDE2Nzg4CQEAAAAKY2FsY1Jld2FyZAAAAAUFAAAADnVzZXJBZGRyZXNzU3RyBQAAAAVhc3NldAUAAAANc3Rha2VkQW1vdW50WAUAAAAOZGVwb3NpdE51bVVzZXIFAAAADmRlcG9zaXROdW1MYXN0BAAAAAtyZXdhcmRUb3RhbAgFAAAADSR0MDE2NjUwMTY3ODgAAAACXzEEAAAABmNhY2hlZAgFAAAADSR0MDE2NjUwMTY3ODgAAAACXzIEAAAAB2R5bmFtaWMIBQAAAA0kdDAxNjY1MDE2Nzg4AAAAAl8zBAAAABNyZXdhcmRDYWNoZWRQYXJ0S0VZCAUAAAANJHQwMTY2NTAxNjc4OAAAAAJfNAQAAAAKY2xhaW1lZEtFWQkBAAAACmtleUNsYWltZWQAAAACBQAAAA51c2VyQWRkcmVzc1N0cgUAAAAFYXNzZXQEAAAADSR0MDE2ODQ4MTY4ODUFAAAABWFjY3VtBAAAAARkYXRhCAUAAAANJHQwMTY4NDgxNjg4NQAAAAJfMQQAAAARY2xhaW1lZEFtdEJ5QXNzZXQIBQAAAA0kdDAxNjg0ODE2ODg1AAAAAl8yBAAAAAduZXdQYXJ0CQAEuQAAAAIJAARMAAAA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b3NpdE51bUtFWQkBAAAAG2tleVVzZXJSZXdhcmRGcm9tRGVwb3NpdE51bQAAAAEFAAAADnVzZXJBZGRyZXNzU3RyBAAAAA5kZXBvc2l0TnVtVXNlcgkBAAAADGdldEludE9yRWxzZQAAAAIFAAAAG3VzZXJSZXdhcmRGcm9tRGVwb3NpdE51bUtFWQD//////////wQAAAAOZGVwb3NpdE51bUxhc3QJAQAAAAxnZXRJbnRPckVsc2UAAAACCQEAAAARa2V5RGVwb3NpdE51bUxhc3QAAAAAAP//////////CgEAAAAfZm9yRWFjaEFzc2V0Q2FsY1VuY2xhaW1lZFJld2FyZAAAAAIAAAAFYWNjdW0AAAAFYXNzZXQEAAAADSR0MDE4NTY5MTg3MDcJAQAAAApjYWxjUmV3YXJkAAAABQUAAAAOdXNlckFkZHJlc3NTdHIFAAAABWFzc2V0BQAAAA1zdGFrZWRBbW91bnRYBQAAAA5kZXBvc2l0TnVtVXNlcgUAAAAOZGVwb3NpdE51bUxhc3QEAAAAC3Jld2FyZFRvdGFsCAUAAAANJHQwMTg1NjkxODcwNwAAAAJfMQQAAAAGY2FjaGVkCAUAAAANJHQwMTg1NjkxODcwNwAAAAJfMgQAAAAHZHluYW1pYwgFAAAADSR0MDE4NTY5MTg3MDcAAAACXzMEAAAAE3Jld2FyZENhY2hlZFBhcnRLRVkIBQAAAA0kdDAxODU2OTE4NzA3AAAAAl80BAAAAAdjbGFpbWVkCQEAAAALdmFsdWVPckVsc2UAAAACCQAEHwAAAAEJAQAAAAprZXlDbGFpbWVkAAAAAgUAAAAOdXNlckFkZHJlc3NTdHIFAAAABWFzc2V0AAAAAAAAAAAACQABLAAAAAIJAAEsAAAAAgUAAAAFYWNjdW0JAAS5AAAAAgkABEwAAAACBQAAAAVhc3NldAkABEwAAAACCQABpAAAAAEFAAAAC3Jld2FyZFRvdGFsCQAETAAAAAIJAAGkAAAAAQUAAAAHY2xhaW1lZAUAAAADbmlsAgAAAAE6AgAAAAFfCgAAAAACJGwFAAAAE3N1cHBvcnRlZEFzc2V0c0xpc3QKAAAAAAIkcwkAAZAAAAABBQAAAAIkbAoAAAAABSRhY2MwAgAAAAAKAQAAAAUkZjBfMQAAAAIAAAACJGEAAAACJGkD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", "chainId": 87, "height": 3178764, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: SHdwwLzT21iRycAVxXpcdJKg8Z4o7GXr1XRqTEN4irL Next: 24XWyrzVBWBFbvMCBpUzntzxhT7R5zqdh2HJ47vNwbY4 Diff:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let revisionNum = "443c64dd5056b5be23b700224699295e733e0452"
4+let revisionNum = "b3ff7472a1d54a9f0c8f6d6665c4458c36a31e48"
55
66 let separator = "__"
7+
8+let SEP = "__"
79
810 let MULT6 = 1000000
911
175177 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
176178 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
177179 func forEachAssetCacheUserReward (accum,asset) = {
178- let $t074017536 = calcReward(userAddress, asset, stakedAmountX, depositNumUser, depositNumLast)
179- let rewardTotal = $t074017536._1
180- let cached = $t074017536._2
181- let dynamic = $t074017536._3
182- let rewardCachedPartKEY = $t074017536._4
180+ let $t074167551 = calcReward(userAddress, asset, stakedAmountX, depositNumUser, depositNumLast)
181+ let rewardTotal = $t074167551._1
182+ let cached = $t074167551._2
183+ let dynamic = $t074167551._3
184+ let rewardCachedPartKEY = $t074167551._4
183185 (accum :+ IntegerEntry(rewardCachedPartKEY, rewardTotal))
184186 }
185187
240242 }
241243
242244
245+let ContolContractKey = "control_contract"
246+
247+let neutrinoContract = addressFromStringValue(getStringOrFail(keyNeutrinoContractAddress()))
248+
249+let controlContract = addressFromStringValue(getStringValue(neutrinoContract, ContolContractKey))
250+
243251 @Callable(i)
244252 func constructor (neutrinoContractAddress,mathContractAddress,minLockAmount,halfLife,supportedRewardAssets) = if ((i.caller != this))
245253 then throw("Permission denied")
249257
250258 @Callable(i)
251259 func stake () = {
252- let $t01119011269 = getParamsOrFail()
253- let auctionContract = $t01119011269._1
254- let bondAssetId = $t01119011269._2
255- let minLockAmount = $t01119011269._3
256- let halfLife = $t01119011269._4
260+ let $t01144211521 = getParamsOrFail()
261+ let auctionContract = $t01144211521._1
262+ let bondAssetId = $t01144211521._2
263+ let minLockAmount = $t01144211521._3
264+ let halfLife = $t01144211521._4
257265 if ((size(i.payments) != 1))
258266 then throw("Invalid payments size")
259267 else {
266274 else {
267275 let userAddress = i.caller
268276 let userAddressStr = toString(i.caller)
269- let $t01181111918 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, -1))
270- let isNewUser = $t01181111918._1
271- let lockAmount = $t01181111918._2
272- let lockStartHeight = $t01181111918._3
277+ let $t01206312170 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, -1))
278+ let isNewUser = $t01206312170._1
279+ let lockAmount = $t01206312170._2
280+ let lockStartHeight = $t01206312170._3
273281 let mergedAmount = if (isNewUser)
274282 then amount
275283 else (amount + lockAmount)
282290 if ((minLockAmount > mergedAmount))
283291 then throw(("Min lock amount is " + toString(minLockAmount)))
284292 else {
285- let $t01236812470 = StatsResult(amount, 1, if (isNewUser)
293+ let $t01262012722 = StatsResult(amount, 1, if (isNewUser)
286294 then 1
287295 else 0)
288- let statsEntries = $t01236812470._1
289- let totalStaked = $t01236812470._2
290- let totalStakedNew = $t01236812470._3
296+ let statsEntries = $t01262012722._1
297+ let totalStaked = $t01262012722._2
298+ let totalStakedNew = $t01262012722._3
291299 ((([HistoryRecordEntry("stake", userAddress, i.transactionId, lockAmount, lockStartHeight, mergedAmount, mergedStartHeight)] ++ RewardEntries(isNewUser, userAddressStr, lockAmount)) ++ LockParamsEntry(userAddress, mergedAmount, mergedStartHeight)) ++ statsEntries)
292300 }
293301 }
302310 else {
303311 let userAddress = i.caller
304312 let userAddressStr = toString(userAddress)
305- let $t01295613034 = getParamsOrFail()
306- let auctionAddress = $t01295613034._1
307- let bondAssetId = $t01295613034._2
308- let minLockAmount = $t01295613034._3
309- let halfLife = $t01295613034._4
310- let $t01303713111 = getUserParamsOrFail(userAddress)
311- let isNewUser = $t01303713111._1
312- let lockAmount = $t01303713111._2
313- let lockStart = $t01303713111._3
313+ let $t01320813286 = getParamsOrFail()
314+ let auctionAddress = $t01320813286._1
315+ let bondAssetId = $t01320813286._2
316+ let minLockAmount = $t01320813286._3
317+ let halfLife = $t01320813286._4
318+ let $t01328913363 = getUserParamsOrFail(userAddress)
319+ let isNewUser = $t01328913363._1
320+ let lockAmount = $t01328913363._2
321+ let lockStart = $t01328913363._3
314322 if ((0 >= lockAmount))
315323 then throw("Nothing to unstake")
316324 else if ((amount > lockAmount))
318326 else {
319327 let mathContract = addressFromStringValue(getStringOrFail(keyMathContractAddress()))
320328 let comissionAmount = asInt(invoke(mathContract, "getUnstakeComissionAmountREADONLY", [amount, lockStart, halfLife], nil))
321- let $t01351213666 = StatsResult(-(amount), if ((amount == lockAmount))
329+ let $t01376413918 = StatsResult(-(amount), if ((amount == lockAmount))
322330 then -1
323331 else 0, if ((amount == lockAmount))
324332 then -1
325333 else 0)
326- let statsEntries = $t01351213666._1
327- let totalStaked = $t01351213666._2
328- let totalStakedNew = $t01351213666._3
334+ let statsEntries = $t01376413918._1
335+ let totalStaked = $t01376413918._2
336+ let totalStakedNew = $t01376413918._3
329337 ((([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)
330338 }
331339 }
393401 if ((size(i.payments) > 0))
394402 then throw("payments are not accepted")
395403 else {
396- let $t01592216027 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
397- let isNewUser = $t01592216027._1
398- let stakedAmount = $t01592216027._2
399- let stakingStart = $t01592216027._3
404+ let $t01617416279 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
405+ let isNewUser = $t01617416279._1
406+ let stakedAmount = $t01617416279._2
407+ let stakingStart = $t01617416279._3
400408 let stakedAmountX = toBigInt(stakedAmount)
401409 let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddressStr)
402410 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
403411 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
404412 func forEachAssetCalcUnclaimedReward (accum,asset) = {
405- let $t01639816536 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
406- let rewardTotal = $t01639816536._1
407- let cached = $t01639816536._2
408- let dynamic = $t01639816536._3
409- let rewardCachedPartKEY = $t01639816536._4
413+ let $t01665016788 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
414+ let rewardTotal = $t01665016788._1
415+ let cached = $t01665016788._2
416+ let dynamic = $t01665016788._3
417+ let rewardCachedPartKEY = $t01665016788._4
410418 let claimedKEY = keyClaimed(userAddressStr, asset)
411- let $t01659616633 = accum
412- let data = $t01659616633._1
413- let claimedAmtByAsset = $t01659616633._2
419+ let $t01684816885 = accum
420+ let data = $t01684816885._1
421+ let claimedAmtByAsset = $t01684816885._2
414422 let newPart = makeString([asset, toString(rewardTotal)], ":")
415423 let claimedAmtByAssetNew = makeString([claimedAmtByAsset, newPart], "_")
416424 if ((0 >= rewardTotal))
418426 else $Tuple2((((data :+ ScriptTransfer(userAddress, rewardTotal, toAssetVect(asset))) :+ IntegerEntry(claimedKEY, (valueOrElse(getInteger(claimedKEY), 0) + rewardTotal))) :+ IntegerEntry(rewardCachedPartKEY, 0)), claimedAmtByAssetNew)
419427 }
420428
421- let $t01709317207 = {
429+ let $t01734517459 = {
422430 let $l = supportedAssetsList
423431 let $s = size($l)
424432 let $acc0 = $Tuple2(nil, "")
432440
433441 $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)
434442 }
435- let transfers = $t01709317207._1
436- let claimedAmtByAssetResult = $t01709317207._2
443+ let transfers = $t01734517459._1
444+ let claimedAmtByAssetResult = $t01734517459._2
437445 if ((0 >= size(transfers)))
438446 then throw("nothing to claim")
439447 else ((transfers :+ IntegerEntry(userRewardFromDepositNumKEY, depositNumLast)) :+ ClaimHistoryEntry(userAddress, i.transactionId, drop(claimedAmtByAssetResult, 1)))
463471 }
464472 else {
465473 let userAddress = addressFromStringValue(userAddressStr)
466- let $t01786617971 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
467- let isNewUser = $t01786617971._1
468- let stakedAmount = $t01786617971._2
469- let stakingStart = $t01786617971._3
474+ let $t01811818223 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
475+ let isNewUser = $t01811818223._1
476+ let stakedAmount = $t01811818223._2
477+ let stakingStart = $t01811818223._3
470478 let stakedAmountX = toBigInt(stakedAmount)
471479 let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddressStr)
472480 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
473481 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
474482 func forEachAssetCalcUnclaimedReward (accum,asset) = {
475- let $t01831718455 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
476- let rewardTotal = $t01831718455._1
477- let cached = $t01831718455._2
478- let dynamic = $t01831718455._3
479- let rewardCachedPartKEY = $t01831718455._4
483+ let $t01856918707 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
484+ let rewardTotal = $t01856918707._1
485+ let cached = $t01856918707._2
486+ let dynamic = $t01856918707._3
487+ let rewardCachedPartKEY = $t01856918707._4
480488 let claimed = valueOrElse(getInteger(keyClaimed(userAddressStr, asset)), 0)
481489 ((accum + makeString([asset, toString(rewardTotal), toString(claimed)], ":")) + "_")
482490 }
506514 then $Tuple2(nil, [0, totalNsbtAmt, 0])
507515 else {
508516 let userAddress = toAddressOrFail(userAddressStr)
509- let $t01905919163 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
510- let isNewUser = $t01905919163._1
511- let userNsbtAmt = $t01905919163._2
512- let stakingStart = $t01905919163._3
517+ let $t01931119415 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
518+ let isNewUser = $t01931119415._1
519+ let userNsbtAmt = $t01931119415._2
520+ let stakingStart = $t01931119415._3
513521 $Tuple2(nil, [userNsbtAmt, totalNsbtAmt, stakingStart])
514522 }
515523 }
517525
518526 @Verifier(tx)
519527 func verify () = {
520- let pubKeyAdminsList = ["GJdLSaLiv5K7xuejac8mcRcHoyo3dPrESrvktG3a6MAR", "FWVffYr2ALmHMejZm3WqeLz6Sdym3gLFGtJn4KTwyU5x", "3Wh2LaWcb5gg7K2pPcW3Ep6EAuRBzYkAgrdpt43jTDFa", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"]
528+ let pubKeyAdminsListStr = makeString(["GJdLSaLiv5K7xuejac8mcRcHoyo3dPrESrvktG3a6MAR", "EYwZmURd5KKaQRBjsVa6g8DPisFoS6SovRJtFiL5gMHU", "DtmAfuDdCrHK8spdAeAYzq6MsZegeD9gnsrpuTRkCbVA", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"], SEP)
529+ let pubKeyAdminsList = split(valueOrElse(getString(controlContract, "%s__multisig"), pubKeyAdminsListStr), SEP)
521530 let count = ((((if (sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(pubKeyAdminsList[0])))
522531 then 1
523532 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 #-}
4-let revisionNum = "443c64dd5056b5be23b700224699295e733e0452"
4+let revisionNum = "b3ff7472a1d54a9f0c8f6d6665c4458c36a31e48"
55
66 let separator = "__"
7+
8+let SEP = "__"
79
810 let MULT6 = 1000000
911
1012 let MULT8 = 100000000
1113
1214 let MULTX6 = toBigInt(MULT6)
1315
1416 let MULTX8 = toBigInt(MULT8)
1517
1618 let MULTX18 = toBigInt(1000000000000000000)
1719
1820 let WAVESIDSTR = "WAVES"
1921
2022 let WAVESID = fromBase58String(WAVESIDSTR)
2123
2224 func keyBondAsset () = "bond_asset_id"
2325
2426
2527 func keyAuctionContractAddress () = "auction_contract"
2628
2729
2830 func keyNeutrinoContractAddress () = "%s__neutrinoContractAddress"
2931
3032
3133 func keyMathContractAddress () = "%s__mathContract"
3234
3335
3436 func keyMinLockAmount () = "%s__minLockAmount"
3537
3638
3739 func keyHalfLife () = "%s__halfLife"
3840
3941
4042 func keyLockParamUserAmount (userAddress) = makeString(["%s%s%s", "paramByUser", toString(userAddress), "amount"], separator)
4143
4244
4345 func keyLockParamStartBlock (userAddress) = makeString(["%s%s%s", "paramByUser", toString(userAddress), "start"], separator)
4446
4547
4648 func keyHistoryRecord (type,userAddress,txId) = makeString(["%s%s%s%s", "history", type, toString(userAddress), toBase58String(txId)], separator)
4749
4850
4951 func keyLockParamTotalAmount () = makeString(["%s%s", "stats", "activeTotalLocked"], separator)
5052
5153
5254 func keyStatsLocksCount () = makeString(["%s%s", "stats", "locksCount"], separator)
5355
5456
5557 func keyStatsUsersCount () = makeString(["%s%s", "stats", "activeUsersCount"], separator)
5658
5759
5860 func keyNextPeriod () = "%s__nextPeriod"
5961
6062
6163 func keySupportedRewardAssets () = "supportedRewardAssets"
6264
6365
6466 func keyDepositNumLast () = makeString(["%s%s%s", "dep", "lastNum"], separator)
6567
6668
6769 func keyUserRewardFromDepositNum (userAddress) = makeString(["%s%s%s", "userRwdFromDepNum", userAddress], separator)
6870
6971
7072 func keyRewardPerNsbtSumAt (depositNum,tkn) = makeString(["%s%d", "rwdPerNsbtSumByDepNum", toString(depositNum), tkn], separator)
7173
7274
7375 func keyReward (userAddress,tkn) = makeString(["%s%s%s", "rwd", userAddress, tkn], separator)
7476
7577
7678 func keyClaimed (userAddress,tkn) = makeString(["%s%s%s", "clm", userAddress, tkn], separator)
7779
7880
7981 func keyNotDistributedReward (tkn) = makeString(["%s%s", "notDistributed", tkn], separator)
8082
8183
8284 func toX18 (origVal,origMult) = fraction(toBigInt(origVal), MULTX18, origMult)
8385
8486
8587 func getIntOrZero (key) = valueOrElse(getInteger(this, key), 0)
8688
8789
8890 func getIntOrElse (key,defaultVal) = valueOrElse(getInteger(this, key), defaultVal)
8991
9092
9193 func getIntOrFail (key) = valueOrErrorMessage(getInteger(this, key), (("Mandatory this." + key) + " is not defined"))
9294
9395
9496 func getStrOrElse (key,defaultVal) = valueOrElse(getString(this, key), defaultVal)
9597
9698
9799 func getStringOrFail (key) = valueOrErrorMessage(getString(this, key), (("Mandatory this." + key) + " is not defined"))
98100
99101
100102 func toAddressOrFail (addressStr) = valueOrErrorMessage(addressFromString(addressStr), ("couldn't parse passed addressStr=" + addressStr))
101103
102104
103105 func toAssetVect (assetStr) = if ((assetStr == WAVESIDSTR))
104106 then unit
105107 else fromBase58String(assetStr)
106108
107109
108110 func asInt (val) = match val {
109111 case valInt: Int =>
110112 valInt
111113 case _ =>
112114 throw("fail to cast into Int")
113115 }
114116
115117
116118 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)
117119
118120
119121 func formatClaimHistoryRecord (user,claimedRewards) = makeString(["%s%d%d%s", user, toString(lastBlock.height), toString(lastBlock.timestamp), claimedRewards], separator)
120122
121123
122124 func HistoryRecordEntry (type,userAddress,txId,oldAmount,oldStart,newAmount,newStart) = StringEntry(keyHistoryRecord(type, userAddress, txId), formatHistoryRecord(oldAmount, oldStart, newAmount, newStart))
123125
124126
125127 func ClaimHistoryEntry (userAddress,txId,claimedRewards) = StringEntry(keyHistoryRecord("claim", userAddress, txId), formatClaimHistoryRecord(toString(userAddress), claimedRewards))
126128
127129
128130 func StatsResult (totalLockedInc,lockCountInc,usersCountInc) = {
129131 let locksCount = getIntOrZero(keyStatsLocksCount())
130132 let usersCount = getIntOrZero(keyStatsUsersCount())
131133 let totalAmount = getIntOrZero(keyLockParamTotalAmount())
132134 let totalAmountNew = (totalAmount + totalLockedInc)
133135 $Tuple3([IntegerEntry(keyStatsLocksCount(), (locksCount + lockCountInc)), IntegerEntry(keyStatsUsersCount(), (usersCount + usersCountInc)), IntegerEntry(keyLockParamTotalAmount(), totalAmountNew)], totalAmount, totalAmountNew)
134136 }
135137
136138
137139 func LockParamsEntry (userAddress,amount,start) = [IntegerEntry(keyLockParamUserAmount(userAddress), amount), IntegerEntry(keyLockParamStartBlock(userAddress), start)]
138140
139141
140142 func getParamsOrFail () = {
141143 let neutrinoContract = addressFromStringValue(getStringOrFail(keyNeutrinoContractAddress()))
142144 $Tuple4(fromBase58String(getStringValue(neutrinoContract, keyAuctionContractAddress())), fromBase58String(getStringValue(neutrinoContract, keyBondAsset())), getIntOrFail(keyMinLockAmount()), getIntOrFail(keyHalfLife()))
143145 }
144146
145147
146148 func isActiveUser (userAddress) = (getIntOrElse(keyLockParamUserAmount(userAddress), 0) > 0)
147149
148150
149151 func getUserParamsOrUnit (userAddress) = if (isActiveUser(userAddress))
150152 then $Tuple3(false, getIntOrFail(keyLockParamUserAmount(userAddress)), getIntOrFail(keyLockParamStartBlock(userAddress)))
151153 else unit
152154
153155
154156 func getUserParamsOrFail (userAddress) = valueOrErrorMessage(getUserParamsOrUnit(userAddress), (("User " + toString(userAddress)) + " is not defined"))
155157
156158
157159 let supportedAssetsStr = getStrOrElse(keySupportedRewardAssets(), "")
158160
159161 let supportedAssetsList = split(supportedAssetsStr, "_")
160162
161163 func calcReward (userAddress,assetId,stakedAmountX,depositNumUser,depositNumLast) = {
162164 let rewardPerNsbtSumLastKEY = keyRewardPerNsbtSumAt(depositNumLast, assetId)
163165 let sumLastX18 = parseBigIntValue(getStrOrElse(keyRewardPerNsbtSumAt(depositNumLast, assetId), "0"))
164166 let sumUserX18 = parseBigIntValue(getStrOrElse(keyRewardPerNsbtSumAt(depositNumUser, assetId), "0"))
165167 let rewardDynamicPart = toInt(fraction((sumLastX18 - sumUserX18), stakedAmountX, MULTX18))
166168 let rewardCachedPartKEY = keyReward(userAddress, assetId)
167169 let rewardCachedPart = getIntOrElse(rewardCachedPartKEY, 0)
168170 $Tuple4((rewardCachedPart + rewardDynamicPart), rewardCachedPart, rewardDynamicPart, rewardCachedPartKEY)
169171 }
170172
171173
172174 func RewardEntries (isNewUser,userAddress,stakedAmount) = {
173175 let stakedAmountX = toBigInt(stakedAmount)
174176 let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddress)
175177 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
176178 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
177179 func forEachAssetCacheUserReward (accum,asset) = {
178- let $t074017536 = calcReward(userAddress, asset, stakedAmountX, depositNumUser, depositNumLast)
179- let rewardTotal = $t074017536._1
180- let cached = $t074017536._2
181- let dynamic = $t074017536._3
182- let rewardCachedPartKEY = $t074017536._4
180+ let $t074167551 = calcReward(userAddress, asset, stakedAmountX, depositNumUser, depositNumLast)
181+ let rewardTotal = $t074167551._1
182+ let cached = $t074167551._2
183+ let dynamic = $t074167551._3
184+ let rewardCachedPartKEY = $t074167551._4
183185 (accum :+ IntegerEntry(rewardCachedPartKEY, rewardTotal))
184186 }
185187
186188 if (if ((depositNumLast == -1))
187189 then (depositNumUser == -1)
188190 else false)
189191 then nil
190192 else if (if ((depositNumLast == -1))
191193 then (depositNumUser > -1)
192194 else false)
193195 then throw("invalid depositNumLast and depositNumUser state")
194196 else if (if ((depositNumLast > -1))
195197 then (depositNumUser == -1)
196198 else false)
197199 then if (isNewUser)
198200 then [IntegerEntry(userRewardFromDepositNumKEY, depositNumLast)]
199201 else ({
200202 let $l = supportedAssetsList
201203 let $s = size($l)
202204 let $acc0 = nil
203205 func $f0_1 ($a,$i) = if (($i >= $s))
204206 then $a
205207 else forEachAssetCacheUserReward($a, $l[$i])
206208
207209 func $f0_2 ($a,$i) = if (($i >= $s))
208210 then $a
209211 else throw("List size exceeds 10")
210212
211213 $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)
212214 } :+ IntegerEntry(userRewardFromDepositNumKEY, depositNumLast))
213215 else if (if ((depositNumLast > -1))
214216 then (depositNumUser > -1)
215217 else false)
216218 then if (isNewUser)
217219 then [IntegerEntry(userRewardFromDepositNumKEY, depositNumLast)]
218220 else ({
219221 let $l = supportedAssetsList
220222 let $s = size($l)
221223 let $acc0 = nil
222224 func $f0_1 ($a,$i) = if (($i >= $s))
223225 then $a
224226 else forEachAssetCacheUserReward($a, $l[$i])
225227
226228 func $f0_2 ($a,$i) = if (($i >= $s))
227229 then $a
228230 else throw("List size exceeds 10")
229231
230232 $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)
231233 } :+ IntegerEntry(userRewardFromDepositNumKEY, depositNumLast))
232234 else throw(((("uncovered condition: depositNumLast=" + toString(depositNumLast)) + " depositNumUser=") + toString(depositNumUser)))
233235 }
234236
235237
236238 func IncrementNotDistributedRewardEntry (tkn,amountInc) = {
237239 let notDistributedRewardKEY = keyNotDistributedReward(tkn)
238240 let notDistributedReward = getIntOrElse(notDistributedRewardKEY, 0)
239241 [IntegerEntry(notDistributedRewardKEY, (notDistributedReward + amountInc))]
240242 }
241243
242244
245+let ContolContractKey = "control_contract"
246+
247+let neutrinoContract = addressFromStringValue(getStringOrFail(keyNeutrinoContractAddress()))
248+
249+let controlContract = addressFromStringValue(getStringValue(neutrinoContract, ContolContractKey))
250+
243251 @Callable(i)
244252 func constructor (neutrinoContractAddress,mathContractAddress,minLockAmount,halfLife,supportedRewardAssets) = if ((i.caller != this))
245253 then throw("Permission denied")
246254 else [StringEntry(keyNeutrinoContractAddress(), neutrinoContractAddress), StringEntry(keyMathContractAddress(), mathContractAddress), IntegerEntry(keyMinLockAmount(), minLockAmount), IntegerEntry(keyHalfLife(), halfLife), StringEntry(keySupportedRewardAssets(), supportedRewardAssets)]
247255
248256
249257
250258 @Callable(i)
251259 func stake () = {
252- let $t01119011269 = getParamsOrFail()
253- let auctionContract = $t01119011269._1
254- let bondAssetId = $t01119011269._2
255- let minLockAmount = $t01119011269._3
256- let halfLife = $t01119011269._4
260+ let $t01144211521 = getParamsOrFail()
261+ let auctionContract = $t01144211521._1
262+ let bondAssetId = $t01144211521._2
263+ let minLockAmount = $t01144211521._3
264+ let halfLife = $t01144211521._4
257265 if ((size(i.payments) != 1))
258266 then throw("Invalid payments size")
259267 else {
260268 let payment = i.payments[0]
261269 let amount = payment.amount
262270 let invalidAssetMessage = (("Invalid asset. " + toBase58String(bondAssetId)) + " is expected")
263271 let assetId = valueOrErrorMessage(payment.assetId, invalidAssetMessage)
264272 if ((assetId != bondAssetId))
265273 then throw(invalidAssetMessage)
266274 else {
267275 let userAddress = i.caller
268276 let userAddressStr = toString(i.caller)
269- let $t01181111918 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, -1))
270- let isNewUser = $t01181111918._1
271- let lockAmount = $t01181111918._2
272- let lockStartHeight = $t01181111918._3
277+ let $t01206312170 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, -1))
278+ let isNewUser = $t01206312170._1
279+ let lockAmount = $t01206312170._2
280+ let lockStartHeight = $t01206312170._3
273281 let mergedAmount = if (isNewUser)
274282 then amount
275283 else (amount + lockAmount)
276284 let mergedStartHeight = if (isNewUser)
277285 then height
278286 else {
279287 let mathContract = addressFromStringValue(getStringOrFail(keyMathContractAddress()))
280288 asInt(invoke(mathContract, "mergeStakesREADONLY", [amount, height, lockAmount, lockStartHeight, halfLife], nil))
281289 }
282290 if ((minLockAmount > mergedAmount))
283291 then throw(("Min lock amount is " + toString(minLockAmount)))
284292 else {
285- let $t01236812470 = StatsResult(amount, 1, if (isNewUser)
293+ let $t01262012722 = StatsResult(amount, 1, if (isNewUser)
286294 then 1
287295 else 0)
288- let statsEntries = $t01236812470._1
289- let totalStaked = $t01236812470._2
290- let totalStakedNew = $t01236812470._3
296+ let statsEntries = $t01262012722._1
297+ let totalStaked = $t01262012722._2
298+ let totalStakedNew = $t01262012722._3
291299 ((([HistoryRecordEntry("stake", userAddress, i.transactionId, lockAmount, lockStartHeight, mergedAmount, mergedStartHeight)] ++ RewardEntries(isNewUser, userAddressStr, lockAmount)) ++ LockParamsEntry(userAddress, mergedAmount, mergedStartHeight)) ++ statsEntries)
292300 }
293301 }
294302 }
295303 }
296304
297305
298306
299307 @Callable(i)
300308 func unstake (amount) = if ((size(i.payments) != 0))
301309 then throw("unstake doesn't require any payment")
302310 else {
303311 let userAddress = i.caller
304312 let userAddressStr = toString(userAddress)
305- let $t01295613034 = getParamsOrFail()
306- let auctionAddress = $t01295613034._1
307- let bondAssetId = $t01295613034._2
308- let minLockAmount = $t01295613034._3
309- let halfLife = $t01295613034._4
310- let $t01303713111 = getUserParamsOrFail(userAddress)
311- let isNewUser = $t01303713111._1
312- let lockAmount = $t01303713111._2
313- let lockStart = $t01303713111._3
313+ let $t01320813286 = getParamsOrFail()
314+ let auctionAddress = $t01320813286._1
315+ let bondAssetId = $t01320813286._2
316+ let minLockAmount = $t01320813286._3
317+ let halfLife = $t01320813286._4
318+ let $t01328913363 = getUserParamsOrFail(userAddress)
319+ let isNewUser = $t01328913363._1
320+ let lockAmount = $t01328913363._2
321+ let lockStart = $t01328913363._3
314322 if ((0 >= lockAmount))
315323 then throw("Nothing to unstake")
316324 else if ((amount > lockAmount))
317325 then throw(((("Requested " + toString(amount)) + ", but staked only ") + toString(lockAmount)))
318326 else {
319327 let mathContract = addressFromStringValue(getStringOrFail(keyMathContractAddress()))
320328 let comissionAmount = asInt(invoke(mathContract, "getUnstakeComissionAmountREADONLY", [amount, lockStart, halfLife], nil))
321- let $t01351213666 = StatsResult(-(amount), if ((amount == lockAmount))
329+ let $t01376413918 = StatsResult(-(amount), if ((amount == lockAmount))
322330 then -1
323331 else 0, if ((amount == lockAmount))
324332 then -1
325333 else 0)
326- let statsEntries = $t01351213666._1
327- let totalStaked = $t01351213666._2
328- let totalStakedNew = $t01351213666._3
334+ let statsEntries = $t01376413918._1
335+ let totalStaked = $t01376413918._2
336+ let totalStakedNew = $t01376413918._3
329337 ((([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)
330338 }
331339 }
332340
333341
334342
335343 @Callable(i)
336344 func deposit () = if ((size(i.payments) != 1))
337345 then throw("exact 1 payment is allowed only")
338346 else {
339347 let pmt = i.payments[0]
340348 let amount = pmt.amount
341349 let pmtAssetId = valueOrElse(pmt.assetId, WAVESID)
342350 let pmtAssetIdStr = toBase58String(pmtAssetId)
343351 let pmtMultX = if ((pmtAssetId == WAVESID))
344352 then MULTX8
345353 else MULTX6
346354 let amountX = toBigInt(amount)
347355 let totalStaked = getIntOrElse(keyLockParamTotalAmount(), 0)
348356 let totalStakedX = toBigInt(totalStaked)
349357 if ((0 > totalStaked))
350358 then throw("TODO: case is not supported")
351359 else if ((totalStaked == 0))
352360 then IncrementNotDistributedRewardEntry(pmtAssetIdStr, amount)
353361 else {
354362 let rewardPerNsbtX18 = fraction(amountX, MULTX18, totalStakedX)
355363 let depositNumLastKEY = keyDepositNumLast()
356364 let depositNumLast = getIntOrElse(depositNumLastKEY, -1)
357365 let depositNumNew = (depositNumLast + 1)
358366 if (!(contains(supportedAssetsStr, pmtAssetIdStr)))
359367 then throw(((supportedAssetsStr + " doesn't contain ") + pmtAssetIdStr))
360368 else {
361369 func refreshRewardPerNsbtSUM (accum,nextAsset) = {
362370 let rewardPerNsbtSumNewKEY = keyRewardPerNsbtSumAt(depositNumNew, nextAsset)
363371 let sumLastStr = getStrOrElse(keyRewardPerNsbtSumAt(depositNumLast, nextAsset), "0")
364372 (accum :+ (if ((nextAsset == pmtAssetIdStr))
365373 then StringEntry(rewardPerNsbtSumNewKEY, toString((parseBigIntValue(sumLastStr) + rewardPerNsbtX18)))
366374 else StringEntry(rewardPerNsbtSumNewKEY, sumLastStr)))
367375 }
368376
369377 ({
370378 let $l = supportedAssetsList
371379 let $s = size($l)
372380 let $acc0 = nil
373381 func $f0_1 ($a,$i) = if (($i >= $s))
374382 then $a
375383 else refreshRewardPerNsbtSUM($a, $l[$i])
376384
377385 func $f0_2 ($a,$i) = if (($i >= $s))
378386 then $a
379387 else throw("List size exceeds 10")
380388
381389 $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)
382390 } :+ IntegerEntry(depositNumLastKEY, depositNumNew))
383391 }
384392 }
385393 }
386394
387395
388396
389397 @Callable(i)
390398 func claimRewards () = {
391399 let userAddress = i.caller
392400 let userAddressStr = toString(userAddress)
393401 if ((size(i.payments) > 0))
394402 then throw("payments are not accepted")
395403 else {
396- let $t01592216027 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
397- let isNewUser = $t01592216027._1
398- let stakedAmount = $t01592216027._2
399- let stakingStart = $t01592216027._3
404+ let $t01617416279 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
405+ let isNewUser = $t01617416279._1
406+ let stakedAmount = $t01617416279._2
407+ let stakingStart = $t01617416279._3
400408 let stakedAmountX = toBigInt(stakedAmount)
401409 let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddressStr)
402410 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
403411 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
404412 func forEachAssetCalcUnclaimedReward (accum,asset) = {
405- let $t01639816536 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
406- let rewardTotal = $t01639816536._1
407- let cached = $t01639816536._2
408- let dynamic = $t01639816536._3
409- let rewardCachedPartKEY = $t01639816536._4
413+ let $t01665016788 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
414+ let rewardTotal = $t01665016788._1
415+ let cached = $t01665016788._2
416+ let dynamic = $t01665016788._3
417+ let rewardCachedPartKEY = $t01665016788._4
410418 let claimedKEY = keyClaimed(userAddressStr, asset)
411- let $t01659616633 = accum
412- let data = $t01659616633._1
413- let claimedAmtByAsset = $t01659616633._2
419+ let $t01684816885 = accum
420+ let data = $t01684816885._1
421+ let claimedAmtByAsset = $t01684816885._2
414422 let newPart = makeString([asset, toString(rewardTotal)], ":")
415423 let claimedAmtByAssetNew = makeString([claimedAmtByAsset, newPart], "_")
416424 if ((0 >= rewardTotal))
417425 then $Tuple2(data, claimedAmtByAssetNew)
418426 else $Tuple2((((data :+ ScriptTransfer(userAddress, rewardTotal, toAssetVect(asset))) :+ IntegerEntry(claimedKEY, (valueOrElse(getInteger(claimedKEY), 0) + rewardTotal))) :+ IntegerEntry(rewardCachedPartKEY, 0)), claimedAmtByAssetNew)
419427 }
420428
421- let $t01709317207 = {
429+ let $t01734517459 = {
422430 let $l = supportedAssetsList
423431 let $s = size($l)
424432 let $acc0 = $Tuple2(nil, "")
425433 func $f0_1 ($a,$i) = if (($i >= $s))
426434 then $a
427435 else forEachAssetCalcUnclaimedReward($a, $l[$i])
428436
429437 func $f0_2 ($a,$i) = if (($i >= $s))
430438 then $a
431439 else throw("List size exceeds 10")
432440
433441 $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)
434442 }
435- let transfers = $t01709317207._1
436- let claimedAmtByAssetResult = $t01709317207._2
443+ let transfers = $t01734517459._1
444+ let claimedAmtByAssetResult = $t01734517459._2
437445 if ((0 >= size(transfers)))
438446 then throw("nothing to claim")
439447 else ((transfers :+ IntegerEntry(userRewardFromDepositNumKEY, depositNumLast)) :+ ClaimHistoryEntry(userAddress, i.transactionId, drop(claimedAmtByAssetResult, 1)))
440448 }
441449 }
442450
443451
444452
445453 @Callable(i)
446454 func unclaimedRewardsREADONLY (userAddressStr) = {
447455 func forEachAssetZeroReward (accum,asset) = ((accum + makeString([asset, "0", "0"], ":")) + "_")
448456
449457 let unclaimedRewardStr = if ((userAddressStr == ""))
450458 then {
451459 let $l = supportedAssetsList
452460 let $s = size($l)
453461 let $acc0 = ""
454462 func $f0_1 ($a,$i) = if (($i >= $s))
455463 then $a
456464 else forEachAssetZeroReward($a, $l[$i])
457465
458466 func $f0_2 ($a,$i) = if (($i >= $s))
459467 then $a
460468 else throw("List size exceeds 10")
461469
462470 $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)
463471 }
464472 else {
465473 let userAddress = addressFromStringValue(userAddressStr)
466- let $t01786617971 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
467- let isNewUser = $t01786617971._1
468- let stakedAmount = $t01786617971._2
469- let stakingStart = $t01786617971._3
474+ let $t01811818223 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
475+ let isNewUser = $t01811818223._1
476+ let stakedAmount = $t01811818223._2
477+ let stakingStart = $t01811818223._3
470478 let stakedAmountX = toBigInt(stakedAmount)
471479 let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddressStr)
472480 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
473481 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
474482 func forEachAssetCalcUnclaimedReward (accum,asset) = {
475- let $t01831718455 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
476- let rewardTotal = $t01831718455._1
477- let cached = $t01831718455._2
478- let dynamic = $t01831718455._3
479- let rewardCachedPartKEY = $t01831718455._4
483+ let $t01856918707 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
484+ let rewardTotal = $t01856918707._1
485+ let cached = $t01856918707._2
486+ let dynamic = $t01856918707._3
487+ let rewardCachedPartKEY = $t01856918707._4
480488 let claimed = valueOrElse(getInteger(keyClaimed(userAddressStr, asset)), 0)
481489 ((accum + makeString([asset, toString(rewardTotal), toString(claimed)], ":")) + "_")
482490 }
483491
484492 let $l = supportedAssetsList
485493 let $s = size($l)
486494 let $acc0 = ""
487495 func $f0_1 ($a,$i) = if (($i >= $s))
488496 then $a
489497 else forEachAssetCalcUnclaimedReward($a, $l[$i])
490498
491499 func $f0_2 ($a,$i) = if (($i >= $s))
492500 then $a
493501 else throw("List size exceeds 10")
494502
495503 $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)
496504 }
497505 $Tuple2(nil, dropRight(unclaimedRewardStr, 1))
498506 }
499507
500508
501509
502510 @Callable(i)
503511 func nsbtStakingSYSREADONLY (userAddressStr) = {
504512 let totalNsbtAmt = getIntOrElse(keyLockParamTotalAmount(), 0)
505513 if ((userAddressStr == ""))
506514 then $Tuple2(nil, [0, totalNsbtAmt, 0])
507515 else {
508516 let userAddress = toAddressOrFail(userAddressStr)
509- let $t01905919163 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
510- let isNewUser = $t01905919163._1
511- let userNsbtAmt = $t01905919163._2
512- let stakingStart = $t01905919163._3
517+ let $t01931119415 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
518+ let isNewUser = $t01931119415._1
519+ let userNsbtAmt = $t01931119415._2
520+ let stakingStart = $t01931119415._3
513521 $Tuple2(nil, [userNsbtAmt, totalNsbtAmt, stakingStart])
514522 }
515523 }
516524
517525
518526 @Verifier(tx)
519527 func verify () = {
520- let pubKeyAdminsList = ["GJdLSaLiv5K7xuejac8mcRcHoyo3dPrESrvktG3a6MAR", "FWVffYr2ALmHMejZm3WqeLz6Sdym3gLFGtJn4KTwyU5x", "3Wh2LaWcb5gg7K2pPcW3Ep6EAuRBzYkAgrdpt43jTDFa", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"]
528+ let pubKeyAdminsListStr = makeString(["GJdLSaLiv5K7xuejac8mcRcHoyo3dPrESrvktG3a6MAR", "EYwZmURd5KKaQRBjsVa6g8DPisFoS6SovRJtFiL5gMHU", "DtmAfuDdCrHK8spdAeAYzq6MsZegeD9gnsrpuTRkCbVA", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"], SEP)
529+ let pubKeyAdminsList = split(valueOrElse(getString(controlContract, "%s__multisig"), pubKeyAdminsListStr), SEP)
521530 let count = ((((if (sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(pubKeyAdminsList[0])))
522531 then 1
523532 else 0) + (if (sigVerify(tx.bodyBytes, tx.proofs[1], fromBase58String(pubKeyAdminsList[1])))
524533 then 1
525534 else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[2], fromBase58String(pubKeyAdminsList[2])))
526535 then 1
527536 else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[3], fromBase58String(pubKeyAdminsList[3])))
528537 then 2
529538 else 0))
530539 (count >= 3)
531540 }
532541

github/deemru/w8io/786bc32 
83.46 ms