tx · CWa7rzWnjopxgzHUqaFMAucGu73gRRxWJ9K7H3PGFqxG

3MzTHd4e3yukNUURApVLVzH5uxeEsXHD6yY:  -0.01400000 Waves

2021.07.28 16:26 [1633559] smart account 3MzTHd4e3yukNUURApVLVzH5uxeEsXHD6yY > SELF 0.00000000 Waves

{ "type": 13, "id": "CWa7rzWnjopxgzHUqaFMAucGu73gRRxWJ9K7H3PGFqxG", "fee": 1400000, "feeAssetId": null, "timestamp": 1627478793846, "version": 2, "chainId": 84, "sender": "3MzTHd4e3yukNUURApVLVzH5uxeEsXHD6yY", "senderPublicKey": "DhKV985fxsz63vhWDNTF3gWwe7AHS4RsGjR2BzThJRYa", "proofs": [ "1L1h5YrXY3hmDVk1SDgF2j6TJM7QpjbC8FRt7JoRa3XWrf5aXSrKrktXD7oW4qXVC5WuYDuSJD6tNHwK4GVFX6W", "x6yh8mA6UGHYQjpgbbRz2Rs5FDzpp19Zk3qQW8wBheBohH3CNBrCQHwb8ZoAe58KgR1fKR5m8kaH5c3eYAYxgmh" ], "script": "base64:AAIFAAAAAAAAACoIAhIDCgEEEgcKBQEBCAgEEgMKAQESAwoBARIAEgMKAQESABIAEgMKAQEAAABUAAAAAAd2ZXJzaW9uAgAAAAUxLjAuMAAAAAAKa2V5VmVyc2lvbgIAAAAHdmVyc2lvbgAAAAAJa2V5QWN0aXZlAgAAAAZhY3RpdmUAAAAAC2tleUFzc2V0SWRBAgAAAApBX2Fzc2V0X2lkAAAAAAtrZXlBc3NldElkQgIAAAAKQl9hc3NldF9pZAAAAAALa2V5QmFsYW5jZUECAAAAD0FfYXNzZXRfYmFsYW5jZQAAAAALa2V5QmFsYW5jZUICAAAAD0JfYXNzZXRfYmFsYW5jZQAAAAAPa2V5QmFsYW5jZUluaXRBAgAAAAxBX2Fzc2V0X2luaXQAAAAAD2tleUJhbGFuY2VJbml0QgIAAAAMQl9hc3NldF9pbml0AAAAAA9rZXlTaGFyZUFzc2V0SWQCAAAADnNoYXJlX2Fzc2V0X2lkAAAAABNrZXlTaGFyZUFzc2V0U3VwcGx5AgAAABJzaGFyZV9hc3NldF9zdXBwbHkAAAAADWtleUNvbW1pc3Npb24CAAAACmNvbW1pc3Npb24AAAAAG2tleUNvbW1pc3Npb25TY2FsZURlbGltaXRlcgIAAAAaY29tbWlzc2lvbl9zY2FsZV9kZWxpbWl0ZXIAAAAACGtleUNhdXNlAgAAAA5zaHV0ZG93bl9jYXVzZQAAAAAPa2V5Rmlyc3RIYXJ2ZXN0AgAAAA1maXJzdF9oYXJ2ZXN0AAAAABVrZXlGaXJzdEhhcnZlc3RIZWlnaHQCAAAAFGZpcnN0X2hhcnZlc3RfaGVpZ2h0AAAAAAtrU2hhcmVMaW1pdAIAAAAcc2hhcmVfbGltaXRfb25fZmlyc3RfaGFydmVzdAAAAAALa0Jhc2VQZXJpb2QCAAAAC2Jhc2VfcGVyaW9kAAAAAA1rUGVyaW9kTGVuZ3RoAgAAAA1wZXJpb2RfbGVuZ3RoAAAAAAxrU3RhcnRIZWlnaHQCAAAADHN0YXJ0X2hlaWdodAAAAAATa0ZpcnN0SGFydmVzdEhlaWdodAIAAAAUZmlyc3RfaGFydmVzdF9oZWlnaHQAAAAAD2tleUFkbWluUHViS2V5MQIAAAALYWRtaW5fcHViXzEAAAAAD2tleUFkbWluUHViS2V5MgIA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AQUAAAAEdGhpcwMJAAAAAAAAAgUAAAADYUlkBQAAAARFVVJOCQAEGgAAAAIFAAAAEnN0YWtpbmdFVVJOQWRkcmVzcwkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAYJXMlcyVzX19zdGFraW5nQmFsYW5jZV9fCQACWAAAAAEFAAAAA2FJZAIAAAACX18JAAQlAAAAAQUAAAAEdGhpcwAAAAAAAAAAAAMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAEVW5pdAAAAAAAAAAAAAkAAAIAAAABAgAAAAtNYXRjaCBlcnJvcgQAAAAHJG1hdGNoMAUAAAAWc3Rha2VkQW1vdW50Q2FsY3VsYXRlZAMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAADSW50BAAAAAFpBQAAAAckbWF0Y2gwBQAAAAFpAAAAAAAAAAAAAAAAAA1zdGFrZWRBbW91bnRBCQEAAAAMc3Rha2VkQW1vdW50AAAAAQUAAAAIYXNzZXRJZEEAAAAADXN0YWtlZEFtb3VudEIJAQAAAAxzdGFrZWRBbW91bnQAAAABBQAAAAhhc3NldElkQgAAAAAKYXNzZXRJbml0QQkBAAAAEUBleHRyTmF0aXZlKDEwNTApAAAAAgUAAAAEdGhpcwUAAAAPa2V5QmFsYW5jZUluaXRBAAAAAAphc3NldEluaXRCCQEAAAARQGV4dHJOYXRpdmUoMTA1MCkAAAACBQAAAAR0aGlzBQAAAA9rZXlCYWxhbmNlSW5pdEIAAAAAEWF2YWlsYWJsZUJhbGFuY2VBCQAAZQAAAAIFAAAACGJhbGFuY2VBBQAAAA1zdGFrZWRBbW91bnRBAAAAABFhdmFpbGFibGVCYWxhbmNlQgkAAGUAAAACBQAAAAhiYWxhbmNlQgUAAAANc3Rha2VkQW1vdW50QgAAAAAZYWNjb3VudEJhbGFuY2VXaXRoU3Rha2VkQQkAAGQAAAACCQEAAAAOYWNjb3VudEJhbGFuY2UAAAABBQAAAAhhc3NldElkQQUAAAANc3Rha2VkQW1vdW50QQAAAAAZYWNjb3VudEJhbGFuY2VXaXRoU3Rha2VkQgkAAGQAAAACCQEAAAAOYWNjb3VudEJhbGFuY2UAAAABBQAAAAhhc3NldElkQgUAAAANc3Rha2VkQW1vdW50QgAAAAAQaGFzRW5v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AAAMSW50ZWdlckVudHJ5AAAAAgUAAAALa2V5QmFsYW5jZUEFAAAACnBtdEFtb3VudEEJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAC2tleUJhbGFuY2VCBQAAAApwbXRBbW91bnRCCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAA1rZXlDb21taXNzaW9uBQAAAApjb21taXNzaW9uCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABtrZXlDb21taXNzaW9uU2NhbGVEZWxpbWl0ZXIFAAAAGGNvbW1pc3Npb25TY2FsZURlbGltaXRlcgkABEwAAAACBQAAAApzaGFyZUlzc3VlCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAD2tleVNoYXJlQXNzZXRJZAkAAlgAAAABBQAAAAxzaGFyZUlzc3VlSWQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAE2tleVNoYXJlQXNzZXRTdXBwbHkFAAAAEnNoYXJlSW5pdGlhbFN1cHBseQkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIFAAAAEnNoYXJlSW5pdGlhbFN1cHBseQUAAAAMc2hhcmVJc3N1ZUlkBQAAAANuaWwDBQAAAAxmaXJzdEhhcnZlc3QJAAROAAAAAgUAAAAJYmFzZUVudHJ5CQAETAAAAAIJAQAAAAxCb29sZWFuRW50cnkAAAACBQAAAA9rZXlGaXJzdEhhcnZlc3QFAAAADGZpcnN0SGFydmVzdAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAVa2V5Rmlyc3RIYXJ2ZXN0SGVpZ2h0CQAAZAAAAAIFAAAAC3N0YXJ0SGVpZ2h0CQAAaAAAAAIFAAAAFWZpcnN0SGFydmVzdEVuZFBlcmlvZAUAAAAMcGVyaW9kTGVuZ3RoBQAAAANuaWwFAAAACWJhc2VFbnRyeQAAAAFpAQAAABFpbml0V2l0aEluaXRSYXRpbwAAAAUAAAAJYW10QXNzZXRBAAAACWFtdEFzc2V0QgAAAAtzdHJBc3NldElkQQAAAAtzdHJBc3NldElkQgAAAAxmaXJzdEhhcnZlc3QEAAAADSR0MDEwNTY5MTA2NTYJAQAAABZnZXRBc3NldEluZm9Gcm9tU3RyaW5nAAAAAQUAAAALc3RyQXNzZXRJZEEEAAAADnBtdFN0ckFzc2V0SWRBCAUAAAANJHQwMTA1NjkxMDY1NgAAAAJfMQQAAAANcG10QXNzZXROYW1lQQgFAAAADSR0MDEwNTY5MTA2NTYAAAACXzIEAAAADHBtdERlY2ltYWxzQQgFAAAADSR0MDEwNTY5MTA2NTYAAAACXzMEAAAADSR0MDEwNjYxMTA3NDgJAQAAABZnZXRBc3NldEluZm9Gcm9tU3RyaW5nAAAAAQUAAAALc3RyQXNzZXRJZEIEAAAADnBtdFN0ckFzc2V0SWRCCAUAAAANJHQwMTA2NjExMDc0OAAAAAJfMQQAAAANcG10QXNzZXROYW1lQggFAAAADSR0MDEwNjYxMTA3NDgAAAACXzIEAAAADHBtdERlY2ltYWxzQggFAAAADSR0MDEwNjYxMTA3NDgAAAACXzMDCQEAAAABIQAAAAEJAQAAAA9jb250YWluc0VsZW1lbnQAAAACCQAETAAAAAIFAAAADGFkbWluUHViS2V5MQkABEwAAAACBQAAAAxhZG1pblB1YktleTIJAARMAAAAAgUAAAAMYWRtaW5QdWJLZXkzCQAETAAAAAIFAAAAEmFkbWluUHViS2V5U3Rha2luZwUAAAADbmlsCAUAAAABaQAAAA9jYWxsZXJQdWJsaWNLZXkJAAACAAAAAQIAAAAhT25seSBhZG1pbiBjYW4gY2FsbCB0aGlzIGZ1bmN0aW9uAwkBAAAACWlzRGVmaW5lZAAAAAEJAAQbAAAAAgUAAAAEdGhpcwUAAAAJa2V5QWN0aXZlCQAAAgAAAAECAAAAFkRBcHAgaXMgYWxyZWFkeSBhY3RpdmUDCQAAAAAAAAIFAAAAC3N0ckFzc2V0SWRBBQAAAAtzdHJBc3NldElkQgkAAAIAAAABAgAAABhBc3NldHMgbXVzdCBiZSBkaWZmZXJlbnQEAAAACXNoYXJlTmFtZQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAABcwkAAS8AAAACBQAAAA1wbXRBc3NldE5hbWVBAAAAAAAAAAAHAgAAAAFfCQABLwAAAAIFAAAADXBtdEFzc2V0TmFtZUIAAAAAAAAAAAcEAAAAEHNoYXJlRGVzY3JpcHRpb24JAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAACJTaGFyZVRva2VuIG9mIFN3b3BGaSBwcm90b2NvbCBmb3IgBQAAAA1wbXRBc3NldE5hbWVBAgAAAAUgYW5kIAUAAAANcG10QXNzZXROYW1lQgIAAAAMIGF0IGFkZHJlc3MgCQAEJQAAAAEFAAAABHRoaXMEAAAADXNoYXJlRGVjaW1hbHMJAABpAAAAAgkAAGQAAAACBQAAAAxwbXREZWNpbWFsc0EFAAAADHBtdERlY2ltYWxzQgAAAAAAAAAAAgQAAAASc2hhcmVJbml0aWFsU3VwcGx5AAAAAAAAAAAABAAAAApzaGFyZUlzc3VlCQAEQgAAAAUFAAAACXNoYXJlTmFtZQUAAAAQc2hhcmVEZXNjcmlwdGlvbgUAAAASc2hhcmVJbml0aWFsU3VwcGx5BQAAAA1zaGFyZURlY2ltYWxzBgQAAAAMc2hhcmVJc3N1ZUlkCQAEOAAAAAEFAAAACnNoYXJlSXNzdWUEAAAACWJhc2VFbnRyeQkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACBQAAAAprZXlWZXJzaW9uBQAAAAd2ZXJzaW9uCQAETAAAAAIJAQAAAAxCb29sZWFuRW50cnkAAAACBQAAAAlrZXlBY3RpdmUGCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAC2tleUFzc2V0SWRBBQAAAA5wbXRTdHJBc3NldElkQQkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACBQAAAAtrZXlBc3NldElkQgUAAAAOcG10U3RyQXNzZXRJZEIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAD2tleUJhbGFuY2VJbml0QQUAAAAJYW10QXNzZXRBCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAA9rZXlCYWxhbmNlSW5pdEIFAAAACWFtdEFzc2V0QgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAALa2V5QmFsYW5jZUEAAAAAAAAAAAAJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAC2tleUJhbGFuY2VCAAAAAAAAAAAACQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAA1rZXlDb21taXNzaW9uBQAAAApjb21taXNzaW9uCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABtrZXlDb21taXNzaW9uU2NhbGVEZWxpbWl0ZXIFAAAAGGNvbW1pc3Npb25TY2FsZURlbGltaXRlcgkABEwAAAACBQAAAApzaGFyZUlzc3VlCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAD2tleVNoYXJlQXNzZXRJZAkAAlgAAAABBQAAAAxzaGFyZUlzc3VlSWQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAE2tleVNoYXJlQXNzZXRTdXBwbHkFAAAAEnNoYXJlSW5pdGlhbFN1cHBseQUAAAADbmlsAwUAAAAMZmlyc3RIYXJ2ZXN0CQAETgAAAAIFAAAACWJhc2VFbnRyeQkABEwAAAACCQEAAAAMQm9vbGVhbkVudHJ5AAAAAgUAAAAPa2V5Rmlyc3RIYXJ2ZXN0BQAAAAxmaXJzdEhhcnZlc3QJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAFWtleUZpcnN0SGFydmVzdEhlaWdodAkAAGQAAAACBQAAAAtzdGFydEhlaWdodAkAAGgAAAACBQAAABVmaXJzdEhhcnZlc3RFbmRQZXJpb2QFAAAADHBlcmlvZExlbmd0aAUAAAADbmlsBQAAAAliYXNlRW50cnkAAAABaQEAAAAYa2VlcExpbWl0Rm9yRmlyc3RIYXJ2ZXN0AAAAAQAAAApzaGFyZUxpbWl0AwkBAAAAASEAAAABBQAAAAhpc0FjdGl2ZQkAAAIAAAABAgAAAB9EQXBwIGlzIGluYWN0aXZlIGF0IHRoaXMgbW9tZW50AwkBAAAAASEAAAABCQEAAAAPY29udGFpbnNFbGVtZW50AAAAAgkABEwAAAACBQAAAAxhZG1pblB1YktleTEJAARMAAAAAgUAAAAMYWRtaW5QdWJLZXkyCQAETAAAAAIFAAAADGFkbWluUHViS2V5MwkABEwAAAACBQAAABJhZG1pblB1YktleVN0YWtpbmcFAAAAA25pbAgFAAAAAWkAAAAPY2FsbGVyUHVibGljS2V5CQAAAgAAAAECAAAAIU9ubHkgYWRtaW4gY2FuIGNhbGwgdGhpcyBmdW5jdGlvbgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAALa1NoYXJlTGltaXQFAAAACnNoYXJlTGltaXQFAAAAA25pbAAAAAFpAQAAABZyZXBsZW5pc2hXaXRoVHdvVG9rZW5zAAAAAQAAABFzbGlwcGFnZVRvbGVyYW5jZQQAAAALcG10QXNzZXRJZEEICQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAAAAAAB2Fzc2V0SWQEAAAAC3BtdEFzc2V0SWRCCAkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAQAAAAdhc3NldElkBAAAAApwbXRBbW91bnRBCQEAAAAQZGVkdWN0U3Rha2luZ0ZlZQAAAAMICQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAAAAAABmFtb3VudAUAAAALcG10QXNzZXRJZEEFAAAAC3BtdEFzc2V0SWRCBAAAAApwbXRBbW91bnRCCQEAAAAQZGVkdWN0U3Rha2luZ0ZlZQAAAAMICQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAABAAAABmFtb3VudAUAAAALcG10QXNzZXRJZEIFAAAAC3BtdEFzc2V0SWRBAwMJAAAAAAAAAgUAAAAIYmFsYW5jZUEAAAAAAAAAAAAJAAAAAAAAAgUAAAAIYmFsYW5jZUIAAAAAAAAAAAAHBAAAAA0kdDAxMzQ1OTEzNTM2CQEAAAAMZ2V0QXNzZXRJbmZvAAAAAQUAAAALcG10QXNzZXRJZEEEAAAADnBtdFN0ckFzc2V0SWRBCAUAAAANJHQwMTM0NTkxMzUzNgAAAAJfMQQAAAANcG10QXNzZXROYW1lQQgFAAAADSR0MDEzNDU5MTM1MzYAAAACXzIEAAAADHBtdERlY2ltYWxzQQgFAAAADSR0MDEzNDU5MTM1MzYAAAACXzMEAAAADSR0MDEzNTQ1MTM2MjIJAQAAAAxnZXRBc3NldEluZm8AAAABBQAAAAtwbXRBc3NldElkQgQAAAAOcG10U3RyQXNzZXRJZEIIBQAAAA0kdDAxMzU0NTEzNjIyAAAAAl8xBAAAAA1wbXRBc3NldE5hbWVCCAUAAAANJHQwMTM1NDUxMzYyMgAAAAJfMgQAAAAMcG10RGVjaW1hbHNCCAUAAAANJHQwMTM1NDUxMzYyMgAAAAJfMwQAAAAKdG9rZW5SYXRpbwkAAGsAAAADCQAAawAAAAMFAAAACmFzc2V0SW5pdEEFAAAAC3NjYWxlVmFsdWU4BQAAAApwbXRBbW91bnRBBQAAAAtzY2FsZVZhbHVlMwkAAGsAAAADBQAAAAphc3NldEluaXRCBQAAAAtzY2FsZVZhbHVlOAUAAAAKcG10QW1vdW50QgMJAAAAAAAAAgUAAAALcG10QXNzZXRJZEEFAAAAC3BtdEFzc2V0SWRCCQAAAgAAAAECAAAAGEFzc2V0cyBtdXN0IGJlIGRpZmZlcmVudAQAAAANc2hhcmVEZWNpbWFscwkAAGkAAAACCQAAZAAAAAIFAAAADHBtdERlY2ltYWxzQQUAAAAMcG10RGVjaW1hbHNCAAAAAAAAAAACBAAAABJzaGFyZUluaXRpYWxTdXBwbHkJAABrAAAAAwkAAGwAAAAGBQAAAApwbXRBbW91bnRBBQAAAAxwbXREZWNpbWFsc0EAAAAAAAAAAAUAAAAAAAAAAAEFAAAADHBtdERlY2ltYWxzQQUAAAAERE9XTgkAAGwAAAAGBQAAAApwbXRBbW91bnRCBQAAAAxwbXREZWNpbWFsc0IAAAAAAAAAAAUAAAAAAAAAAAEFAAAADHBtdERlY2ltYWxzQgUAAAAERE9XTgkAAGwAAAAGAAAAAAAAAAAKAAAAAAAAAAAABQAAAA1zaGFyZURlY2ltYWxzAAAAAAAAAAAAAAAAAAAAAAAABQAAAARET1dOAwkBAAAAASEAAAABBQAAAAhpc0FjdGl2ZQkAAAIAAAABAgAAAB9EQXBwIGlzIGluYWN0aXZlIGF0IHRoaXMgbW9tZW50AwMJAABmAAAAAgAAAAAAAAAAAAUAAAARc2xpcHBhZ2VUb2xlcmFuY2UGCQAAZgAAAAIFAAAAEXNsaXBwYWdlVG9sZXJhbmNlBQAAABpzbGlwcGFnZVRvbGVyYW5jZURlbGltaXRlcgkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAAClTbGlwcGFnZSB0b2xlcmFuY2UgbXVzdCBiZSBiZXR3ZWVuIDAgYW5kIAkAAaQAAAABBQAAABpzbGlwcGFnZVRvbGVyYW5jZURlbGltaXRlcgIAAAAWIGluY2x1c2l2ZWx5LiBBY3R1YWw6IAkAAaQAAAABBQAAABFzbGlwcGFnZVRvbGVyYW5jZQMJAQAAAAIhPQAAAAIJAAGQAAAAAQgFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAIJAAACAAAAAQIAAAAcVHdvIGF0dGFjaGVkIGFzc2V0cyBleHBlY3RlZAMDCQAAZgAAAAIJAABpAAAAAgkAAGgAAAACBQAAAAtzY2FsZVZhbHVlMwkAAGUAAAACBQAAABpzbGlwcGFnZVRvbGVyYW5jZURlbGltaXRlcgUAAAARc2xpcHBhZ2VUb2xlcmFuY2UFAAAAGnNsaXBwYWdlVG9sZXJhbmNlRGVsaW1pdGVyBQAAAAp0b2tlblJhdGlvBgkAAGYAAAACBQAAAAp0b2tlblJhdGlvCQAAaQAAAAIJAABoAAAAAgUAAAALc2NhbGVWYWx1ZTMJAABkAAAAAgUAAAAac2xpcHBhZ2VUb2xlcmFuY2VEZWxpbWl0ZXIFAAAAEXNsaXBwYWdlVG9sZXJhbmNlBQAAABpzbGlwcGFnZVRvbGVyYW5jZURlbGltaXRlcgkAAAIAAAABAgAAAD1JbmNvcnJlY3QgYXNzZXRzIGFtb3VudDogYW1vdW50cyBtdXN0IGhhdmUgdGhlIGNvbnRyYWN0IHJhdGlvAwMJAQAAAAIhPQAAAAIFAAAAC3BtdEFzc2V0SWRBBQAAAAhhc3NldElkQQYJAQAAAAIhPQAAAAIFAAAAC3BtdEFzc2V0SWRCBQAAAAhhc3NldElkQgkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAACVJbmNvcnJlY3QgYXNzZXRzIGF0dGFjaGVkLiBFeHBlY3RlZDogBQAAAAtzdHJBc3NldElkQQIAAAAFIGFuZCAFAAAAC3N0ckFzc2V0SWRCAwkAAAAAAAACBQAAABJzaGFyZUluaXRpYWxTdXBwbHkAAAAAAAAAAAAJAAACAAAAAQIAAAAdVG9vIHNtYWxsIGFtb3VudCB0byByZXBsZW5pc2gDCQEAAAABIQAAAAEFAAAAEGhhc0Vub3VnaEJhbGFuY2UJAAROAAAAAgkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIFAAAACnBtdEFtb3VudEEFAAAAC3BtdEFzc2V0SWRBCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAAKcG10QW1vdW50QgUAAAALcG10QXNzZXRJZEIFAAAAA25pbAkBAAAAEXN1c3BlbmRTdXNwaWNpb3VzAAAAAAkABEwAAAACCQEAAAAHUmVpc3N1ZQAAAAMFAAAADHNoYXJlQXNzZXRJZAUAAAASc2hhcmVJbml0aWFsU3VwcGx5BgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAALa2V5QmFsYW5jZUEFAAAACnBtdEFtb3VudEEJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAC2tleUJhbGFuY2VCBQAAAApwbXRBbW91bnRCCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABNrZXlTaGFyZUFzc2V0U3VwcGx5BQAAABJzaGFyZUluaXRpYWxTdXBwbHkJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAABJzaGFyZUluaXRpYWxTdXBwbHkFAAAADHNoYXJlQXNzZXRJZAUAAAADbmlsBAAAAAp0b2tlblJhdGlvCQAAawAAAAMJAABrAAAAAwUAAAAIYmFsYW5jZUEFAAAAC3NjYWxlVmFsdWU4BQAAAApwbXRBbW91bnRBBQAAAAtzY2FsZVZhbHVlMwkAAGsAAAADBQAAAAhiYWxhbmNlQgUAAAALc2NhbGVWYWx1ZTgFAAAACnBtdEFtb3VudEIEAAAAE3JhdGlvU2hhcmVUb2tlbnNJbkEJAABrAAAAAwUAAAAKcG10QW1vdW50QQUAAAALc2NhbGVWYWx1ZTgFAAAACGJhbGFuY2VBBAAAABNyYXRpb1NoYXJlVG9rZW5zSW5CCQAAawAAAAMFAAAACnBtdEFtb3VudEIFAAAAC3NjYWxlVmFsdWU4BQAAAAhiYWxhbmNlQgQAAAAVc2hhcmVUb2tlblRvUGF5QW1vdW50CQAAawAAAAMJAAGXAAAAAQkABEwAAAACBQAAABNyYXRpb1NoYXJlVG9rZW5zSW5BCQAETAAAAAIFAAAAE3JhdGlvU2hhcmVUb2tlbnNJbkIFAAAAA25pbAUAAAAQc2hhcmVBc3NldFN1cHBseQUAAAALc2NhbGVWYWx1ZTgDCQEAAAABIQAAAAEFAAAACGlzQWN0aXZlCQAAAgAAAAECAAAAH0RBcHAgaXMgaW5hY3RpdmUgYXQgdGhpcyBtb21lbnQDAwkAAGYAAAACAAAAAAAAAAAABQAAABFzbGlwcGFnZVRvbGVyYW5jZQYJAABmAAAAAgUAAAARc2xpcHBhZ2VUb2xlcmFuY2UFAAAAGnNsaXBwYWdlVG9sZXJhbmNlRGVsaW1pdGVyCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAKVNsaXBwYWdlIHRvbGVyYW5jZSBtdXN0IGJlIGJldHdlZW4gMCBhbmQgCQABpAAAAAEFAAAAGnNsaXBwYWdlVG9sZXJhbmNlRGVsaW1pdGVyAgAAABYgaW5jbHVzaXZlbHkuIEFjdHVhbDogCQABpAAAAAEFAAAAEXNsaXBwYWdlVG9sZXJhbmNlAwkBAAAAAiE9AAAAAgkAAZAAAAABCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAgkAAAIAAAABAgAAABxUd28gYXR0YWNoZWQgYXNzZXRzIGV4cGVjdGVkAwMJAQAAAAIhPQAAAAIFAAAAC3BtdEFzc2V0SWRBBQAAAAhhc3NldElkQQYJAQAAAAIhPQAAAAIFAAAAC3BtdEFzc2V0SWRCBQAAAAhhc3NldElkQgkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAACVJbmNvcnJlY3QgYXNzZXRzIGF0dGFjaGVkLiBFeHBlY3RlZDogBQAAAAtzdHJBc3NldElkQQIAAAAFIGFuZCAFAAAAC3N0ckFzc2V0SWRCAwMJAABmAAAAAgkAAGkAAAACCQAAaAAAAAIFAAAAC3NjYWxlVmFsdWUzCQAAZQAAAAIFAAAAGnNsaXBwYWdlVG9sZXJhbmNlRGVsaW1pdGVyBQAAABFzbGlwcGFnZVRvbGVyYW5jZQUAAAAac2xpcHBhZ2VUb2xlcmFuY2VEZWxpbWl0ZXIFAAAACnRva2VuUmF0aW8GCQAAZgAAAAIFAAAACnRva2VuUmF0aW8JAABpAAAAAgkAAGgAAAACBQAAAAtzY2FsZVZhbHVlMwkAAGQAAAACBQAAABpzbGlwcGFnZVRvbGVyYW5jZURlbGltaXRlcgUAAAARc2xpcHBhZ2VUb2xlcmFuY2UFAAAAGnNsaXBwYWdlVG9sZXJhbmNlRGVsaW1pdGVyCQAAAgAAAAECAAAAPUluY29ycmVjdCBhc3NldHMgYW1vdW50OiBhbW91bnRzIG11c3QgaGF2ZSB0aGUgY29udHJhY3QgcmF0aW8DCQAAAAAAAAIFAAAAFXNoYXJlVG9rZW5Ub1BheUFtb3VudAAAAAAAAAAAAAkAAAIAAAABAgAAAB1Ub28gc21hbGwgYW1vdW50IHRvIHJlcGxlbmlzaAMJAQAAAAEhAAAAAQUAAAAQaGFzRW5vdWdoQmFsYW5jZQkABE4AAAACCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAAKcG10QW1vdW50QQUAAAALcG10QXNzZXRJZEEJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAAApwbXRBbW91bnRCBQAAAAtwbXRBc3NldElkQgUAAAADbmlsCQEAAAARc3VzcGVuZFN1c3BpY2lvdXMAAAAACQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAtrZXlCYWxhbmNlQQkAAGQAAAACBQAAAAhiYWxhbmNlQQUAAAAKcG10QW1vdW50QQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAALa2V5QmFsYW5jZUIJAABkAAAAAgUAAAAIYmFsYW5jZUIFAAAACnBtdEFtb3VudEIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAE2tleVNoYXJlQXNzZXRTdXBwbHkJAABkAAAAAgUAAAAQc2hhcmVBc3NldFN1cHBseQUAAAAVc2hhcmVUb2tlblRvUGF5QW1vdW50CQAETAAAAAIJAQAAAAdSZWlzc3VlAAAAAwUAAAAMc2hhcmVBc3NldElkBQAAABVzaGFyZVRva2VuVG9QYXlBbW91bnQGCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAAVc2hhcmVUb2tlblRvUGF5QW1vdW50BQAAAAxzaGFyZUFzc2V0SWQFAAAAA25pbAAAAAFpAQAAAAh3aXRoZHJhdwAAAAAEAAAADSR0MDE4MDIxMTgxNzEJAAUUAAAAAggJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAAAAAGYW1vdW50CAkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAdhc3NldElkBAAAAAlwbXRBbW91bnQIBQAAAA0kdDAxODAyMTE4MTcxAAAAAl8xBAAAAApwbXRBc3NldElkCAUAAAANJHQwMTgwMjExODE3MQAAAAJfMgQAAAAMYW1vdW50VG9QYXlBCQEAAAAQZGVkdWN0U3Rha2luZ0ZlZQAAAAMJAABrAAAAAwUAAAAJcG10QW1vdW50BQAAAAhiYWxhbmNlQQUAAAAQc2hhcmVBc3NldFN1cHBseQUAAAAIYXNzZXRJZEEFAAAACGFzc2V0SWRCBAAAAAxhbW91bnRUb1BheUIJAQAAABBkZWR1Y3RTdGFraW5nRmVlAAAAAwkAAGsAAAADBQAAAAlwbXRBbW91bnQFAAAACGJhbGFuY2VCBQAAABBzaGFyZUFzc2V0U3VwcGx5BQAAAAhhc3NldElkQgUAAAAIYXNzZXRJZEEDCQEAAAABIQAAAAEFAAAACGlzQWN0aXZlCQAAAgAAAAECAAAAH0RBcHAgaXMgaW5hY3RpdmUgYXQgdGhpcyBtb21lbnQDCQEAAAACIT0AAAACCQABkAAAAAEIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAABCQAAAgAAAAECAAAAHU9uZSBhdHRhY2hlZCBwYXltZW50IGV4cGVjdGVkAwkBAAAAAiE9AAAAAgUAAAAKcG10QXNzZXRJZAUAAAAMc2hhcmVBc3NldElkCQAAAgAAAAEJAAEsAAAAAgIAAAAkSW5jb3JyZWN0IGFzc2V0IGF0dGFjaGVkLiBFeHBlY3RlZDogCQACWAAAAAEFAAAADHNoYXJlQXNzZXRJZAMJAQAAAAEhAAAAAQUAAAAQaGFzRW5vdWdoQmFsYW5jZQkABE4AAAACCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAAJcG10QW1vdW50BQAAAApwbXRBc3NldElkBQAAAANuaWwJAQAAABFzdXNwZW5kU3VzcGljaW91cwAAAAADAwkAAGYAAAACBQAAAAxhbW91bnRUb1BheUEFAAAAEWF2YWlsYWJsZUJhbGFuY2VBBgkAAGYAAAACBQAAAAxhbW91bnRUb1BheUIFAAAAEWF2YWlsYWJsZUJhbGFuY2VCCQEAAAAidGhyb3dJbnN1ZmZpY2llbnRBdmFpbGFibGVCYWxhbmNlcwAAAAIFAAAADGFtb3VudFRvUGF5QQUAAAAMYW1vdW50VG9QYXlCCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAtrZXlCYWxhbmNlQQkAAGUAAAACBQAAAAhiYWxhbmNlQQUAAAAMYW1vdW50VG9QYXlBCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAtrZXlCYWxhbmNlQgkAAGUAAAACBQAAAAhiYWxhbmNlQgUAAAAMYW1vdW50VG9QYXlCCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABNrZXlTaGFyZUFzc2V0U3VwcGx5CQAAZQAAAAIFAAAAEHNoYXJlQXNzZXRTdXBwbHkFAAAACXBtdEFtb3VudAkABEwAAAACCQEAAAAEQnVybgAAAAIFAAAADHNoYXJlQXNzZXRJZAUAAAAJcG10QW1vdW50CQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAAMYW1vdW50VG9QYXlBBQAAAAhhc3NldElkQQkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIFAAAADGFtb3VudFRvUGF5QgUAAAAIYXNzZXRJZEIFAAAAA25pbAAAAAFpAQAAAAhleGNoYW5nZQAAAAEAAAASbWluQW1vdW50VG9SZWNlaXZlBAAAAA0kdDAxOTM5NzE5NDcyCQAFFAAAAAIICQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAAAAAABmFtb3VudAgJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAAAAAHYXNzZXRJZAQAAAAJcG10QW1vdW50CAUAAAANJHQwMTkzOTcxOTQ3MgAAAAJfMQQAAAAKcG10QXNzZXRJZAgFAAAADSR0MDE5Mzk3MTk0NzIAAAACXzIKAQAAAA1jYWxjdWxhdGVGZWVzAAAAAgAAAAl0b2tlbkZyb20AAAAHdG9rZW5UbwQAAAAQYW1vdW50V2l0aG91dEZlZQkAAGsAAAADBQAAAAd0b2tlblRvBQAAAAlwbXRBbW91bnQJAABkAAAAAgUAAAAJcG10QW1vdW50BQAAAAl0b2tlbkZyb20EAAAADWFtb3VudFdpdGhGZWUJAABrAAAAAwUAAAAQYW1vdW50V2l0aG91dEZlZQkAAGUAAAACBQAAABhjb21taXNzaW9uU2NhbGVEZWxpbWl0ZXIFAAAACmNvbW1pc3Npb24FAAAAGGNvbW1pc3Npb25TY2FsZURlbGltaXRlcgQAAAAQZ292ZXJuYW5jZVJld2FyZAkAAGsAAAADBQAAABBhbW91bnRXaXRob3V0RmVlBQAAABRjb21taXNzaW9uR292ZXJuYW5jZQUAAAAYY29tbWlzc2lvblNjYWxlRGVsaW1pdGVyAwkAAGYAAAACBQAAABJtaW5BbW91bnRUb1JlY2VpdmUFAAAADWFtb3VudFdpdGhGZWUJAAACAAAAAQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAdQ2FsY3VsYXRlZCBhbW91bnQgdG8gcmVjZWl2ZSAJAAGkAAAAAQUAAAANYW1vdW50V2l0aEZlZQIAAAAgIGlzIGxlc3MgdGhhbiBzcGVjaWZpZWQgbWluaW11bSAJAAGkAAAAAQUAAAASbWluQW1vdW50VG9SZWNlaXZlCQAFFQAAAAMFAAAAEGFtb3VudFdpdGhvdXRGZWUFAAAADWFtb3VudFdpdGhGZWUFAAAAEGdvdmVybmFuY2VSZXdhcmQDCQEAAAABIQAAAAEFAAAACGlzQWN0aXZlCQAAAgAAAAECAAAAH0RBcHAgaXMgaW5hY3RpdmUgYXQgdGhpcyBtb21lbnQDAwkAAAAAAAACBQAAAAhiYWxhbmNlQQAAAAAAAAAAAAYJAAAAAAAAAgUAAAAIYmFsYW5jZUIAAAAAAAAAAAAJAAACAAAAAQIAAAAgQ2FuJ3QgZXhjaGFuZ2Ugd2l0aCB6ZXJvIGJhbGFuY2UDCQAAZwAAAAIAAAAAAAAAAAAFAAAAEm1pbkFtb3VudFRvUmVjZWl2ZQkAAAIAAAABCQABLAAAAAICAAAANE1pbmltYWwgYW1vdW50IHRvIHJlY2VpdmUgbXVzdCBiZSBwb3NpdGl2ZS4gQWN0dWFsOiAJAAGkAAAAAQUAAAASbWluQW1vdW50VG9SZWNlaXZlAwkBAAAAAiE9AAAAAgkAAZAAAAABCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAQkAAAIAAAABAgAAAB1PbmUgYXR0YWNoZWQgcGF5bWVudCBleHBlY3RlZAMJAQAAAAEhAAAAAQUAAAAQaGFzRW5vdWdoQmFsYW5jZQkABE4AAAACCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAAJcG10QW1vdW50BQAAAApwbXRBc3NldElkBQAAAANuaWwJAQAAABFzdXNwZW5kU3VzcGljaW91cwAAAAADCQAAAAAAAAIFAAAACnBtdEFzc2V0SWQFAAAACGFzc2V0SWRBBAAAAAthc3NldElkU2VuZAUAAAAIYXNzZXRJZEIEAAAADSR0MDIwNzQ2MjA4MzcJAQAAAA1jYWxjdWxhdGVGZWVzAAAAAgUAAAAIYmFsYW5jZUEFAAAACGJhbGFuY2VCBAAAABBhbW91bnRXaXRob3V0RmVlCAUAAAANJHQwMjA3NDYyMDgzNwAAAAJfMQQAAAANYW1vdW50V2l0aEZlZQgFAAAADSR0MDIwNzQ2MjA4MzcAAAACXzIEAAAAEGdvdmVybmFuY2VSZXdhcmQIBQAAAA0kdDAyMDc0NjIwODM3AAAAAl8zBAAAAAtuZXdCYWxhbmNlQQkAAGQAAAACBQAAAAhiYWxhbmNlQQUAAAAJcG10QW1vdW50BAAAAAtuZXdCYWxhbmNlQgkAAGUAAAACCQAAZQAAAAIFAAAACGJhbGFuY2VCBQAAAA1hbW91bnRXaXRoRmVlBQAAABBnb3Zlcm5hbmNlUmV3YXJkAwMJAABnAAAAAgUAAAANc3Rha2VkQW1vdW50QQUAAAALbmV3QmFsYW5jZUEGCQAAZwAAAAIFAAAADXN0YWtlZEFtb3VudEIFAAAAC25ld0JhbGFuY2VCCQEAAAAhdGhyb3dJbnN1ZmZpY2llbnRBdmFpbGFibGVCYWxhbmNlAAAAAwUAAAANYW1vdW50V2l0aEZlZQUAAAARYXZhaWxhYmxlQmFsYW5jZUIFAAAACmFzc2V0TmFtZUIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAC2tleUJhbGFuY2VBBQAAAAtuZXdCYWxhbmNlQQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAALa2V5QmFsYW5jZUIFAAAAC25ld0JhbGFuY2VCCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAANYW1vdW50V2l0aEZlZQUAAAALYXNzZXRJZFNlbmQJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwUAAAANd2FsbGV0QWRkcmVzcwUAAAAQZ292ZXJuYW5jZVJld2FyZAUAAAALYXNzZXRJZFNlbmQFAAAAA25pbAMJAAAAAAAAAgUAAAAKcG10QXNzZXRJZAUAAAAIYXNzZXRJZEIEAAAAC2Fzc2V0SWRTZW5kBQAAAAhhc3NldElkQQQAAAANJHQwMjE2NTYyMTc0NwkBAAAADWNhbGN1bGF0ZUZlZXMAAAACBQAAAAhiYWxhbmNlQgUAAAAIYmFsYW5jZUEEAAAAEGFtb3VudFdpdGhvdXRGZWUIBQAAAA0kdDAyMTY1NjIxNzQ3AAAAAl8xBAAAAA1hbW91bnRXaXRoRmVlCAUAAAANJHQwMjE2NTYyMTc0NwAAAAJfMgQAAAAQZ292ZXJuYW5jZVJld2FyZAgFAAAADSR0MDIxNjU2MjE3NDcAAAACXzMEAAAAC25ld0JhbGFuY2VBCQAAZQAAAAIJAABlAAAAAgUAAAAIYmFsYW5jZUEFAAAADWFtb3VudFdpdGhGZWUFAAAAEGdvdmVybmFuY2VSZXdhcmQEAAAAC25ld0JhbGFuY2VCCQAAZAAAAAIFAAAACGJhbGFuY2VCBQAAAAlwbXRBbW91bnQDAwkAAGcAAAACBQAAAA1zdGFrZWRBbW91bnRBBQAAAAtuZXdCYWxhbmNlQQYJAABnAAAAAgUAAAANc3Rha2VkQW1vdW50QgUAAAALbmV3QmFsYW5jZUIJAQAAACF0aHJvd0luc3VmZmljaWVudEF2YWlsYWJsZUJhbGFuY2UAAAADBQAAAA1hbW91bnRXaXRoRmVlBQAAABFhdmFpbGFibGVCYWxhbmNlQQUAAAAKYXNzZXROYW1lQQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAALa2V5QmFsYW5jZUEFAAAAC25ld0JhbGFuY2VBCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAtrZXlCYWxhbmNlQgUAAAALbmV3QmFsYW5jZUIJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAAA1hbW91bnRXaXRoRmVlBQAAAAthc3NldElkU2VuZAkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADBQAAAA13YWxsZXRBZGRyZXNzBQAAABBnb3Zlcm5hbmNlUmV3YXJkBQAAAAthc3NldElkU2VuZAUAAAADbmlsCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAJEluY29ycmVjdCBhc3NldCBhdHRhY2hlZC4gRXhwZWN0ZWQ6IAUAAAALc3RyQXNzZXRJZEECAAAABCBvciAFAAAAC3N0ckFzc2V0SWRCAAAAAWkBAAAACHNodXRkb3duAAAAAAMJAQAAAAEhAAAAAQUAAAAIaXNBY3RpdmUJAAACAAAAAQkAASwAAAACAgAAACJEQXBwIGlzIGFscmVhZHkgc3VzcGVuZGVkLiBDYXVzZTogCQEAAAALdmFsdWVPckVsc2UAAAACCQAEHQAAAAIFAAAABHRoaXMFAAAACGtleUNhdXNlAgAAABp0aGUgY2F1c2Ugd2Fzbid0IHNwZWNpZmllZAMJAQAAAAEhAAAAAQkBAAAAD2NvbnRhaW5zRWxlbWVudAAAAAIJAARMAAAAAgUAAAAMYWRtaW5QdWJLZXkxCQAETAAAAAIFAAAADGFkbWluUHViS2V5MgkABEwAAAACBQAAAAxhZG1pblB1YktleTMJAARMAAAAAgUAAAAUYWRtaW5QdWJLZXlTdGFydFN0b3AFAAAAA25pbAgFAAAAAWkAAAAPY2FsbGVyUHVibGljS2V5CQAAAgAAAAECAAAAIU9ubHkgYWRtaW4gY2FuIGNhbGwgdGhpcyBmdW5jdGlvbgkBAAAAB3N1c3BlbmQAAAABAgAAAA9QYXVzZWQgYnkgYWRtaW4AAAABaQEAAAAIYWN0aXZhdGUAAAAAAwUAAAAIaXNBY3RpdmUJAAACAAAAAQIAAAAWREFwcCBpcyBhbHJlYWR5IGFjdGl2ZQMJAQAAAAEhAAAAAQkBAAAAD2NvbnRhaW5zRWxlbWVudAAAAAIJAARMAAAAAgUAAAAMYWRtaW5QdWJLZXkxCQAETAAAAAIFAAAADGFkbWluUHViS2V5MgkABEwAAAACBQAAAAxhZG1pblB1YktleTMJAARMAAAAAgUAAAAUYWRtaW5QdWJLZXlTdGFydFN0b3AFAAAAA25pbAgFAAAAAWkAAAAPY2FsbGVyUHVibGljS2V5CQAAAgAAAAECAAAAIU9ubHkgYWRtaW4gY2FuIGNhbGwgdGhpcyBmdW5jdGlvbgkABEwAAAACCQEAAAAMQm9vbGVhbkVudHJ5AAAAAgUAAAAJa2V5QWN0aXZlBgkABEwAAAACCQEAAAALRGVsZXRlRW50cnkAAAABBQAAAAhrZXlDYXVzZQUAAAADbmlsAAAAAWkBAAAAGXRha2VJbnRvQWNjb3VudEV4dHJhRnVuZHMAAAABAAAAC2Ftb3VudExlYXZlBAAAAB11bmNvdW50YWJsZUFtb3VudEVucm9sbEFzc2V0QQkAAGUAAAACBQAAABlhY2NvdW50QmFsYW5jZVdpdGhTdGFrZWRBBQAAAAhiYWxhbmNlQQQAAAAddW5jb3VudGFibGVBbW91bnRFbnJvbGxBc3NldEIJAABlAAAAAgUAAAAZYWNjb3VudEJhbGFuY2VXaXRoU3Rha2VkQgUAAAAIYmFsYW5jZUIEAAAADWFtb3VudEVucm9sbEEJAABlAAAAAgUAAAAddW5jb3VudGFibGVBbW91bnRFbnJvbGxBc3NldEEDCQAAAAAAAAIFAAAACGFzc2V0SWRBBQAAAAR1bml0BQAAAAthbW91bnRMZWF2ZQAAAAAAAAAAAAQAAAANYW1vdW50RW5yb2xsQgkAAGUAAAACBQAAAB11bmNvdW50YWJsZUFtb3VudEVucm9sbEFzc2V0QgMJAAAAAAAAAgUAAAAIYXNzZXRJZEIFAAAABHVuaXQFAAAAC2Ftb3VudExlYXZlAAAAAAAAAAAAAwkBAAAAASEAAAABBQAAAAhpc0FjdGl2ZQkAAAIA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", "height": 1633559, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 2D7fadJmPTPzQ84crsgEEFX1AVQsCbXhE6TiWpVpt5Qr Next: 2he85K197PvpzabRUq6iYpSV5KUjCiKfTsR4eBPBW8pK Diff:
OldNewDifferences
1515
1616 let keyBalanceB = "B_asset_balance"
1717
18+let keyBalanceInitA = "A_asset_init"
19+
20+let keyBalanceInitB = "B_asset_init"
21+
1822 let keyShareAssetId = "share_asset_id"
1923
2024 let keyShareAssetSupply = "share_asset_supply"
2428 let keyCommissionScaleDelimiter = "commission_scale_delimiter"
2529
2630 let keyCause = "shutdown_cause"
31+
32+let keyFirstHarvest = "first_harvest"
33+
34+let keyFirstHarvestHeight = "first_harvest_height"
35+
36+let kShareLimit = "share_limit_on_first_harvest"
37+
38+let kBasePeriod = "base_period"
39+
40+let kPeriodLength = "period_length"
41+
42+let kStartHeight = "start_height"
43+
44+let kFirstHarvestHeight = "first_harvest_height"
2745
2846 let keyAdminPubKey1 = "admin_pub_1"
2947
5169
5270 let adminPubKeyStaking = base58'Kn7NpzaG12dLZgcHf2ipUftU6hbJygmrhFqQYE4B7ZK'
5371
54-let governanceAddress = Address(base58'3NAGTtZz6WpupSN89NZD5rMZwwziZEg4Kx4')
72+let walletAddress = Address(base58'3NAGTtZz6WpupSN89NZD5rMZwwziZEg4Kx4')
5573
56-let stakingAddressUSDN = Address(base58'3N6q7sCGSSLBUXDdjBdYGTJbZGZfhhh8cNg')
74+let votingAddress = Address(base58'3MrJgdL1GniipErHy44YF9idzLaUL2iX5DQ')
5775
5876 let USDN = base58'8UrfDVd5GreeUwm7uPk7eYz1eMv376kzR52C6sANPkwS'
5977
6179
6280 let SWOP = base58'2HAJrwa8q4SxBx9cHYaBTQdBjdk5wwqdof7ccpAx2uhZ'
6381
64-let swopUSDNtoWAVES = Address(base58'3N77kfPbQyjXWpDALX3xjKw3iEGMWEctV37')
82+let EURN = base58'ECBCkHS68DckpBrzLeoRgYbFg7sCVqR176mPqbXsj9pA'
6583
66-let swopUSDNtoNSBT = Address(base58'3MzTHd4e3yukNUURApVLVzH5uxeEsXHD6yY')
84+let stakingUSDNNSBTAddress = Address(base58'3N1qKnD3EoFpmFphWeZgmFjAUPXJmGw9cUp')
85+
86+let stakingEURNAddress = Address(base58'3MyVqAbmKWh339gF6hy8faWw1jGeTV2wnGE')
87+
88+let USDNToWavesExchanger = Address(base58'3N77kfPbQyjXWpDALX3xjKw3iEGMWEctV37')
89+
90+let USDNToNSBTExchanger = Address(base58'3MzTHd4e3yukNUURApVLVzH5uxeEsXHD6yY')
6791
6892 let stakingFeeInUSDN = 270000
93+
94+let stakingFeeInEURN = 234000
95+
96+let basePeriod = valueOrErrorMessage(getInteger(votingAddress, kBasePeriod), "Empty kBasePeriod")
97+
98+let startHeight = valueOrErrorMessage(getInteger(votingAddress, kStartHeight), "Empty kStartHeight")
99+
100+let periodLength = valueOrErrorMessage(getInteger(votingAddress, kPeriodLength), "Empty kPeriodLength")
101+
102+let firstHarvestEndPeriod = ((basePeriod + ((height - startHeight) / periodLength)) + 3)
69103
70104 let isActive = getBooleanValue(this, keyActive)
71105
131165 }
132166
133167
134-func stakedAmount (stakingAddress,asset) = {
135- let stakedAmountCalculated = match getInteger(stakingAddress, ((("rpd_balance_" + asset) + "_") + toString(this))) {
136- case staked: Int =>
137- staked
138- case nothing: Unit =>
168+func stakedAmount (assetId) = {
169+ let stakedAmountCalculated = match assetId {
170+ case aId: ByteVector =>
171+ if (if ((aId == USDN))
172+ then true
173+ else (aId == NSBT))
174+ then getInteger(stakingUSDNNSBTAddress, ((("rpd_balance_" + toBase58String(aId)) + "_") + toString(this)))
175+ else if ((aId == EURN))
176+ then getInteger(stakingEURNAddress, ((("%s%s%s__stakingBalance__" + toBase58String(aId)) + "__") + toString(this)))
177+ else 0
178+ case _: Unit =>
139179 0
140180 case _ =>
141181 throw("Match error")
142182 }
143- stakedAmountCalculated
183+ match stakedAmountCalculated {
184+ case i: Int =>
185+ i
186+ case _ =>
187+ 0
188+ }
144189 }
145190
146191
147-let stakedAmountA = stakedAmount(stakingAddressUSDN, strAssetIdA)
192+let stakedAmountA = stakedAmount(assetIdA)
148193
149-let stakedAmountB = stakedAmount(stakingAddressUSDN, strAssetIdB)
194+let stakedAmountB = stakedAmount(assetIdB)
195+
196+let assetInitA = getIntegerValue(this, keyBalanceInitA)
197+
198+let assetInitB = getIntegerValue(this, keyBalanceInitB)
150199
151200 let availableBalanceA = (balanceA - stakedAmountA)
152201
172221 }
173222
174223
224+func getAssetInfoFromString (assetStr) = if ((assetStr == "WAVES"))
225+ then $Tuple3("WAVES", "WAVES", 8)
226+ else {
227+ let stringId = assetStr
228+ let id = fromBase58String(assetStr)
229+ let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
230+ $Tuple3(stringId, info.name, info.decimals)
231+ }
232+
233+
175234 func suspend (cause) = [BooleanEntry(keyActive, false), StringEntry(keyCause, cause)]
176235
177236
178-func stakedTokenCount () = {
179- let isStakedA = if ((stakedAmountA > 0))
180- then 1
181- else 0
182- let isStakedB = if ((stakedAmountB > 0))
183- then 1
184- else 0
185- (isStakedA + isStakedB)
186- }
187-
188-
189-func deductStakingFee (amount,assetId) = if ((assetId == USDN))
237+func deductStakingFee (amount,assetId,secondAssetId) = if (if ((assetId == USDN))
238+ then true
239+ else (assetId == EURN))
190240 then {
191- let result = (amount - (stakedTokenCount() * stakingFeeInUSDN))
241+ let stakinFee = if ((assetId == USDN))
242+ then (stakingFeeInUSDN * (if ((secondAssetId == NSBT))
243+ then 2
244+ else 1))
245+ else if ((assetId == EURN))
246+ then stakingFeeInEURN
247+ else 0
248+ let result = (amount - stakinFee)
192249 if ((0 >= result))
193- then throw((((("Insufficient amount " + toString(amount)) + " to deduct staking fee ") + toString(stakingFeeInUSDN)) + " USD-N"))
250+ then throw((((("Insufficient amount " + toString(amount)) + " to deduct staking fee ") + toString(stakinFee)) + "USDN/EURN"))
194251 else result
195252 }
196253 else amount
254+
255+
256+func getStakingFee (assetId,secondAssetId) = if ((assetId == USDN))
257+ then (stakingFeeInUSDN * (if ((secondAssetId == NSBT))
258+ then 2
259+ else 1))
260+ else if ((assetId == EURN))
261+ then stakingFeeInEURN
262+ else 0
197263
198264
199265 func throwInsufficientAvailableBalance (amount,available,assetName) = throw((((((((("Insufficient DApp balance to pay " + toString(amount)) + " ") + assetName) + " due to staking. Available: ") + toString(available)) + " ") + assetName) + ". Please contact support in Telegram: https://t.me/swopfisupport"))
206272
207273
208274 @Callable(i)
209-func init () = {
210- let $t059366013 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
211- let pmtAmountA = $t059366013._1
212- let pmtAssetIdA = $t059366013._2
213- let $t060186095 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
214- let pmtAmountB = $t060186095._1
215- let pmtAssetIdB = $t060186095._2
216- let $t061006177 = getAssetInfo(pmtAssetIdA)
217- let pmtStrAssetIdA = $t061006177._1
218- let pmtAssetNameA = $t061006177._2
219- let pmtDecimalsA = $t061006177._3
220- let $t061826259 = getAssetInfo(pmtAssetIdB)
221- let pmtStrAssetIdB = $t061826259._1
222- let pmtAssetNameB = $t061826259._2
223- let pmtDecimalsB = $t061826259._3
224- if (isDefined(getBoolean(this, keyActive)))
225- then throw("DApp is already active")
226- else if ((pmtAssetIdA == pmtAssetIdB))
227- then throw("Assets must be different")
228- else {
229- let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
230- let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
231- let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
232- let shareInitialSupply = fraction(pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN), pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN), pow(10, 0, shareDecimals, 0, 0, DOWN))
233- let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
234- let shareIssueId = calculateAssetId(shareIssue)
235-[StringEntry(keyVersion, version), BooleanEntry(keyActive, true), StringEntry(keyAssetIdA, pmtStrAssetIdA), StringEntry(keyAssetIdB, pmtStrAssetIdB), IntegerEntry(keyBalanceA, pmtAmountA), IntegerEntry(keyBalanceB, pmtAmountB), IntegerEntry(keyCommission, commission), IntegerEntry(keyCommissionScaleDelimiter, commissionScaleDelimiter), shareIssue, StringEntry(keyShareAssetId, toBase58String(shareIssueId)), IntegerEntry(keyShareAssetSupply, shareInitialSupply), ScriptTransfer(i.caller, shareInitialSupply, shareIssueId)]
236- }
275+func init (firstHarvest) = {
276+ let $t080018078 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
277+ let pmtAmountA = $t080018078._1
278+ let pmtAssetIdA = $t080018078._2
279+ let $t080838160 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
280+ let pmtAmountB = $t080838160._1
281+ let pmtAssetIdB = $t080838160._2
282+ let $t081658242 = getAssetInfo(pmtAssetIdA)
283+ let pmtStrAssetIdA = $t081658242._1
284+ let pmtAssetNameA = $t081658242._2
285+ let pmtDecimalsA = $t081658242._3
286+ let $t082478324 = getAssetInfo(pmtAssetIdB)
287+ let pmtStrAssetIdB = $t082478324._1
288+ let pmtAssetNameB = $t082478324._2
289+ let pmtDecimalsB = $t082478324._3
290+ if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey)))
291+ then throw("Only admin can call this function")
292+ else if (isDefined(getBoolean(this, keyActive)))
293+ then throw("DApp is already active")
294+ else if ((pmtAssetIdA == pmtAssetIdB))
295+ then throw("Assets must be different")
296+ else {
297+ let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
298+ let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
299+ let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
300+ let arg1 = pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN)
301+ let arg2 = pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN)
302+ let arg3 = pow(10, 0, shareDecimals, 0, 0, DOWN)
303+ let shareInitialSupply = fraction(arg1, arg2, arg3)
304+ let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
305+ let shareIssueId = calculateAssetId(shareIssue)
306+ let baseEntry = [StringEntry(keyVersion, version), BooleanEntry(keyActive, true), StringEntry(keyAssetIdA, pmtStrAssetIdA), StringEntry(keyAssetIdB, pmtStrAssetIdB), IntegerEntry(keyBalanceA, pmtAmountA), IntegerEntry(keyBalanceB, pmtAmountB), IntegerEntry(keyCommission, commission), IntegerEntry(keyCommissionScaleDelimiter, commissionScaleDelimiter), shareIssue, StringEntry(keyShareAssetId, toBase58String(shareIssueId)), IntegerEntry(keyShareAssetSupply, shareInitialSupply), ScriptTransfer(i.caller, shareInitialSupply, shareIssueId)]
307+ if (firstHarvest)
308+ then (baseEntry ++ [BooleanEntry(keyFirstHarvest, firstHarvest), IntegerEntry(keyFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))])
309+ else baseEntry
310+ }
237311 }
312+
313+
314+
315+@Callable(i)
316+func initWithInitRatio (amtAssetA,amtAssetB,strAssetIdA,strAssetIdB,firstHarvest) = {
317+ let $t01056910656 = getAssetInfoFromString(strAssetIdA)
318+ let pmtStrAssetIdA = $t01056910656._1
319+ let pmtAssetNameA = $t01056910656._2
320+ let pmtDecimalsA = $t01056910656._3
321+ let $t01066110748 = getAssetInfoFromString(strAssetIdB)
322+ let pmtStrAssetIdB = $t01066110748._1
323+ let pmtAssetNameB = $t01066110748._2
324+ let pmtDecimalsB = $t01066110748._3
325+ if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey)))
326+ then throw("Only admin can call this function")
327+ else if (isDefined(getBoolean(this, keyActive)))
328+ then throw("DApp is already active")
329+ else if ((strAssetIdA == strAssetIdB))
330+ then throw("Assets must be different")
331+ else {
332+ let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
333+ let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
334+ let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
335+ let shareInitialSupply = 0
336+ let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
337+ let shareIssueId = calculateAssetId(shareIssue)
338+ let baseEntry = [StringEntry(keyVersion, version), BooleanEntry(keyActive, true), StringEntry(keyAssetIdA, pmtStrAssetIdA), StringEntry(keyAssetIdB, pmtStrAssetIdB), IntegerEntry(keyBalanceInitA, amtAssetA), IntegerEntry(keyBalanceInitB, amtAssetB), IntegerEntry(keyBalanceA, 0), IntegerEntry(keyBalanceB, 0), IntegerEntry(keyCommission, commission), IntegerEntry(keyCommissionScaleDelimiter, commissionScaleDelimiter), shareIssue, StringEntry(keyShareAssetId, toBase58String(shareIssueId)), IntegerEntry(keyShareAssetSupply, shareInitialSupply)]
339+ if (firstHarvest)
340+ then (baseEntry ++ [BooleanEntry(keyFirstHarvest, firstHarvest), IntegerEntry(keyFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))])
341+ else baseEntry
342+ }
343+ }
344+
345+
346+
347+@Callable(i)
348+func keepLimitForFirstHarvest (shareLimit) = if (!(isActive))
349+ then throw("DApp is inactive at this moment")
350+ else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey)))
351+ then throw("Only admin can call this function")
352+ else [IntegerEntry(kShareLimit, shareLimit)]
238353
239354
240355
242357 func replenishWithTwoTokens (slippageTolerance) = {
243358 let pmtAssetIdA = i.payments[0].assetId
244359 let pmtAssetIdB = i.payments[1].assetId
245- let pmtAmountA = deductStakingFee(i.payments[0].amount, pmtAssetIdA)
246- let pmtAmountB = deductStakingFee(i.payments[1].amount, pmtAssetIdB)
247- let tokenRatio = fraction(fraction(balanceA, scaleValue8, pmtAmountA), scaleValue3, fraction(balanceB, scaleValue8, pmtAmountB))
248- let ratioShareTokensInA = fraction(pmtAmountA, scaleValue8, balanceA)
249- let ratioShareTokensInB = fraction(pmtAmountB, scaleValue8, balanceB)
250- let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scaleValue8)
251- if (!(isActive))
252- then throw("DApp is inactive at this moment")
253- else if (if ((0 > slippageTolerance))
254- then true
255- else (slippageTolerance > slippageToleranceDelimiter))
256- then throw(((("Slippage tolerance must be between 0 and " + toString(slippageToleranceDelimiter)) + " inclusively. Actual: ") + toString(slippageTolerance)))
257- else if ((size(i.payments) != 2))
258- then throw("Two attached assets expected")
259- else if (if ((pmtAssetIdA != assetIdA))
360+ let pmtAmountA = deductStakingFee(i.payments[0].amount, pmtAssetIdA, pmtAssetIdB)
361+ let pmtAmountB = deductStakingFee(i.payments[1].amount, pmtAssetIdB, pmtAssetIdA)
362+ if (if ((balanceA == 0))
363+ then (balanceB == 0)
364+ else false)
365+ then {
366+ let $t01345913536 = getAssetInfo(pmtAssetIdA)
367+ let pmtStrAssetIdA = $t01345913536._1
368+ let pmtAssetNameA = $t01345913536._2
369+ let pmtDecimalsA = $t01345913536._3
370+ let $t01354513622 = getAssetInfo(pmtAssetIdB)
371+ let pmtStrAssetIdB = $t01354513622._1
372+ let pmtAssetNameB = $t01354513622._2
373+ let pmtDecimalsB = $t01354513622._3
374+ let tokenRatio = fraction(fraction(assetInitA, scaleValue8, pmtAmountA), scaleValue3, fraction(assetInitB, scaleValue8, pmtAmountB))
375+ if ((pmtAssetIdA == pmtAssetIdB))
376+ then throw("Assets must be different")
377+ else {
378+ let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
379+ let shareInitialSupply = fraction(pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN), pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN), pow(10, 0, shareDecimals, 0, 0, DOWN))
380+ if (!(isActive))
381+ then throw("DApp is inactive at this moment")
382+ else if (if ((0 > slippageTolerance))
383+ then true
384+ else (slippageTolerance > slippageToleranceDelimiter))
385+ then throw(((("Slippage tolerance must be between 0 and " + toString(slippageToleranceDelimiter)) + " inclusively. Actual: ") + toString(slippageTolerance)))
386+ else if ((size(i.payments) != 2))
387+ then throw("Two attached assets expected")
388+ else if (if ((((scaleValue3 * (slippageToleranceDelimiter - slippageTolerance)) / slippageToleranceDelimiter) > tokenRatio))
389+ then true
390+ else (tokenRatio > ((scaleValue3 * (slippageToleranceDelimiter + slippageTolerance)) / slippageToleranceDelimiter)))
391+ then throw("Incorrect assets amount: amounts must have the contract ratio")
392+ else if (if ((pmtAssetIdA != assetIdA))
393+ then true
394+ else (pmtAssetIdB != assetIdB))
395+ then throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
396+ else if ((shareInitialSupply == 0))
397+ then throw("Too small amount to replenish")
398+ else if (!(hasEnoughBalance))
399+ then ([ScriptTransfer(i.caller, pmtAmountA, pmtAssetIdA), ScriptTransfer(i.caller, pmtAmountB, pmtAssetIdB)] ++ suspendSuspicious())
400+ else [Reissue(shareAssetId, shareInitialSupply, true), IntegerEntry(keyBalanceA, pmtAmountA), IntegerEntry(keyBalanceB, pmtAmountB), IntegerEntry(keyShareAssetSupply, shareInitialSupply), ScriptTransfer(i.caller, shareInitialSupply, shareAssetId)]
401+ }
402+ }
403+ else {
404+ let tokenRatio = fraction(fraction(balanceA, scaleValue8, pmtAmountA), scaleValue3, fraction(balanceB, scaleValue8, pmtAmountB))
405+ let ratioShareTokensInA = fraction(pmtAmountA, scaleValue8, balanceA)
406+ let ratioShareTokensInB = fraction(pmtAmountB, scaleValue8, balanceB)
407+ let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scaleValue8)
408+ if (!(isActive))
409+ then throw("DApp is inactive at this moment")
410+ else if (if ((0 > slippageTolerance))
260411 then true
261- else (pmtAssetIdB != assetIdB))
262- then throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
263- else if (if ((((scaleValue3 * (slippageToleranceDelimiter - slippageTolerance)) / slippageToleranceDelimiter) > tokenRatio))
264- then true
265- else (tokenRatio > ((scaleValue3 * (slippageToleranceDelimiter + slippageTolerance)) / slippageToleranceDelimiter)))
266- then throw("Incorrect assets amount: amounts must have the contract ratio")
267- else if ((shareTokenToPayAmount == 0))
268- then throw("Too small amount to replenish")
269- else if (!(hasEnoughBalance))
270- then ([ScriptTransfer(i.caller, pmtAmountA, pmtAssetIdA), ScriptTransfer(i.caller, pmtAmountB, pmtAssetIdB)] ++ suspendSuspicious())
271- else [IntegerEntry(keyBalanceA, (balanceA + pmtAmountA)), IntegerEntry(keyBalanceB, (balanceB + pmtAmountB)), IntegerEntry(keyShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId)]
412+ else (slippageTolerance > slippageToleranceDelimiter))
413+ then throw(((("Slippage tolerance must be between 0 and " + toString(slippageToleranceDelimiter)) + " inclusively. Actual: ") + toString(slippageTolerance)))
414+ else if ((size(i.payments) != 2))
415+ then throw("Two attached assets expected")
416+ else if (if ((pmtAssetIdA != assetIdA))
417+ then true
418+ else (pmtAssetIdB != assetIdB))
419+ then throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
420+ else if (if ((((scaleValue3 * (slippageToleranceDelimiter - slippageTolerance)) / slippageToleranceDelimiter) > tokenRatio))
421+ then true
422+ else (tokenRatio > ((scaleValue3 * (slippageToleranceDelimiter + slippageTolerance)) / slippageToleranceDelimiter)))
423+ then throw("Incorrect assets amount: amounts must have the contract ratio")
424+ else if ((shareTokenToPayAmount == 0))
425+ then throw("Too small amount to replenish")
426+ else if (!(hasEnoughBalance))
427+ then ([ScriptTransfer(i.caller, pmtAmountA, pmtAssetIdA), ScriptTransfer(i.caller, pmtAmountB, pmtAssetIdB)] ++ suspendSuspicious())
428+ else [IntegerEntry(keyBalanceA, (balanceA + pmtAmountA)), IntegerEntry(keyBalanceB, (balanceB + pmtAmountB)), IntegerEntry(keyShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId)]
429+ }
272430 }
273431
274432
275433
276434 @Callable(i)
277435 func withdraw () = {
278- let $t01032110471 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
279- let pmtAmount = $t01032110471._1
280- let pmtAssetId = $t01032110471._2
281- let amountToPayA = deductStakingFee(fraction(pmtAmount, balanceA, shareAssetSupply), assetIdA)
282- let amountToPayB = deductStakingFee(fraction(pmtAmount, balanceB, shareAssetSupply), assetIdB)
436+ let $t01802118171 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
437+ let pmtAmount = $t01802118171._1
438+ let pmtAssetId = $t01802118171._2
439+ let amountToPayA = deductStakingFee(fraction(pmtAmount, balanceA, shareAssetSupply), assetIdA, assetIdB)
440+ let amountToPayB = deductStakingFee(fraction(pmtAmount, balanceB, shareAssetSupply), assetIdB, assetIdA)
283441 if (!(isActive))
284442 then throw("DApp is inactive at this moment")
285443 else if ((size(i.payments) != 1))
299457
300458 @Callable(i)
301459 func exchange (minAmountToReceive) = {
302- let $t01167811753 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
303- let pmtAmount = $t01167811753._1
304- let pmtAssetId = $t01167811753._2
460+ let $t01939719472 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
461+ let pmtAmount = $t01939719472._1
462+ let pmtAssetId = $t01939719472._2
305463 func calculateFees (tokenFrom,tokenTo) = {
306464 let amountWithoutFee = fraction(tokenTo, pmtAmount, (pmtAmount + tokenFrom))
307465 let amountWithFee = fraction(amountWithoutFee, (commissionScaleDelimiter - commission), commissionScaleDelimiter)
313471
314472 if (!(isActive))
315473 then throw("DApp is inactive at this moment")
316- else if ((0 >= minAmountToReceive))
317- then throw(("Minimal amount to receive must be positive. Actual: " + toString(minAmountToReceive)))
318- else if ((size(i.payments) != 1))
319- then throw("One attached payment expected")
320- else if (!(hasEnoughBalance))
321- then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
322- else if ((pmtAssetId == assetIdA))
323- then {
324- let assetIdSend = assetIdB
325- let $t01292913020 = calculateFees(balanceA, balanceB)
326- let amountWithoutFee = $t01292913020._1
327- let amountWithFee = $t01292913020._2
328- let governanceReward = $t01292913020._3
329- let newBalanceA = (balanceA + pmtAmount)
330- let newBalanceB = ((balanceB - amountWithFee) - governanceReward)
331- if (if ((stakedAmountA >= newBalanceA))
332- then true
333- else (stakedAmountB >= newBalanceB))
334- then throwInsufficientAvailableBalance(amountWithFee, availableBalanceB, assetNameB)
335- else [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(governanceAddress, governanceReward, assetIdSend)]
336- }
337- else if ((pmtAssetId == assetIdB))
474+ else if (if ((balanceA == 0))
475+ then true
476+ else (balanceB == 0))
477+ then throw("Can't exchange with zero balance")
478+ else if ((0 >= minAmountToReceive))
479+ then throw(("Minimal amount to receive must be positive. Actual: " + toString(minAmountToReceive)))
480+ else if ((size(i.payments) != 1))
481+ then throw("One attached payment expected")
482+ else if (!(hasEnoughBalance))
483+ then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
484+ else if ((pmtAssetId == assetIdA))
338485 then {
339- let assetIdSend = assetIdA
340- let $t01384313934 = calculateFees(balanceB, balanceA)
341- let amountWithoutFee = $t01384313934._1
342- let amountWithFee = $t01384313934._2
343- let governanceReward = $t01384313934._3
344- let newBalanceA = ((balanceA - amountWithFee) - governanceReward)
345- let newBalanceB = (balanceB + pmtAmount)
486+ let assetIdSend = assetIdB
487+ let $t02074620837 = calculateFees(balanceA, balanceB)
488+ let amountWithoutFee = $t02074620837._1
489+ let amountWithFee = $t02074620837._2
490+ let governanceReward = $t02074620837._3
491+ let newBalanceA = (balanceA + pmtAmount)
492+ let newBalanceB = ((balanceB - amountWithFee) - governanceReward)
346493 if (if ((stakedAmountA >= newBalanceA))
347494 then true
348495 else (stakedAmountB >= newBalanceB))
349- then throwInsufficientAvailableBalance(amountWithFee, availableBalanceA, assetNameA)
350- else [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(governanceAddress, governanceReward, assetIdSend)]
496+ then throwInsufficientAvailableBalance(amountWithFee, availableBalanceB, assetNameB)
497+ else [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(walletAddress, governanceReward, assetIdSend)]
351498 }
352- else throw(((("Incorrect asset attached. Expected: " + strAssetIdA) + " or ") + strAssetIdB))
499+ else if ((pmtAssetId == assetIdB))
500+ then {
501+ let assetIdSend = assetIdA
502+ let $t02165621747 = calculateFees(balanceB, balanceA)
503+ let amountWithoutFee = $t02165621747._1
504+ let amountWithFee = $t02165621747._2
505+ let governanceReward = $t02165621747._3
506+ let newBalanceA = ((balanceA - amountWithFee) - governanceReward)
507+ let newBalanceB = (balanceB + pmtAmount)
508+ if (if ((stakedAmountA >= newBalanceA))
509+ then true
510+ else (stakedAmountB >= newBalanceB))
511+ then throwInsufficientAvailableBalance(amountWithFee, availableBalanceA, assetNameA)
512+ else [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(walletAddress, governanceReward, assetIdSend)]
513+ }
514+ else throw(((("Incorrect asset attached. Expected: " + strAssetIdA) + " or ") + strAssetIdB))
353515 }
354516
355517
416578 }
417579 match tx {
418580 case inv: InvokeScriptTransaction =>
419- if (if (if (if (sigVerify(inv.bodyBytes, inv.proofs[0], adminPubKeyStaking))
420- then (inv.dApp == stakingAddressUSDN)
581+ let callTakeIntoAccount = if ((inv.dApp == this))
582+ then (inv.function == "takeIntoAccountExtraFunds")
583+ else false
584+ let callStaking = if (if ((inv.dApp == stakingUSDNNSBTAddress))
585+ then if (if (if ((inv.function == "lockNeutrino"))
586+ then (size(inv.payments) == 1)
587+ else false)
588+ then if ((inv.payments[0].assetId == USDN))
589+ then true
590+ else (inv.payments[0].assetId == NSBT)
591+ else false)
592+ then true
593+ else if ((inv.function == "unlockNeutrino"))
594+ then (size(inv.payments) == 0)
595+ else false
421596 else false)
422597 then true
423- else if (if (sigVerify(inv.bodyBytes, inv.proofs[0], adminPubKeyStaking))
424- then (inv.function == "exchange")
425- else false)
426- then if (if (if (if (if ((assetIdA == NSBT))
427- then (assetIdB == USDN)
598+ else if ((inv.dApp == stakingEURNAddress))
599+ then if (if (if ((inv.function == "startStaking"))
600+ then (size(inv.payments) == 1)
428601 else false)
429- then (inv.dApp == swopUSDNtoWAVES)
430- else false)
431- then (inv.payments[0].assetId == unit)
432- else false)
433- then if ((inv.payments[0].assetId == unit))
434- then true
435- else (inv.payments[0].assetId == USDN)
602+ then (inv.payments[0].assetId == EURN)
436603 else false)
437604 then true
438- else if (if ((assetIdA == NSBT))
439- then (assetIdB == SWOP)
440- else false)
441- then if (if ((inv.dApp == swopUSDNtoNSBT))
442- then (inv.payments[0].assetId == USDN)
443- else false)
444- then true
445- else if ((inv.dApp == swopUSDNtoWAVES))
446- then if ((inv.payments[0].assetId == unit))
447- then true
448- else (inv.payments[0].assetId == USDN)
449- else false
605+ else if ((inv.function == "stopStaking"))
606+ then (size(inv.payments) == 0)
450607 else false
608+ else false
609+ let exchangeToWaves = if (if (if ((inv.dApp == USDNToWavesExchanger))
610+ then (inv.function == "exchange")
611+ else false)
612+ then (assetIdA == USDN)
613+ else false)
614+ then true
615+ else if (if ((assetIdB == USDN))
616+ then (size(inv.payments) == 1)
451617 else false)
618+ then (inv.payments[0].assetId == USDN)
619+ else false
620+ let exchangeToNSBTs = if (if (if ((inv.dApp == USDNToNSBTExchanger))
621+ then (inv.function == "exchange")
622+ else false)
623+ then (assetIdA == NSBT)
624+ else false)
452625 then true
453- else if (if (sigVerify(inv.bodyBytes, inv.proofs[0], adminPubKeyStaking))
454- then (inv.dApp == this)
626+ else if (if ((assetIdB == NSBT))
627+ then (size(inv.payments) == 1)
455628 else false)
456- then (inv.function == "takeIntoAccountExtraFunds")
457- else false)
629+ then (inv.payments[0].assetId == USDN)
630+ else false
631+ let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
632+ then true
633+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey2))
634+ then true
635+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey3))
636+ then true
637+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKeyStaking)
638+ if (if (if (if (if (callTakeIntoAccount)
639+ then true
640+ else callStaking)
641+ then true
642+ else exchangeToWaves)
643+ then true
644+ else exchangeToNSBTs)
645+ then signedByAdmin
646+ else false)
458647 then true
459648 else multiSignedByAdmins
460649 case _ =>
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let version = "1.0.0"
55
66 let keyVersion = "version"
77
88 let keyActive = "active"
99
1010 let keyAssetIdA = "A_asset_id"
1111
1212 let keyAssetIdB = "B_asset_id"
1313
1414 let keyBalanceA = "A_asset_balance"
1515
1616 let keyBalanceB = "B_asset_balance"
1717
18+let keyBalanceInitA = "A_asset_init"
19+
20+let keyBalanceInitB = "B_asset_init"
21+
1822 let keyShareAssetId = "share_asset_id"
1923
2024 let keyShareAssetSupply = "share_asset_supply"
2125
2226 let keyCommission = "commission"
2327
2428 let keyCommissionScaleDelimiter = "commission_scale_delimiter"
2529
2630 let keyCause = "shutdown_cause"
31+
32+let keyFirstHarvest = "first_harvest"
33+
34+let keyFirstHarvestHeight = "first_harvest_height"
35+
36+let kShareLimit = "share_limit_on_first_harvest"
37+
38+let kBasePeriod = "base_period"
39+
40+let kPeriodLength = "period_length"
41+
42+let kStartHeight = "start_height"
43+
44+let kFirstHarvestHeight = "first_harvest_height"
2745
2846 let keyAdminPubKey1 = "admin_pub_1"
2947
3048 let keyAdminPubKey2 = "admin_pub_2"
3149
3250 let keyAdminPubKey3 = "admin_pub_3"
3351
3452 let oracle = Address(base58'3NBBWfzZtZtszaXbitTKnrB2xXwv26Bn7H9')
3553
3654 func getAdminPub (keyAdminPub) = match getString(oracle, keyAdminPub) {
3755 case string: String =>
3856 fromBase58String(string)
3957 case nothing =>
4058 throw("Admin public key is empty")
4159 }
4260
4361
4462 let adminPubKey1 = getAdminPub(keyAdminPubKey1)
4563
4664 let adminPubKey2 = getAdminPub(keyAdminPubKey2)
4765
4866 let adminPubKey3 = getAdminPub(keyAdminPubKey3)
4967
5068 let adminPubKeyStartStop = base58'Kn7NpzaG12dLZgcHf2ipUftU6hbJygmrhFqQYE4B7ZK'
5169
5270 let adminPubKeyStaking = base58'Kn7NpzaG12dLZgcHf2ipUftU6hbJygmrhFqQYE4B7ZK'
5371
54-let governanceAddress = Address(base58'3NAGTtZz6WpupSN89NZD5rMZwwziZEg4Kx4')
72+let walletAddress = Address(base58'3NAGTtZz6WpupSN89NZD5rMZwwziZEg4Kx4')
5573
56-let stakingAddressUSDN = Address(base58'3N6q7sCGSSLBUXDdjBdYGTJbZGZfhhh8cNg')
74+let votingAddress = Address(base58'3MrJgdL1GniipErHy44YF9idzLaUL2iX5DQ')
5775
5876 let USDN = base58'8UrfDVd5GreeUwm7uPk7eYz1eMv376kzR52C6sANPkwS'
5977
6078 let NSBT = base58'36mg8NZTaFRDygiVwb8uBnLR51hetJruUCZcxhaVcHj9'
6179
6280 let SWOP = base58'2HAJrwa8q4SxBx9cHYaBTQdBjdk5wwqdof7ccpAx2uhZ'
6381
64-let swopUSDNtoWAVES = Address(base58'3N77kfPbQyjXWpDALX3xjKw3iEGMWEctV37')
82+let EURN = base58'ECBCkHS68DckpBrzLeoRgYbFg7sCVqR176mPqbXsj9pA'
6583
66-let swopUSDNtoNSBT = Address(base58'3MzTHd4e3yukNUURApVLVzH5uxeEsXHD6yY')
84+let stakingUSDNNSBTAddress = Address(base58'3N1qKnD3EoFpmFphWeZgmFjAUPXJmGw9cUp')
85+
86+let stakingEURNAddress = Address(base58'3MyVqAbmKWh339gF6hy8faWw1jGeTV2wnGE')
87+
88+let USDNToWavesExchanger = Address(base58'3N77kfPbQyjXWpDALX3xjKw3iEGMWEctV37')
89+
90+let USDNToNSBTExchanger = Address(base58'3MzTHd4e3yukNUURApVLVzH5uxeEsXHD6yY')
6791
6892 let stakingFeeInUSDN = 270000
93+
94+let stakingFeeInEURN = 234000
95+
96+let basePeriod = valueOrErrorMessage(getInteger(votingAddress, kBasePeriod), "Empty kBasePeriod")
97+
98+let startHeight = valueOrErrorMessage(getInteger(votingAddress, kStartHeight), "Empty kStartHeight")
99+
100+let periodLength = valueOrErrorMessage(getInteger(votingAddress, kPeriodLength), "Empty kPeriodLength")
101+
102+let firstHarvestEndPeriod = ((basePeriod + ((height - startHeight) / periodLength)) + 3)
69103
70104 let isActive = getBooleanValue(this, keyActive)
71105
72106 let strAssetIdA = getStringValue(this, keyAssetIdA)
73107
74108 let strAssetIdB = getStringValue(this, keyAssetIdB)
75109
76110 let assetIdA = if ((strAssetIdA == "WAVES"))
77111 then unit
78112 else fromBase58String(strAssetIdA)
79113
80114 let assetIdB = if ((strAssetIdB == "WAVES"))
81115 then unit
82116 else fromBase58String(strAssetIdB)
83117
84118 let assetNameA = match assetIdA {
85119 case id: ByteVector =>
86120 value(assetInfo(id)).name
87121 case waves: Unit =>
88122 "WAVES"
89123 case _ =>
90124 throw("Match error")
91125 }
92126
93127 let assetNameB = match assetIdB {
94128 case id: ByteVector =>
95129 value(assetInfo(id)).name
96130 case waves: Unit =>
97131 "WAVES"
98132 case _ =>
99133 throw("Match error")
100134 }
101135
102136 let balanceA = getIntegerValue(this, keyBalanceA)
103137
104138 let balanceB = getIntegerValue(this, keyBalanceB)
105139
106140 let shareAssetId = fromBase58String(getStringValue(this, keyShareAssetId))
107141
108142 let shareAssetSupply = getIntegerValue(this, keyShareAssetSupply)
109143
110144 let commission = 3000
111145
112146 let commissionGovernance = 1200
113147
114148 let commissionScaleDelimiter = 1000000
115149
116150 let scaleValue3 = 1000
117151
118152 let scaleValue8 = 100000000
119153
120154 let slippageToleranceDelimiter = 1000
121155
122156 let scaleValue8Digits = 8
123157
124158 func accountBalance (assetId) = match assetId {
125159 case id: ByteVector =>
126160 assetBalance(this, id)
127161 case waves: Unit =>
128162 wavesBalance(this).available
129163 case _ =>
130164 throw("Match error")
131165 }
132166
133167
134-func stakedAmount (stakingAddress,asset) = {
135- let stakedAmountCalculated = match getInteger(stakingAddress, ((("rpd_balance_" + asset) + "_") + toString(this))) {
136- case staked: Int =>
137- staked
138- case nothing: Unit =>
168+func stakedAmount (assetId) = {
169+ let stakedAmountCalculated = match assetId {
170+ case aId: ByteVector =>
171+ if (if ((aId == USDN))
172+ then true
173+ else (aId == NSBT))
174+ then getInteger(stakingUSDNNSBTAddress, ((("rpd_balance_" + toBase58String(aId)) + "_") + toString(this)))
175+ else if ((aId == EURN))
176+ then getInteger(stakingEURNAddress, ((("%s%s%s__stakingBalance__" + toBase58String(aId)) + "__") + toString(this)))
177+ else 0
178+ case _: Unit =>
139179 0
140180 case _ =>
141181 throw("Match error")
142182 }
143- stakedAmountCalculated
183+ match stakedAmountCalculated {
184+ case i: Int =>
185+ i
186+ case _ =>
187+ 0
188+ }
144189 }
145190
146191
147-let stakedAmountA = stakedAmount(stakingAddressUSDN, strAssetIdA)
192+let stakedAmountA = stakedAmount(assetIdA)
148193
149-let stakedAmountB = stakedAmount(stakingAddressUSDN, strAssetIdB)
194+let stakedAmountB = stakedAmount(assetIdB)
195+
196+let assetInitA = getIntegerValue(this, keyBalanceInitA)
197+
198+let assetInitB = getIntegerValue(this, keyBalanceInitB)
150199
151200 let availableBalanceA = (balanceA - stakedAmountA)
152201
153202 let availableBalanceB = (balanceB - stakedAmountB)
154203
155204 let accountBalanceWithStakedA = (accountBalance(assetIdA) + stakedAmountA)
156205
157206 let accountBalanceWithStakedB = (accountBalance(assetIdB) + stakedAmountB)
158207
159208 let hasEnoughBalance = if ((accountBalanceWithStakedA >= balanceA))
160209 then (accountBalanceWithStakedB >= balanceB)
161210 else false
162211
163212 func getAssetInfo (assetId) = match assetId {
164213 case id: ByteVector =>
165214 let stringId = toBase58String(id)
166215 let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
167216 $Tuple3(stringId, info.name, info.decimals)
168217 case waves: Unit =>
169218 $Tuple3("WAVES", "WAVES", 8)
170219 case _ =>
171220 throw("Match error")
172221 }
173222
174223
224+func getAssetInfoFromString (assetStr) = if ((assetStr == "WAVES"))
225+ then $Tuple3("WAVES", "WAVES", 8)
226+ else {
227+ let stringId = assetStr
228+ let id = fromBase58String(assetStr)
229+ let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
230+ $Tuple3(stringId, info.name, info.decimals)
231+ }
232+
233+
175234 func suspend (cause) = [BooleanEntry(keyActive, false), StringEntry(keyCause, cause)]
176235
177236
178-func stakedTokenCount () = {
179- let isStakedA = if ((stakedAmountA > 0))
180- then 1
181- else 0
182- let isStakedB = if ((stakedAmountB > 0))
183- then 1
184- else 0
185- (isStakedA + isStakedB)
186- }
187-
188-
189-func deductStakingFee (amount,assetId) = if ((assetId == USDN))
237+func deductStakingFee (amount,assetId,secondAssetId) = if (if ((assetId == USDN))
238+ then true
239+ else (assetId == EURN))
190240 then {
191- let result = (amount - (stakedTokenCount() * stakingFeeInUSDN))
241+ let stakinFee = if ((assetId == USDN))
242+ then (stakingFeeInUSDN * (if ((secondAssetId == NSBT))
243+ then 2
244+ else 1))
245+ else if ((assetId == EURN))
246+ then stakingFeeInEURN
247+ else 0
248+ let result = (amount - stakinFee)
192249 if ((0 >= result))
193- then throw((((("Insufficient amount " + toString(amount)) + " to deduct staking fee ") + toString(stakingFeeInUSDN)) + " USD-N"))
250+ then throw((((("Insufficient amount " + toString(amount)) + " to deduct staking fee ") + toString(stakinFee)) + "USDN/EURN"))
194251 else result
195252 }
196253 else amount
254+
255+
256+func getStakingFee (assetId,secondAssetId) = if ((assetId == USDN))
257+ then (stakingFeeInUSDN * (if ((secondAssetId == NSBT))
258+ then 2
259+ else 1))
260+ else if ((assetId == EURN))
261+ then stakingFeeInEURN
262+ else 0
197263
198264
199265 func throwInsufficientAvailableBalance (amount,available,assetName) = throw((((((((("Insufficient DApp balance to pay " + toString(amount)) + " ") + assetName) + " due to staking. Available: ") + toString(available)) + " ") + assetName) + ". Please contact support in Telegram: https://t.me/swopfisupport"))
200266
201267
202268 func throwInsufficientAvailableBalances (amountA,amountB) = throw((((((((((((((((("Insufficient DApp balance to pay " + toString(amountA)) + " ") + assetNameA) + " and ") + toString(amountB)) + " ") + assetNameB) + " due to staking. Available: ") + toString(availableBalanceA)) + " ") + assetNameA) + " and ") + toString(availableBalanceB)) + " ") + assetNameB) + ". Please contact support in Telegram: https://t.me/swopfisupport"))
203269
204270
205271 func suspendSuspicious () = suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(accountBalanceWithStakedA)) + " ") + assetNameA) + ", ") + toString(accountBalanceWithStakedB)) + " ") + assetNameB) + ". State: ") + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB))
206272
207273
208274 @Callable(i)
209-func init () = {
210- let $t059366013 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
211- let pmtAmountA = $t059366013._1
212- let pmtAssetIdA = $t059366013._2
213- let $t060186095 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
214- let pmtAmountB = $t060186095._1
215- let pmtAssetIdB = $t060186095._2
216- let $t061006177 = getAssetInfo(pmtAssetIdA)
217- let pmtStrAssetIdA = $t061006177._1
218- let pmtAssetNameA = $t061006177._2
219- let pmtDecimalsA = $t061006177._3
220- let $t061826259 = getAssetInfo(pmtAssetIdB)
221- let pmtStrAssetIdB = $t061826259._1
222- let pmtAssetNameB = $t061826259._2
223- let pmtDecimalsB = $t061826259._3
224- if (isDefined(getBoolean(this, keyActive)))
225- then throw("DApp is already active")
226- else if ((pmtAssetIdA == pmtAssetIdB))
227- then throw("Assets must be different")
228- else {
229- let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
230- let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
231- let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
232- let shareInitialSupply = fraction(pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN), pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN), pow(10, 0, shareDecimals, 0, 0, DOWN))
233- let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
234- let shareIssueId = calculateAssetId(shareIssue)
235-[StringEntry(keyVersion, version), BooleanEntry(keyActive, true), StringEntry(keyAssetIdA, pmtStrAssetIdA), StringEntry(keyAssetIdB, pmtStrAssetIdB), IntegerEntry(keyBalanceA, pmtAmountA), IntegerEntry(keyBalanceB, pmtAmountB), IntegerEntry(keyCommission, commission), IntegerEntry(keyCommissionScaleDelimiter, commissionScaleDelimiter), shareIssue, StringEntry(keyShareAssetId, toBase58String(shareIssueId)), IntegerEntry(keyShareAssetSupply, shareInitialSupply), ScriptTransfer(i.caller, shareInitialSupply, shareIssueId)]
236- }
275+func init (firstHarvest) = {
276+ let $t080018078 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
277+ let pmtAmountA = $t080018078._1
278+ let pmtAssetIdA = $t080018078._2
279+ let $t080838160 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
280+ let pmtAmountB = $t080838160._1
281+ let pmtAssetIdB = $t080838160._2
282+ let $t081658242 = getAssetInfo(pmtAssetIdA)
283+ let pmtStrAssetIdA = $t081658242._1
284+ let pmtAssetNameA = $t081658242._2
285+ let pmtDecimalsA = $t081658242._3
286+ let $t082478324 = getAssetInfo(pmtAssetIdB)
287+ let pmtStrAssetIdB = $t082478324._1
288+ let pmtAssetNameB = $t082478324._2
289+ let pmtDecimalsB = $t082478324._3
290+ if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey)))
291+ then throw("Only admin can call this function")
292+ else if (isDefined(getBoolean(this, keyActive)))
293+ then throw("DApp is already active")
294+ else if ((pmtAssetIdA == pmtAssetIdB))
295+ then throw("Assets must be different")
296+ else {
297+ let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
298+ let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
299+ let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
300+ let arg1 = pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN)
301+ let arg2 = pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN)
302+ let arg3 = pow(10, 0, shareDecimals, 0, 0, DOWN)
303+ let shareInitialSupply = fraction(arg1, arg2, arg3)
304+ let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
305+ let shareIssueId = calculateAssetId(shareIssue)
306+ let baseEntry = [StringEntry(keyVersion, version), BooleanEntry(keyActive, true), StringEntry(keyAssetIdA, pmtStrAssetIdA), StringEntry(keyAssetIdB, pmtStrAssetIdB), IntegerEntry(keyBalanceA, pmtAmountA), IntegerEntry(keyBalanceB, pmtAmountB), IntegerEntry(keyCommission, commission), IntegerEntry(keyCommissionScaleDelimiter, commissionScaleDelimiter), shareIssue, StringEntry(keyShareAssetId, toBase58String(shareIssueId)), IntegerEntry(keyShareAssetSupply, shareInitialSupply), ScriptTransfer(i.caller, shareInitialSupply, shareIssueId)]
307+ if (firstHarvest)
308+ then (baseEntry ++ [BooleanEntry(keyFirstHarvest, firstHarvest), IntegerEntry(keyFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))])
309+ else baseEntry
310+ }
237311 }
312+
313+
314+
315+@Callable(i)
316+func initWithInitRatio (amtAssetA,amtAssetB,strAssetIdA,strAssetIdB,firstHarvest) = {
317+ let $t01056910656 = getAssetInfoFromString(strAssetIdA)
318+ let pmtStrAssetIdA = $t01056910656._1
319+ let pmtAssetNameA = $t01056910656._2
320+ let pmtDecimalsA = $t01056910656._3
321+ let $t01066110748 = getAssetInfoFromString(strAssetIdB)
322+ let pmtStrAssetIdB = $t01066110748._1
323+ let pmtAssetNameB = $t01066110748._2
324+ let pmtDecimalsB = $t01066110748._3
325+ if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey)))
326+ then throw("Only admin can call this function")
327+ else if (isDefined(getBoolean(this, keyActive)))
328+ then throw("DApp is already active")
329+ else if ((strAssetIdA == strAssetIdB))
330+ then throw("Assets must be different")
331+ else {
332+ let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
333+ let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
334+ let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
335+ let shareInitialSupply = 0
336+ let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
337+ let shareIssueId = calculateAssetId(shareIssue)
338+ let baseEntry = [StringEntry(keyVersion, version), BooleanEntry(keyActive, true), StringEntry(keyAssetIdA, pmtStrAssetIdA), StringEntry(keyAssetIdB, pmtStrAssetIdB), IntegerEntry(keyBalanceInitA, amtAssetA), IntegerEntry(keyBalanceInitB, amtAssetB), IntegerEntry(keyBalanceA, 0), IntegerEntry(keyBalanceB, 0), IntegerEntry(keyCommission, commission), IntegerEntry(keyCommissionScaleDelimiter, commissionScaleDelimiter), shareIssue, StringEntry(keyShareAssetId, toBase58String(shareIssueId)), IntegerEntry(keyShareAssetSupply, shareInitialSupply)]
339+ if (firstHarvest)
340+ then (baseEntry ++ [BooleanEntry(keyFirstHarvest, firstHarvest), IntegerEntry(keyFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))])
341+ else baseEntry
342+ }
343+ }
344+
345+
346+
347+@Callable(i)
348+func keepLimitForFirstHarvest (shareLimit) = if (!(isActive))
349+ then throw("DApp is inactive at this moment")
350+ else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey)))
351+ then throw("Only admin can call this function")
352+ else [IntegerEntry(kShareLimit, shareLimit)]
238353
239354
240355
241356 @Callable(i)
242357 func replenishWithTwoTokens (slippageTolerance) = {
243358 let pmtAssetIdA = i.payments[0].assetId
244359 let pmtAssetIdB = i.payments[1].assetId
245- let pmtAmountA = deductStakingFee(i.payments[0].amount, pmtAssetIdA)
246- let pmtAmountB = deductStakingFee(i.payments[1].amount, pmtAssetIdB)
247- let tokenRatio = fraction(fraction(balanceA, scaleValue8, pmtAmountA), scaleValue3, fraction(balanceB, scaleValue8, pmtAmountB))
248- let ratioShareTokensInA = fraction(pmtAmountA, scaleValue8, balanceA)
249- let ratioShareTokensInB = fraction(pmtAmountB, scaleValue8, balanceB)
250- let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scaleValue8)
251- if (!(isActive))
252- then throw("DApp is inactive at this moment")
253- else if (if ((0 > slippageTolerance))
254- then true
255- else (slippageTolerance > slippageToleranceDelimiter))
256- then throw(((("Slippage tolerance must be between 0 and " + toString(slippageToleranceDelimiter)) + " inclusively. Actual: ") + toString(slippageTolerance)))
257- else if ((size(i.payments) != 2))
258- then throw("Two attached assets expected")
259- else if (if ((pmtAssetIdA != assetIdA))
360+ let pmtAmountA = deductStakingFee(i.payments[0].amount, pmtAssetIdA, pmtAssetIdB)
361+ let pmtAmountB = deductStakingFee(i.payments[1].amount, pmtAssetIdB, pmtAssetIdA)
362+ if (if ((balanceA == 0))
363+ then (balanceB == 0)
364+ else false)
365+ then {
366+ let $t01345913536 = getAssetInfo(pmtAssetIdA)
367+ let pmtStrAssetIdA = $t01345913536._1
368+ let pmtAssetNameA = $t01345913536._2
369+ let pmtDecimalsA = $t01345913536._3
370+ let $t01354513622 = getAssetInfo(pmtAssetIdB)
371+ let pmtStrAssetIdB = $t01354513622._1
372+ let pmtAssetNameB = $t01354513622._2
373+ let pmtDecimalsB = $t01354513622._3
374+ let tokenRatio = fraction(fraction(assetInitA, scaleValue8, pmtAmountA), scaleValue3, fraction(assetInitB, scaleValue8, pmtAmountB))
375+ if ((pmtAssetIdA == pmtAssetIdB))
376+ then throw("Assets must be different")
377+ else {
378+ let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
379+ let shareInitialSupply = fraction(pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN), pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN), pow(10, 0, shareDecimals, 0, 0, DOWN))
380+ if (!(isActive))
381+ then throw("DApp is inactive at this moment")
382+ else if (if ((0 > slippageTolerance))
383+ then true
384+ else (slippageTolerance > slippageToleranceDelimiter))
385+ then throw(((("Slippage tolerance must be between 0 and " + toString(slippageToleranceDelimiter)) + " inclusively. Actual: ") + toString(slippageTolerance)))
386+ else if ((size(i.payments) != 2))
387+ then throw("Two attached assets expected")
388+ else if (if ((((scaleValue3 * (slippageToleranceDelimiter - slippageTolerance)) / slippageToleranceDelimiter) > tokenRatio))
389+ then true
390+ else (tokenRatio > ((scaleValue3 * (slippageToleranceDelimiter + slippageTolerance)) / slippageToleranceDelimiter)))
391+ then throw("Incorrect assets amount: amounts must have the contract ratio")
392+ else if (if ((pmtAssetIdA != assetIdA))
393+ then true
394+ else (pmtAssetIdB != assetIdB))
395+ then throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
396+ else if ((shareInitialSupply == 0))
397+ then throw("Too small amount to replenish")
398+ else if (!(hasEnoughBalance))
399+ then ([ScriptTransfer(i.caller, pmtAmountA, pmtAssetIdA), ScriptTransfer(i.caller, pmtAmountB, pmtAssetIdB)] ++ suspendSuspicious())
400+ else [Reissue(shareAssetId, shareInitialSupply, true), IntegerEntry(keyBalanceA, pmtAmountA), IntegerEntry(keyBalanceB, pmtAmountB), IntegerEntry(keyShareAssetSupply, shareInitialSupply), ScriptTransfer(i.caller, shareInitialSupply, shareAssetId)]
401+ }
402+ }
403+ else {
404+ let tokenRatio = fraction(fraction(balanceA, scaleValue8, pmtAmountA), scaleValue3, fraction(balanceB, scaleValue8, pmtAmountB))
405+ let ratioShareTokensInA = fraction(pmtAmountA, scaleValue8, balanceA)
406+ let ratioShareTokensInB = fraction(pmtAmountB, scaleValue8, balanceB)
407+ let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scaleValue8)
408+ if (!(isActive))
409+ then throw("DApp is inactive at this moment")
410+ else if (if ((0 > slippageTolerance))
260411 then true
261- else (pmtAssetIdB != assetIdB))
262- then throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
263- else if (if ((((scaleValue3 * (slippageToleranceDelimiter - slippageTolerance)) / slippageToleranceDelimiter) > tokenRatio))
264- then true
265- else (tokenRatio > ((scaleValue3 * (slippageToleranceDelimiter + slippageTolerance)) / slippageToleranceDelimiter)))
266- then throw("Incorrect assets amount: amounts must have the contract ratio")
267- else if ((shareTokenToPayAmount == 0))
268- then throw("Too small amount to replenish")
269- else if (!(hasEnoughBalance))
270- then ([ScriptTransfer(i.caller, pmtAmountA, pmtAssetIdA), ScriptTransfer(i.caller, pmtAmountB, pmtAssetIdB)] ++ suspendSuspicious())
271- else [IntegerEntry(keyBalanceA, (balanceA + pmtAmountA)), IntegerEntry(keyBalanceB, (balanceB + pmtAmountB)), IntegerEntry(keyShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId)]
412+ else (slippageTolerance > slippageToleranceDelimiter))
413+ then throw(((("Slippage tolerance must be between 0 and " + toString(slippageToleranceDelimiter)) + " inclusively. Actual: ") + toString(slippageTolerance)))
414+ else if ((size(i.payments) != 2))
415+ then throw("Two attached assets expected")
416+ else if (if ((pmtAssetIdA != assetIdA))
417+ then true
418+ else (pmtAssetIdB != assetIdB))
419+ then throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
420+ else if (if ((((scaleValue3 * (slippageToleranceDelimiter - slippageTolerance)) / slippageToleranceDelimiter) > tokenRatio))
421+ then true
422+ else (tokenRatio > ((scaleValue3 * (slippageToleranceDelimiter + slippageTolerance)) / slippageToleranceDelimiter)))
423+ then throw("Incorrect assets amount: amounts must have the contract ratio")
424+ else if ((shareTokenToPayAmount == 0))
425+ then throw("Too small amount to replenish")
426+ else if (!(hasEnoughBalance))
427+ then ([ScriptTransfer(i.caller, pmtAmountA, pmtAssetIdA), ScriptTransfer(i.caller, pmtAmountB, pmtAssetIdB)] ++ suspendSuspicious())
428+ else [IntegerEntry(keyBalanceA, (balanceA + pmtAmountA)), IntegerEntry(keyBalanceB, (balanceB + pmtAmountB)), IntegerEntry(keyShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId)]
429+ }
272430 }
273431
274432
275433
276434 @Callable(i)
277435 func withdraw () = {
278- let $t01032110471 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
279- let pmtAmount = $t01032110471._1
280- let pmtAssetId = $t01032110471._2
281- let amountToPayA = deductStakingFee(fraction(pmtAmount, balanceA, shareAssetSupply), assetIdA)
282- let amountToPayB = deductStakingFee(fraction(pmtAmount, balanceB, shareAssetSupply), assetIdB)
436+ let $t01802118171 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
437+ let pmtAmount = $t01802118171._1
438+ let pmtAssetId = $t01802118171._2
439+ let amountToPayA = deductStakingFee(fraction(pmtAmount, balanceA, shareAssetSupply), assetIdA, assetIdB)
440+ let amountToPayB = deductStakingFee(fraction(pmtAmount, balanceB, shareAssetSupply), assetIdB, assetIdA)
283441 if (!(isActive))
284442 then throw("DApp is inactive at this moment")
285443 else if ((size(i.payments) != 1))
286444 then throw("One attached payment expected")
287445 else if ((pmtAssetId != shareAssetId))
288446 then throw(("Incorrect asset attached. Expected: " + toBase58String(shareAssetId)))
289447 else if (!(hasEnoughBalance))
290448 then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
291449 else if (if ((amountToPayA > availableBalanceA))
292450 then true
293451 else (amountToPayB > availableBalanceB))
294452 then throwInsufficientAvailableBalances(amountToPayA, amountToPayB)
295453 else [IntegerEntry(keyBalanceA, (balanceA - amountToPayA)), IntegerEntry(keyBalanceB, (balanceB - amountToPayB)), IntegerEntry(keyShareAssetSupply, (shareAssetSupply - pmtAmount)), Burn(shareAssetId, pmtAmount), ScriptTransfer(i.caller, amountToPayA, assetIdA), ScriptTransfer(i.caller, amountToPayB, assetIdB)]
296454 }
297455
298456
299457
300458 @Callable(i)
301459 func exchange (minAmountToReceive) = {
302- let $t01167811753 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
303- let pmtAmount = $t01167811753._1
304- let pmtAssetId = $t01167811753._2
460+ let $t01939719472 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
461+ let pmtAmount = $t01939719472._1
462+ let pmtAssetId = $t01939719472._2
305463 func calculateFees (tokenFrom,tokenTo) = {
306464 let amountWithoutFee = fraction(tokenTo, pmtAmount, (pmtAmount + tokenFrom))
307465 let amountWithFee = fraction(amountWithoutFee, (commissionScaleDelimiter - commission), commissionScaleDelimiter)
308466 let governanceReward = fraction(amountWithoutFee, commissionGovernance, commissionScaleDelimiter)
309467 if ((minAmountToReceive > amountWithFee))
310468 then throw(((("Calculated amount to receive " + toString(amountWithFee)) + " is less than specified minimum ") + toString(minAmountToReceive)))
311469 else $Tuple3(amountWithoutFee, amountWithFee, governanceReward)
312470 }
313471
314472 if (!(isActive))
315473 then throw("DApp is inactive at this moment")
316- else if ((0 >= minAmountToReceive))
317- then throw(("Minimal amount to receive must be positive. Actual: " + toString(minAmountToReceive)))
318- else if ((size(i.payments) != 1))
319- then throw("One attached payment expected")
320- else if (!(hasEnoughBalance))
321- then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
322- else if ((pmtAssetId == assetIdA))
323- then {
324- let assetIdSend = assetIdB
325- let $t01292913020 = calculateFees(balanceA, balanceB)
326- let amountWithoutFee = $t01292913020._1
327- let amountWithFee = $t01292913020._2
328- let governanceReward = $t01292913020._3
329- let newBalanceA = (balanceA + pmtAmount)
330- let newBalanceB = ((balanceB - amountWithFee) - governanceReward)
331- if (if ((stakedAmountA >= newBalanceA))
332- then true
333- else (stakedAmountB >= newBalanceB))
334- then throwInsufficientAvailableBalance(amountWithFee, availableBalanceB, assetNameB)
335- else [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(governanceAddress, governanceReward, assetIdSend)]
336- }
337- else if ((pmtAssetId == assetIdB))
474+ else if (if ((balanceA == 0))
475+ then true
476+ else (balanceB == 0))
477+ then throw("Can't exchange with zero balance")
478+ else if ((0 >= minAmountToReceive))
479+ then throw(("Minimal amount to receive must be positive. Actual: " + toString(minAmountToReceive)))
480+ else if ((size(i.payments) != 1))
481+ then throw("One attached payment expected")
482+ else if (!(hasEnoughBalance))
483+ then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
484+ else if ((pmtAssetId == assetIdA))
338485 then {
339- let assetIdSend = assetIdA
340- let $t01384313934 = calculateFees(balanceB, balanceA)
341- let amountWithoutFee = $t01384313934._1
342- let amountWithFee = $t01384313934._2
343- let governanceReward = $t01384313934._3
344- let newBalanceA = ((balanceA - amountWithFee) - governanceReward)
345- let newBalanceB = (balanceB + pmtAmount)
486+ let assetIdSend = assetIdB
487+ let $t02074620837 = calculateFees(balanceA, balanceB)
488+ let amountWithoutFee = $t02074620837._1
489+ let amountWithFee = $t02074620837._2
490+ let governanceReward = $t02074620837._3
491+ let newBalanceA = (balanceA + pmtAmount)
492+ let newBalanceB = ((balanceB - amountWithFee) - governanceReward)
346493 if (if ((stakedAmountA >= newBalanceA))
347494 then true
348495 else (stakedAmountB >= newBalanceB))
349- then throwInsufficientAvailableBalance(amountWithFee, availableBalanceA, assetNameA)
350- else [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(governanceAddress, governanceReward, assetIdSend)]
496+ then throwInsufficientAvailableBalance(amountWithFee, availableBalanceB, assetNameB)
497+ else [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(walletAddress, governanceReward, assetIdSend)]
351498 }
352- else throw(((("Incorrect asset attached. Expected: " + strAssetIdA) + " or ") + strAssetIdB))
499+ else if ((pmtAssetId == assetIdB))
500+ then {
501+ let assetIdSend = assetIdA
502+ let $t02165621747 = calculateFees(balanceB, balanceA)
503+ let amountWithoutFee = $t02165621747._1
504+ let amountWithFee = $t02165621747._2
505+ let governanceReward = $t02165621747._3
506+ let newBalanceA = ((balanceA - amountWithFee) - governanceReward)
507+ let newBalanceB = (balanceB + pmtAmount)
508+ if (if ((stakedAmountA >= newBalanceA))
509+ then true
510+ else (stakedAmountB >= newBalanceB))
511+ then throwInsufficientAvailableBalance(amountWithFee, availableBalanceA, assetNameA)
512+ else [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(walletAddress, governanceReward, assetIdSend)]
513+ }
514+ else throw(((("Incorrect asset attached. Expected: " + strAssetIdA) + " or ") + strAssetIdB))
353515 }
354516
355517
356518
357519 @Callable(i)
358520 func shutdown () = if (!(isActive))
359521 then throw(("DApp is already suspended. Cause: " + valueOrElse(getString(this, keyCause), "the cause wasn't specified")))
360522 else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStartStop], i.callerPublicKey)))
361523 then throw("Only admin can call this function")
362524 else suspend("Paused by admin")
363525
364526
365527
366528 @Callable(i)
367529 func activate () = if (isActive)
368530 then throw("DApp is already active")
369531 else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStartStop], i.callerPublicKey)))
370532 then throw("Only admin can call this function")
371533 else [BooleanEntry(keyActive, true), DeleteEntry(keyCause)]
372534
373535
374536
375537 @Callable(i)
376538 func takeIntoAccountExtraFunds (amountLeave) = {
377539 let uncountableAmountEnrollAssetA = (accountBalanceWithStakedA - balanceA)
378540 let uncountableAmountEnrollAssetB = (accountBalanceWithStakedB - balanceB)
379541 let amountEnrollA = (uncountableAmountEnrollAssetA - (if ((assetIdA == unit))
380542 then amountLeave
381543 else 0))
382544 let amountEnrollB = (uncountableAmountEnrollAssetB - (if ((assetIdB == unit))
383545 then amountLeave
384546 else 0))
385547 if (!(isActive))
386548 then throw("DApp is inactive at this moment")
387549 else if ((i.caller != this))
388550 then throw("Only the DApp itself can call this function")
389551 else if ((0 > amountLeave))
390552 then throw(("Argument 'amountLeave' cannot be negative. Actual: " + toString(amountLeave)))
391553 else if (if ((0 > uncountableAmountEnrollAssetA))
392554 then true
393555 else (0 > uncountableAmountEnrollAssetB))
394556 then suspend("Enroll amount negative")
395557 else if (if ((0 > amountEnrollA))
396558 then true
397559 else (0 > amountEnrollB))
398560 then throw("Too large amountLeave")
399561 else [IntegerEntry(keyBalanceA, (balanceA + amountEnrollA)), IntegerEntry(keyBalanceB, (balanceB + amountEnrollB)), IntegerEntry(("last_income_" + strAssetIdA), amountEnrollA), IntegerEntry(("last_income_" + strAssetIdB), amountEnrollB)]
400562 }
401563
402564
403565 @Verifier(tx)
404566 func verify () = {
405567 let multiSignedByAdmins = {
406568 let adminPubKey1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
407569 then 1
408570 else 0
409571 let adminPubKey2Signed = if (sigVerify(tx.bodyBytes, tx.proofs[1], adminPubKey2))
410572 then 1
411573 else 0
412574 let adminPubKey3Signed = if (sigVerify(tx.bodyBytes, tx.proofs[2], adminPubKey3))
413575 then 1
414576 else 0
415577 (((adminPubKey1Signed + adminPubKey2Signed) + adminPubKey3Signed) >= 2)
416578 }
417579 match tx {
418580 case inv: InvokeScriptTransaction =>
419- if (if (if (if (sigVerify(inv.bodyBytes, inv.proofs[0], adminPubKeyStaking))
420- then (inv.dApp == stakingAddressUSDN)
581+ let callTakeIntoAccount = if ((inv.dApp == this))
582+ then (inv.function == "takeIntoAccountExtraFunds")
583+ else false
584+ let callStaking = if (if ((inv.dApp == stakingUSDNNSBTAddress))
585+ then if (if (if ((inv.function == "lockNeutrino"))
586+ then (size(inv.payments) == 1)
587+ else false)
588+ then if ((inv.payments[0].assetId == USDN))
589+ then true
590+ else (inv.payments[0].assetId == NSBT)
591+ else false)
592+ then true
593+ else if ((inv.function == "unlockNeutrino"))
594+ then (size(inv.payments) == 0)
595+ else false
421596 else false)
422597 then true
423- else if (if (sigVerify(inv.bodyBytes, inv.proofs[0], adminPubKeyStaking))
424- then (inv.function == "exchange")
425- else false)
426- then if (if (if (if (if ((assetIdA == NSBT))
427- then (assetIdB == USDN)
598+ else if ((inv.dApp == stakingEURNAddress))
599+ then if (if (if ((inv.function == "startStaking"))
600+ then (size(inv.payments) == 1)
428601 else false)
429- then (inv.dApp == swopUSDNtoWAVES)
430- else false)
431- then (inv.payments[0].assetId == unit)
432- else false)
433- then if ((inv.payments[0].assetId == unit))
434- then true
435- else (inv.payments[0].assetId == USDN)
602+ then (inv.payments[0].assetId == EURN)
436603 else false)
437604 then true
438- else if (if ((assetIdA == NSBT))
439- then (assetIdB == SWOP)
440- else false)
441- then if (if ((inv.dApp == swopUSDNtoNSBT))
442- then (inv.payments[0].assetId == USDN)
443- else false)
444- then true
445- else if ((inv.dApp == swopUSDNtoWAVES))
446- then if ((inv.payments[0].assetId == unit))
447- then true
448- else (inv.payments[0].assetId == USDN)
449- else false
605+ else if ((inv.function == "stopStaking"))
606+ then (size(inv.payments) == 0)
450607 else false
608+ else false
609+ let exchangeToWaves = if (if (if ((inv.dApp == USDNToWavesExchanger))
610+ then (inv.function == "exchange")
611+ else false)
612+ then (assetIdA == USDN)
613+ else false)
614+ then true
615+ else if (if ((assetIdB == USDN))
616+ then (size(inv.payments) == 1)
451617 else false)
618+ then (inv.payments[0].assetId == USDN)
619+ else false
620+ let exchangeToNSBTs = if (if (if ((inv.dApp == USDNToNSBTExchanger))
621+ then (inv.function == "exchange")
622+ else false)
623+ then (assetIdA == NSBT)
624+ else false)
452625 then true
453- else if (if (sigVerify(inv.bodyBytes, inv.proofs[0], adminPubKeyStaking))
454- then (inv.dApp == this)
626+ else if (if ((assetIdB == NSBT))
627+ then (size(inv.payments) == 1)
455628 else false)
456- then (inv.function == "takeIntoAccountExtraFunds")
457- else false)
629+ then (inv.payments[0].assetId == USDN)
630+ else false
631+ let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
632+ then true
633+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey2))
634+ then true
635+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey3))
636+ then true
637+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKeyStaking)
638+ if (if (if (if (if (callTakeIntoAccount)
639+ then true
640+ else callStaking)
641+ then true
642+ else exchangeToWaves)
643+ then true
644+ else exchangeToNSBTs)
645+ then signedByAdmin
646+ else false)
458647 then true
459648 else multiSignedByAdmins
460649 case _ =>
461650 multiSignedByAdmins
462651 }
463652 }
464653

github/deemru/w8io/873ac7e 
75.59 ms