tx · 9aSC87Ub5LW2JueEeButiKuwbuDsotoggDtefnTXRfPs

3PPH7x7iqobW5ziyiRCic19rQqKr6nPYaK1:  -0.01400000 Waves

2022.01.14 13:15 [2943535] smart account 3PPH7x7iqobW5ziyiRCic19rQqKr6nPYaK1 > SELF 0.00000000 Waves

{ "type": 13, "id": "9aSC87Ub5LW2JueEeButiKuwbuDsotoggDtefnTXRfPs", "fee": 1400000, "feeAssetId": null, "timestamp": 1642154970109, "version": 2, "chainId": 87, "sender": "3PPH7x7iqobW5ziyiRCic19rQqKr6nPYaK1", "senderPublicKey": "5aTg4oxM77iRmUGy3y8Zavn5fhVbgtUciAuSGfCJAYjn", "proofs": [ "", "4KsgYbfWk1Gy2G6e48NprJe5NWHDdNmb83ByEVh41aD6HdbW7ueWRBn5XQw4Sqm9vi2BwZtSty1tq3EpVo6ujydK", "21b3Q9Wkcq4rfhdyJmss2RktuDtDGphVv8NmD1RTPXvbN798Avdiez5fyY48jRQjPpPHDmW9VU7wEUtEv3AVgxuD" ], "script": "base64:AAIFAAAAAAAAACYIAhIAEgMKAQESBAoCAQESABIECgIBARIAEgASABIFCgMEAQgSAAAAAFEAAAAAB3ZlcnNpb24CAAAABTIuMC4wAAAAAAhrVmVyc2lvbgIAAAAHdmVyc2lvbgAAAAAHa0FjdGl2ZQIAAAAGYWN0aXZlAAAAAAlrQXNzZXRJZEECAAAACkFfYXNzZXRfaWQAAAAACWtBc3NldElkQgIAAAAKQl9hc3NldF9pZAAAAAAJa0JhbGFuY2VBAgAAAA9BX2Fzc2V0X2JhbGFuY2UAAAAACWtCYWxhbmNlQgIAAAAPQl9hc3NldF9iYWxhbmNlAAAAAA1rU2hhcmVBc3NldElkAgAAAA5zaGFyZV9hc3NldF9pZAAAAAARa1NoYXJlQXNzZXRTdXBwbHkCAAAAEnNoYXJlX2Fzc2V0X3N1cHBseQAAAAAEa0ZlZQIAAAAKY29tbWlzc2lvbgAAAAASa0ZlZVNjYWxlRGVsaW1pdGVyAgAAABpjb21taXNzaW9uX3NjYWxlX2RlbGltaXRlcgAAAAAKa0ludmFyaWFudAIAAAAJaW52YXJpYW50AAAAAAZrQ2F1c2UCAAAADnNodXRkb3duX2NhdXNlAAAAABJrZXlVU0ROTlNCVEFkZHJlc3MCAAAAGHN0YWtpbmdfdXNkbm5zYnRfYWRkcmVzcwAAAAAOa2V5RVVSTkFkZHJlc3MCAAAAFHN0YWtpbmdfZXVybl9hZGRyZXNzAAAAAA9rZXlBZG1pblB1YktleTECAAAAC2FkbWluX3B1Yl8xAAAAAA9rZXlBZG1pblB1YktleTICAAAAC2FkbWluX3B1Yl8yAAAAAA9rZXlBZG1pblB1YktleTMCAAAAC2FkbWluX3B1Yl8zAAAAABRVU0ROVG9XYXZlc0V4Y2hhbmdlcgkBAAAAB0FkZHJlc3MAAAABAQAAABoBV6ugnY67/HaJPzVO8b2xSyoDl1hFH8eK8wAAAAAGb3JhY2xlCQEAAAAHQWRkcmVzcwAAAAEBAAAAGgFXiv8IaJo1ukDNYXTyEjfepjfw+jjO6B44AQAAAAtnZXRBZG1pblB1YgAAAAEAAAALa2V5QWRtaW5QdWIEAAAAByRtYXRjaDAJAAQdAAAAAgUAAAAGb3JhY2xlBQAAAAtrZXlBZG1pblB1YgMJAAABAAAAAgUAAAAH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AA1zbGlwcGFnZVZhbHVlCQAAZQAAAAIFAAAABnNjYWxlOAkAAGkAAAACCQAAaAAAAAIFAAAABnNjYWxlOAAAAAAAAAAAAQAAAAAAAJiWgAQAAAAeZGVsdGFCZXR3ZWVuTWF4QW5kTWluU2VuZFZhbHVlCQAAZQAAAAIFAAAAFWFtb3VudFRvU2VuZEVzdGltYXRlZAUAAAAVbWluVG9rZW5SZWNlaXZlQW1vdW50BAAAAAF4CQAAZAAAAAIFAAAACGJhbGFuY2VBBQAAABJ0b2tlblJlY2VpdmVBbW91bnQEAAAAAXkJAABkAAAAAgUAAAAIYmFsYW5jZUIFAAAAEnRva2VuUmVjZWl2ZUFtb3VudAQAAAAMaW52YXJpYW50TmV3AwkAAAAAAAACBQAAAAd0b2tlbklkBQAAAAhhc3NldElkQQkBAAAADWludmFyaWFudENhbGMAAAACBQAAAAF4CQAAZQAAAAIFAAAACGJhbGFuY2VCBQAAABVhbW91bnRUb1NlbmRFc3RpbWF0ZWQDCQAAAAAAAAIFAAAAB3Rva2VuSWQFAAAACGFzc2V0SWRCCQEAAAANaW52YXJpYW50Q2FsYwAAAAIJAABlAAAAAgUAAAAIYmFsYW5jZUEFAAAAFWFtb3VudFRvU2VuZEVzdGltYXRlZAUAAAABeQkAAAIAAAABAgAAABZXcm9uZyBhc3NldCBpbiBwYXltZW50BAAAABdpbnZhcmlhbnRFc3RpbWF0ZWRSYXRpbwkAAGsAAAADBQAAAAZzY2FsZTgFAAAACWludmFyaWFudAUAAAAMaW52YXJpYW50TmV3CgEAAAANZ2V0U3RlcEFtb3VudAAAAAIAAAADYWNjAAAABHN0ZXADCQAAAAAAAAIFAAAAA2FjYwD//////////wQAAAAMYW1vdW50VG9TZW5kCQAAZQAAAAIFAAAAFWFtb3VudFRvU2VuZEVzdGltYXRlZAkAAGkAAAACCQAAaAAAAAIFAAAABHN0ZXAFAAAAHmRlbHRhQmV0d2Vlbk1heEFuZE1pblNlbmRWYWx1ZQAAAAAAAAAABQQAAAANc3RlcEludmFyaWFudAMJAAAAAAAAAgUAAAAHdG9rZW5JZAUAAAAIYXNzZXRJZEEJAQAAAA1pbnZhcmlhbnRDYWxjAAAAAgUAAAABeAkAAGUAAAACBQAA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bnRlZ2VyRW50cnkAAAACBQAAABFrU2hhcmVBc3NldFN1cHBseQUAAAASc2hhcmVJbml0aWFsU3VwcGx5CQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAASc2hhcmVJbml0aWFsU3VwcGx5BQAAAAxzaGFyZUlzc3VlSWQFAAAAA25pbAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAAAAAWkBAAAAFnJlcGxlbmlzaFdpdGhUd29Ub2tlbnMAAAABAAAAEXNsaXBwYWdlVG9sZXJhbmNlBAAAAAtwbXRBc3NldElkQQgJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAAAAAHYXNzZXRJZAQAAAALcG10QXNzZXRJZEIICQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAABAAAAB2Fzc2V0SWQEAAAACnBtdEFtb3VudEEICQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAAAAAABmFtb3VudAQAAAAKcG10QW1vdW50QggJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAEAAAAGYW1vdW50BAAAAA0kdDAxMTkyMjExOTk5CQEAAAAMZ2V0QXNzZXRJbmZvAAAAAQUAAAALcG10QXNzZXRJZEEEAAAADnBtdFN0ckFzc2V0SWRBCAUAAAANJHQwMTE5MjIxMTk5OQAAAAJfMQQAAAANcG10QXNzZXROYW1lQQgFAAAADSR0MDExOTIyMTE5OTkAAAACXzIEAAAADHBtdERlY2ltYWxzQQgFAAAADSR0MDExOTIyMTE5OTkAAAACXzMEAAAADSR0MDEyMDA0MTIxOTgJAQAAAAxnZXRBc3NldEluZm8AAAABBQAAAAtwbXRBc3NldElkQgQAAAAOcG10U3RyQXNzZXRJZEIIBQAAAA0kdDAxMjAwNDEyMTk4AAAAAl8xBAAAAA1wbXRBc3NldE5hbWVCCAUAAAANJHQwMTIwMDQxMjE5OAAAAAJfMgQAAAAMcG10RGVjaW1hbHNCCAUAAAANJHQwMTIwMDQxMjE5OAAAAAJfMwQAAAAKdG9rZW5SYXRpbwkAAGsAAAADCQAAawAAAAMFAAAABnNjYWxlOAUAAAAIYmFsYW5jZUEFAAAACnBtdEFtb3VudEEFAAAABnNjYWxlMwkAAGsAAAADBQAAAAZzY2FsZTgFAAAACGJhbGFuY2VCBQAAAApwbXRBbW91bnRCBAAAABNyYXRpb1NoYXJlVG9rZW5zSW5BCQAAawAAAAMFAAAABnNjYWxlOAUAAAAKcG10QW1vdW50QQUAAAAIYmFsYW5jZUEEAAAAE3JhdGlvU2hhcmVUb2tlbnNJbkIJAABrAAAAAwUAAAAGc2NhbGU4BQAAAApwbXRBbW91bnRCBQAAAAhiYWxhbmNlQgQAAAAVc2hhcmVUb2tlblRvUGF5QW1vdW50CQAAawAAAAMJAAGXAAAAAQkABEwAAAACBQAAABNyYXRpb1NoYXJlVG9rZW5zSW5BCQAETAAAAAIFAAAAE3JhdGlvU2hhcmVUb2tlbnNJbkIFAAAAA25pbAUAAAAQc2hhcmVBc3NldFN1cHBseQUAAAAGc2NhbGU4BAAAABNpbnZhcmlhbnRDYWxjdWxhdGVkCQEAAAANaW52YXJpYW50Q2FsYwAAAAIJAABkAAAAAgUAAAAIYmFsYW5jZUEFAAAACnBtdEFtb3VudEEJAABkAAAAAgUAAAAIYmFsYW5jZUIFAAAACnBtdEFtb3VudEIDCQEAAAABIQAAAAEFAAAACGlzQWN0aXZlCQEAAAAPdGhyb3dJc0luYWN0aXZlAAAAAAMDCQAAZgAAAAIAAAAAAAAAAAAFAAAAEXNsaXBwYWdlVG9sZXJhbmNlBgkAAGYAAAACBQAAABFzbGlwcGFnZVRvbGVyYW5jZQAAAAAAAAAACgkAAAIAAAABAgAAACBTbGlwcGFnZSB0b2xlcmFuY2UgbXVzdCBiZSA8PSAxJQMJAQAAAAIhPQAAAAIJAAGQAAAAAQgFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAIJAAACAAAAAQIAAAAcVHdvIGF0dGFjaGVkIGFzc2V0cyBleHBlY3RlZAMDCQEAAAACIT0AAAACBQAAAAtwbXRBc3NldElkQQUAAAAIYXNzZXRJZEEGCQEAAAACIT0AAAACBQAAAAtwbXRBc3NldElkQgUAAAAIYXNzZXRJZEIJAQAAAAt0aHJvd0Fzc2V0cwAAAAADAwkAAGYAAAACCQAAaQAAAAIJAABoAAAAAgUAAAAGc2NhbGUzCQAAZQAAAAIFAAAADnNsaXBwYWdlU2NhbGUzBQAAABFzbGlwcGFnZVRvbGVyYW5jZQUAAAAOc2xpcHBhZ2VTY2FsZTMFAAAACnRva2VuUmF0aW8GCQAAZgAAAAIFAAAACnRva2VuUmF0aW8JAABpAAAAAgkAAGgAAAACBQAAAAZzY2FsZTMJAABkAAAAAgUAAAAOc2xpcHBhZ2VTY2FsZTMFAAAAEXNsaXBwYWdlVG9sZXJhbmNlBQAAAA5zbGlwcGFnZVNjYWxlMwkAAAIAAAABAgAAAD1JbmNvcnJlY3QgYXNzZXRzIGFtb3VudDogYW1vdW50cyBtdXN0IGhhdmUgdGhlIGNvbnRyYWN0IHJhdGlvAwkAAAAAAAACBQAAABVzaGFyZVRva2VuVG9QYXlBbW91bnQAAAAAAAAAAAAJAAACAAAAAQIAAAAdVG9vIHNtYWxsIGFtb3VudCB0byByZXBsZW5pc2gDCQEAAAABIQAAAAEFAAAAEGhhc0Vub3VnaEJhbGFuY2UJAAROAAAAAgkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIFAAAACnBtdEFtb3VudEEFAAAAC3BtdEFzc2V0SWRBCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAAKcG10QW1vdW50QgUAAAALcG10QXNzZXRJZEIFAAAAA25pbAkBAAAAEXN1c3BlbmRTdXNwaWNpb3VzAAAAAAQAAAAGc3Rha2UxAwkBAAAAD2NvbnRhaW5zRWxlbWVudAAAAAIFAAAADXN0YWtpbmdBc3NldHMFAAAADnBtdFN0ckFzc2V0SWRBCQAD/AAAAAQFAAAABHRoaXMCAAAADHN0YWtlVW5zdGFrZQkABEwAAAACBgkABEwAAAACBQAAAApwbXRBbW91bnRBCQAETAAAAAIFAAAADnBtdFN0ckFzc2V0SWRBBQAAAANuaWwFAAAAA25pbAAAAAAAAAAAAAMJAAAAAAAAAgUAAAAGc3Rha2UxBQAAAAZzdGFrZTEEAAAABnN0YWtlMgMJAQAAAA9jb250YWluc0VsZW1lbnQAAAACBQAAAA1zdGFraW5nQXNzZXRzBQAAAA5wbXRTdHJBc3NldElkQgkAA/wAAAAEBQAAAAR0aGlzAgAAAAxzdGFrZVVuc3Rha2UJAARMAAAAAgYJAARMAAAAAgUAAAAKcG10QW1vdW50QgkABEwAAAACBQAAAA5wbXRTdHJBc3NldElkQgUAAAADbmlsBQAAAANuaWwAAAAAAAAAAAADCQAAAAAAAAIFAAAABnN0YWtlMgUAAAAGc3Rha2UyCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAlrQmFsYW5jZUEJAABkAAAAAgUAAAAIYmFsYW5jZUEFAAAACnBtdEFtb3VudEEJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAACWtCYWxhbmNlQgkAAGQAAAACBQAAAAhiYWxhbmNlQgUAAAAKcG10QW1vdW50QgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAARa1NoYXJlQXNzZXRTdXBwbHkJAABkAAAAAgUAAAAQc2hhcmVBc3NldFN1cHBseQUAAAAVc2hhcmVUb2tlblRvUGF5QW1vdW50CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAprSW52YXJpYW50BQAAABNpbnZhcmlhbnRDYWxjdWxhdGVkCQAETAAAAAIJAQAAAAdSZWlzc3VlAAAAAwUAAAAMc2hhcmVBc3NldElkBQAAABVzaGFyZVRva2VuVG9QYXlBbW91bnQGCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAAVc2hhcmVUb2tlblRvUGF5QW1vdW50BQAAAAxzaGFyZUFzc2V0SWQFAAAAA25pbAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAAAAAWkBAAAAFXJlcGxlbmlzaFdpdGhPbmVUb2tlbgAAAAIAAAATdmlydHVhbFN3YXBUb2tlblBheQAAABN2aXJ0dWFsU3dhcFRva2VuR2V0BAAAAA0kdDAxNDQ5NzE0NTcyCQAFFAAAAAIICQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAAAAAABmFtb3VudAgJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAAAAAHYXNzZXRJZAQAAAAJcG10QW1vdW50CAUAAAANJHQwMTQ0OTcxNDU3MgAAAAJfMQQAAAAKcG10QXNzZXRJZAgFAAAADSR0MDE0NDk3MTQ1NzIAAAACXzIEAAAADSR0MDE0NTc3MTQ2NTAJAQAAAAxnZXRBc3NldEluZm8AAAABBQAAAApwbXRBc3NldElkBAAAAA1wbXRTdHJBc3NldElkCAUAAAANJHQwMTQ1NzcxNDY1MAAAAAJfMQQAAAAMcG10QXNzZXROYW1lCAUAAAANJHQwMTQ1NzcxNDY1MAAAAAJfMgQAAAALcG10RGVjaW1hbHMIBQAAAA0kdDAxNDU3NzE0NjUwAAAAAl8zBAAAAA9wbXRNaW5UaHJlc2hvbGQAAAAAAABMS0AEAAAAHXRocmVzaG9sZFZhbHVlRm9yTWluVG9sZXJhbmNlAAAAAAAC+vCABAAAAAl0b2xlcmFuY2UDCQAAZgAAAAIFAAAAHXRocmVzaG9sZFZhbHVlRm9yTWluVG9sZXJhbmNlBQAAAAlwbXRBbW91bnQAAAAAAAABhqAAAAAAAAAAAAEEAAAAHHNsaXBwYWdlVmFsdWVNaW5Gb3JSZXBsZW5pc2gJAABlAAAAAgUAAAAGc2NhbGU4CQAAaQAAAAIJAABoAAAAAgUAAAAGc2NhbGU4BQAAAAl0b2xlcmFuY2UAAAAAAACYloAEAAAAHHNsaXBwYWdlVmFsdWVNYXhGb3JSZXBsZW5pc2gJAABkAAAAAgUAAAAGc2NhbGU4CQAAaQAAAAIJAABoAAAAAgUAAAAGc2NhbGU4BQAAAAl0b2xlcmFuY2UAAAAAAACYloAEAAAAF3NsaXBwYWdlVmFsdWVNaW5Gb3JTd2FwCQAAZQAAAAIFAAAABnNjYWxlOAkAAGkAAAACCQAAaAAAAAIFAAAABnNjYWxlOAAAAAAAAAAAAQAAAAAAAJiWgAMJAQAAAAEhAAAAAQUAAAAIaXNBY3RpdmUJAQAAAA90aHJvd0lzSW5hY3RpdmUAAAAAAwkAAGYAAAACBQAAAA9wbXRNaW5UaHJlc2hvbGQFAAAACXBtdEFtb3VudAkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAD1BheW1lbnQgYW1vdW50IAkAAaQAAAABBQAAAAlwbXRBbW91bnQCAAAAJyBkb2VzIG5vdCBleGNlZWQgdGhlIG1pbmltdW0gYW1vdW50IG9mIAkAAaQAAAABBQAAAA9wbXRNaW5UaHJlc2hvbGQCAAAAByB0b2tlbnMDCQEAAAACIT0AAAACCQABkAAAAAEIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAABCQAAAgAAAAECAAAAHU9uZSBhdHRhY2hlZCBwYXltZW50IGV4cGVjdGVkAwkBAAAAASEAAAABBQAAABBoYXNFbm91Z2hCYWxhbmNlCQAETgAAAAIJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAAAlwbXRBbW91bnQFAAAACnBtdEFzc2V0SWQFAAAAA25pbAkBAAAAEXN1c3BlbmRTdXNwaWNpb3VzAAAAAAMDCQEAAAACIT0AAAACBQAAAApwbXRBc3NldElkBQAAAAhhc3NldElkQQkBAAAAAiE9AAAAAgUAAAAKcG10QXNzZXRJZAUAAAAIYXNzZXRJZEIHCQEAAAALdGhyb3dBc3NldHMAAAAABAAAAA0kdDAxNTY2MjE2NDI3AwkAAAAAAAACBQAAAApwbXRBc3NldElkBQAAAAhhc3NldElkQQkABRkAAAAHCQAAZQAAAAIFAAAACXBtdEFtb3VudAUAAAATdmlydHVhbFN3YXBUb2tlblBheQUAAAATdmlydHVhbFN3YXBUb2tlbkdldAkAAGQAAAACBQAAAAhiYWxhbmNlQQUAAAATdmlydHVhbFN3YXBUb2tlblBheQkAAGUAAAACBQAAAAhiYWxhbmNlQgUAAAATdmlydHVhbFN3YXBUb2tlbkdldAkBAAAADWludmFyaWFudENhbGMAAAACCQAAZAAAAAIFAAAACGJhbGFuY2VBBQAAAAlwbXRBbW91bnQFAAAACGJhbGFuY2VCCQAAZAAAAAIFAAAACGJhbGFuY2VBBQAAAAlwbXRBbW91bnQFAAAACGJhbGFuY2VCCQAFGQAAAAcFAAAAE3ZpcnR1YWxTd2FwVG9rZW5HZXQJAABlAAAAAgUAAAAJcG10QW1vdW50BQAAABN2aXJ0dWFsU3dhcFRva2VuUGF5CQAAZQAAAAIFAAAACGJhbGFuY2VBBQAAABN2aXJ0dWFsU3dhcFRva2VuR2V0CQAAZAAAAAIFAAAACGJhbGFuY2VCBQAAABN2aXJ0dWFsU3dhcFRva2VuUGF5CQEAAAANaW52YXJpYW50Q2FsYwAAAAIFAAAACGJhbGFuY2VBCQAAZAAAAAIFAAAACGJhbGFuY2VCBQAAAAlwbXRBbW91bnQFAAAACGJhbGFuY2VBCQAAZAAAAAIFAAAACGJhbGFuY2VCBQAAAAlwbXRBbW91bnQEAAAAEXZpcnR1YWxSZXBsZW5pc2hBCAUAAAANJHQwMTU2NjIxNjQyNwAAAAJfMQQAAAARdmlydHVhbFJlcGxlbmlzaEIIBQAAAA0kdDAxNTY2MjE2NDI3AAAAAl8yBAAAABFiYWxhbmNlQWZ0ZXJTd2FwQQgFAAAADSR0MDE1NjYyMTY0MjcAAAACXzMEAAAAEWJhbGFuY2VBZnRlclN3YXBCCAUAAAANJHQwMTU2NjIxNjQyNwAAAAJfNAQAAAATaW52YXJpYW50Q2FsY3VsYXRlZAgFAAAADSR0MDE1NjYyMTY0MjcAAAACXzUEAAAAC25ld0JhbGFuY2VBCAUAAAANJHQwMTU2NjIxNjQyNwAAAAJfNgQAAAALbmV3QmFsYW5jZUIIBQAAAA0kdDAxNTY2MjE2NDI3AAAAAl83BAAAAA9uZXdCYWxhbmNlRW50cnkDCQAAAAAAAAIFAAAACnBtdEFzc2V0SWQFAAAACGFzc2V0SWRBCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAJa0JhbGFuY2VBBQAAAAtuZXdCYWxhbmNlQQkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAACWtCYWxhbmNlQgUAAAALbmV3QmFsYW5jZUIEAAAADGludmFyaWFudE5ldwkBAAAADWludmFyaWFudENhbGMAAAACBQAAABFiYWxhbmNlQWZ0ZXJTd2FwQQUAAAARYmFsYW5jZUFmdGVyU3dhcEIEAAAAF2ludmFyaWFudEVzdGltYXRlZFJhdGlvCQAAawAAAAMFAAAABnNjYWxlOAUAAAAJaW52YXJpYW50BQAAAAxpbnZhcmlhbnROZXcEAAAAJXJhdGlvVmlydHVhbEJhbGFuY2VUb1ZpcnR1YWxSZXBsZW5pc2gJAABpAAAAAgkAAGsAAAADCQAAaAAAAAIFAAAABnNjYWxlOAUAAAAGc2NhbGU4BQAAABFiYWxhbmNlQWZ0ZXJTd2FwQQUAAAARYmFsYW5jZUFmdGVyU3dhcEIJAABrAAAAAwUAAAAGc2NhbGU4BQAAABF2aXJ0dWFsUmVwbGVuaXNoQQUAAAARdmlydHVhbFJlcGxlbmlzaEIEAAAAE2RBcHBUaHJlc2hvbGRBbW91bnQJAABrAAAAAwkAAGQAAAACBQAAAAtuZXdCYWxhbmNlQQUAAAALbmV3QmFsYW5jZUIFAAAADWRBcHBUaHJlc2hvbGQJAABoAAAAAgAAAAAAAAAAAgUAAAATZEFwcFRocmVzaG9sZFNjYWxlMgMDCQAAZwAAAAIFAAAAF3NsaXBwYWdlVmFsdWVNaW5Gb3JTd2FwBQAAABdpbnZhcmlhbnRFc3RpbWF0ZWRSYXRpbwYJAABmAAAAAgUAAAAJaW52YXJpYW50BQAAAAxpbnZhcmlhbnROZXcJAAACAAAAAQIAAAA6SW5jb3JyZWN0IHZpcnR1YWxTd2FwVG9rZW5QYXkgb3IgdmlydHVhbFN3YXBUb2tlbkdldCB2YWx1ZQMDCQAAZgAAAAIFAAAAHHNsaXBwYWdlVmFsdWVNaW5Gb3JSZXBsZW5pc2gFAAAAJXJhdGlvVmlydHVhbEJhbGFuY2VUb1ZpcnR1YWxSZXBsZW5pc2gGCQAAZgAAAAIFAAAAJXJhdGlvVmlydHVhbEJhbGFuY2VUb1ZpcnR1YWxSZXBsZW5pc2gFAAAAHHNsaXBwYWdlVmFsdWVNYXhGb3JSZXBsZW5pc2gJAAACAAAAAQIAAABsU3dhcCB3aXRoIHZpcnR1YWxTd2FwVG9rZW5QYXkgYW5kIHZpcnR1YWxTd2FwVG9rZW5HZXQgaXMgcG9zc2libGUsIGJ1dCByYXRpbyBhZnRlciB2aXJ0dWFsIHN3YXAgaXMgaW5jb3JyZWN0AwMJAABmAAAAAgUAAAATZEFwcFRocmVzaG9sZEFtb3VudAUAAAALbmV3QmFsYW5jZUEGCQAAZgAAAAIFAAAAE2RBcHBUaHJlc2hvbGRBbW91bnQFAAAAC25ld0JhbGFuY2VCCQEAAAAOdGhyb3dUaHJlc2hvbGQAAAADBQAAABNkQXBwVGhyZXNob2xkQW1vdW50BQAAAAtuZXdCYWxhbmNlQQUAAAALbmV3QmFsYW5jZUIEAAAABnN0YWtlMQMJAQAAAA9jb250YWluc0VsZW1lbnQAAAACBQAAAA1zdGFraW5nQXNzZXRzBQAAAA1wbXRTdHJBc3NldElkCQAD/AAAAAQFAAAABHRoaXMCAAAADHN0YWtlVW5zdGFrZQkABEwAAAACBgkABEwAAAACBQAAAAlwbXRBbW91bnQJAARMAAAAAgUAAAANcG10U3RyQXNzZXRJZAUAAAADbmlsBQAAAANuaWwAAAAAAAAAAAADCQAAAAAAAAIFAAAABnN0YWtlMQUAAAAGc3Rha2UxBAAAABNyYXRpb1NoYXJlVG9rZW5zSW5BCQAAawAAAAMFAAAAEXZpcnR1YWxSZXBsZW5pc2hBBQAAAAZzY2FsZTgFAAAAEWJhbGFuY2VBZnRlclN3YXBBBAAAABNyYXRpb1NoYXJlVG9rZW5zSW5CCQAAawAAAAMFAAAAEXZpcnR1YWxSZXBsZW5pc2hCBQAAAAZzY2FsZTgFAAAAEWJhbGFuY2VBZnRlclN3YXBCBAAAABVzaGFyZVRva2VuVG9QYXlBbW91bnQJAABrAAAAAwkAAZcAAAABCQAETAAAAAIFAAAAE3JhdGlvU2hhcmVUb2tlbnNJbkEJAARMAAAAAgUAAAATcmF0aW9TaGFyZVRva2Vuc0luQgUAAAADbmlsBQAAABBzaGFyZUFzc2V0U3VwcGx5BQAAAAZzY2FsZTgJAARMAAAAAgkBAAAAB1JlaXNzdWUAAAADBQAAAAxzaGFyZUFzc2V0SWQFAAAAFXNoYXJlVG9rZW5Ub1BheUFtb3VudAYJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAABVzaGFyZVRva2VuVG9QYXlBbW91bnQFAAAADHNoYXJlQXNzZXRJZAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAARa1NoYXJlQXNzZXRTdXBwbHkJAABkAAAAAgUAAAAQc2hhcmVBc3NldFN1cHBseQUAAAAVc2hhcmVUb2tlblRvUGF5QW1v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AAprSW52YXJpYW50BQAAABNpbnZhcmlhbnRDYWxjdWxhdGVkCQAETAAAAAIJAQAAAARCdXJuAAAAAgUAAAAMc2hhcmVBc3NldElkBQAAAAlwbXRBbW91bnQJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAAAxhbW91bnRUb1BheUEFAAAACGFzc2V0SWRBCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAAMYW1vdW50VG9QYXlCBQAAAAhhc3NldElkQgUAAAADbmlsCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAAABaQEAAAAIZXhjaGFuZ2UAAAACAAAAGGVzdGltYXRlZEFtb3VudFRvUmVjZWl2ZQAAABJtaW5BbW91bnRUb1JlY2VpdmUEAAAADSR0MDIwMzEwMjAzODUJAAUUAAAAAggJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAAAAAGYW1vdW50CAkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAdhc3NldElkBAAAAAlwbXRBbW91bnQIBQAAAA0kdDAyMDMxMDIwMzg1AAAAAl8xBAAAAApwbXRBc3NldElkCAUAAAANJHQwMjAzMTAyMDM4NQAAAAJfMgMJAQAAAAEhAAAAAQUAAAAIaXNBY3RpdmUJAQAAAA90aHJvd0lzSW5hY3RpdmUAAAAAAwkAAGcAAAACAAAAAAAAAAAABQAAABhlc3RpbWF0ZWRBbW91bnRUb1JlY2VpdmUJAAACAAAAAQkAASwAAAACAgAAACtFc3RpbWF0ZWQgYW1vdW50IG11c3QgYmUgcG9zaXRpdmUuIEFjdHVhbDogCQABpAAAAAEFAAAAGGVzdGltYXRlZEFtb3VudFRvUmVjZWl2ZQMJAABmAAAAAgUAAAASbWluQW1vdW50VG9SZWNlaXZlBQAAABhlc3RpbWF0ZWRBbW91bnRUb1JlY2VpdmUJAAACAAAAAQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAA7TWluaW1hbCBhbW91bnQgY2FuJ3QgYmUgZ3JlYXRlciB0aGFuIGVzdGltYXRlZC4gRXN0aW1hdGVkOiAJAAGkAAAAAQUAAAAYZXN0aW1hdGVkQW1vdW50VG9SZWNlaXZlAgAAAAsuIE1pbmltYWw6IAkAAaQAAAABBQAAABJtaW5BbW91bnRUb1JlY2VpdmUDCQEAAAACIT0AAAACCQABkAAAAAEIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAABCQAAAgAAAAECAAAAHU9uZSBhdHRhY2hlZCBwYXltZW50IGV4cGVjdGVkAwkBAAAAASEAAAABBQAAABBoYXNFbm91Z2hCYWxhbmNlCQAETgAAAAIJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAAAlwbXRBbW91bnQFAAAACnBtdEFzc2V0SWQFAAAAA25pbAkBAAAAEXN1c3BlbmRTdXNwaWNpb3VzAAAAAAMDCQEAAAACIT0AAAACBQAAAApwbXRBc3NldElkBQAAAAhhc3NldElkQQkBAAAAAiE9AAAAAgUAAAAKcG10QXNzZXRJZAUAAAAIYXNzZXRJZEIHCQEAAAALdGhyb3dBc3NldHMAAAAAAwkAAGYAAAACAAAAAAAAmJaABQAAAAlwbXRBbW91bnQJAAACAAAAAQIAAAAwT25seSBzd2FwIG9mIDEwLjAwMDAwMCBvciBtb3JlIHRva2VucyBpcyBhbGxvd2VkAwMJAABmAAAAAgUAAAAVZXhjaGFuZ2VSYXRpb0xpbWl0TWluCQAAawAAAAMFAAAABnNjYWxlOAUAAAASbWluQW1vdW50VG9SZWNlaXZlBQAAAAlwbXRBbW91bnQGCQAAZgAAAAIJAABrAAAAAwUAAAAGc2NhbGU4BQAAABhlc3RpbWF0ZWRBbW91bnRUb1JlY2VpdmUFAAAACXBtdEFtb3VudAUAAAAVZXhjaGFuZ2VSYXRpb0xpbWl0TWF4CQAAAgAAAAECAAAAHEluY29ycmVjdCBhcmdzIGFuZCBwbXQgcmF0aW8EAAAAC3NlbmRBc3NldElkAwkAAAAAAAACBQAAAApwbXRBc3NldElkBQAAAAhhc3NldElkQQUAAAAIYXNzZXRJZEIFAAAACGFzc2V0SWRBBAAAAAZhbW91bnQJAQAAABNjYWxjdWxhdGVTZW5kQW1vdW50AAAABAUAAAAYZXN0aW1hdGVkQW1vdW50VG9SZWNlaXZlBQAAABJtaW5BbW91bnRUb1JlY2VpdmUFAAAACXBtdEFtb3VudAUAAAAKcG10QXNzZXRJZAQAAAAQZ292ZXJuYW5jZVJld2FyZAkAAGsAAAADBQAAAAZhbW91bnQFAAAADWZlZUdvdmVybmFuY2UFAAAACWZlZVNjYWxlNgQAAAAOYW1vdW50TWludXNGZWUJAABrAAAAAwUAAAAGYW1vdW50CQAAZQAAAAIFAAAACWZlZVNjYWxlNgUAAAADZmVlBQAAAAlmZWVTY2FsZTYEAAAADSR0MDIxODA3MjIwNjkDCQAAAAAAAAIFAAAACnBtdEFzc2V0SWQFAAAACGFzc2V0SWRBCQAFFAAAAAIJAABkAAAAAgUAAAAIYmFsYW5jZUEFAAAACXBtdEFtb3VudAkAAGUAAAACCQAAZQAAAAIFAAAACGJhbGFuY2VCBQAAAA5hbW91bnRNaW51c0ZlZQUAAAAQZ292ZXJuYW5jZVJld2FyZAkABRQAAAACCQAAZQAAAAIJAABlAAAAAgUAAAAIYmFsYW5jZUEFAAAADmFtb3VudE1pbnVzRmVlBQAAABBnb3Zlcm5hbmNlUmV3YXJkCQAAZAAAAAIFAAAACGJhbGFuY2VCBQAAAAlwbXRBbW91bnQEAAAAC25ld0JhbGFuY2VBCAUAAAANJHQwMjE4MDcyMjA2OQAAAAJfMQQAAAALbmV3QmFsYW5jZUIIBQAAAA0kdDAyMTgwNzIyMDY5AAAAAl8yBAAAABNkQXBwVGhyZXNob2xkQW1vdW50CQAAawAAAAMJAABkAAAAAgUAAAALbmV3QmFsYW5jZUEFAAAAC25ld0JhbGFuY2VCBQAAAA1kQXBwVGhyZXNob2xkCQAAaAAAAAIAAAAAAAAAAAIFAAAAE2RBcHBUaHJlc2hvbGRTY2FsZTIDAwkAAGYAAAACBQAAABNkQXBwVGhyZXNob2xkQW1vdW50BQAAAAtuZXdCYWxhbmNlQQYJAABmAAAAAgUAAAATZEFwcFRocmVzaG9sZEFtb3VudAUAAAALbmV3QmFsYW5jZUIJAQAAAA50aHJvd1RocmVzaG9sZAAAAAMFAAAAE2RBcHBUaHJlc2hvbGRBbW91bnQFAAAAC25ld0JhbGFuY2VBBQAAAAtuZXdCYWxhbmNlQgQAAAANJHQwMjIzNjcyMjQ0MAkBAAAADGdldEFzc2V0SW5mbwAAAAEFAAAACnBtdEFzc2V0SWQEAAAADXBtdFN0ckFzc2V0SWQIBQAAAA0kdDAyMjM2NzIyNDQwAAAAAl8xBAAAAAxwbXRBc3NldE5hbWUIBQAAAA0kdDAyMjM2NzIyNDQwAAAAAl8yBAAAAAtwbXREZWNpbWFscwgFAAAADSR0MDIyMzY3MjI0NDAAAAACXzMEAAAADSR0MDIyNDUzMjI1MzAJAQAAAAxnZXRBc3NldEluZm8AAAABBQAAAAtzZW5kQXNzZXRJZAQAAAAOc2VuZFN0ckFzc2V0SWQIBQAAAA0kdDAyMjQ1MzIyNTMwAAAAAl8xBAAAAA1zZW5kQXNzZXROYW1lCAUAAAANJHQwMjI0NTMyMjUzMAAAAAJfMgQAAAAMc2VuZERlY2ltYWxzCAUAAAANJHQwMjI0NTMyMjUzMAAAAAJfMwQAAAAGc3Rha2UxAwkBAAAAD2NvbnRhaW5zRWxlbWVudAAAAAIFAAAADXN0YWtpbmdBc3NldHMFAAAADXBtdFN0ckFzc2V0SWQJAAP8AAAABAUAAAAEdGhpcwIAAAAMc3Rha2VVbnN0YWtlCQAETAAAAAIGCQAETAAAAAIFAAAACXBtdEFtb3VudAkABEwAAAACBQAAAA1wbXRTdHJBc3NldElkBQAAAANuaWwFAAAAA25pbAAAAAAAAAAAAAMJAAAAAAAAAgUAAAAGc3Rha2UxBQAAAAZzdGFrZTEEAAAABnN0YWtlMgMJAQAAAA9jb250YWluc0VsZW1lbnQAAAACBQAAAA1zdGFraW5nQXNzZXRzBQAAAA5zZW5kU3RyQXNzZXRJZAkAA/wAAAAEBQAAAAR0aGlzAgAAAAxzdGFrZVVuc3Rha2UJAARMAAAAAgcJAARMAAAAAgkAAGQAAAACBQAAAA5hbW91bnRNaW51c0ZlZQUAAAAQZ292ZXJuYW5jZVJld2FyZAkABEwAAAACBQAAAA5zZW5kU3RyQXNzZXRJZAUAAAADbmlsBQAAAANuaWwAAAAAAAAAAAADCQAAAAAAAAIFAAAABnN0YWtlMgUAAAAGc3Rha2UyCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAlrQmFsYW5jZUEFAAAAC25ld0JhbGFuY2VBCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAlrQmFsYW5jZUIFAAAAC25ld0JhbGFuY2VCCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAprSW52YXJpYW50CQEAAAANaW52YXJpYW50Q2FsYwAAAAIFAAAAC25ld0JhbGFuY2VBBQAAAAtuZXdCYWxhbmNlQgkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIFAAAADmFtb3VudE1pbnVzRmVlBQAAAAtzZW5kQXNzZXRJZAkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADBQAAAA13YWxsZXRBZGRyZXNzBQAAABBnb3Zlcm5hbmNlUmV3YXJkBQAAAAtzZW5kQXNzZXRJZAUAAAADbmlsCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAAABaQEAAAAIc2h1dGRvd24AAAAAAwkBAAAAASEAAAABBQAAAAhpc0FjdGl2ZQkAAAIAAAABCQABLAAAAAICAAAAIkRBcHAgaXMgYWxyZWFkeSBzdXNwZW5kZWQuIENhdXNlOiAJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwUAAAAGa0NhdXNlAgAAABp0aGUgY2F1c2Ugd2Fzbid0IHNwZWNpZmllZAMJAQAAAAEhAAAAAQkBAAAAD2NvbnRhaW5zRWxlbWVudAAAAAIJAARMAAAAAgUAAAAMYWRtaW5QdWJLZXkxCQAETAAAAAIFAAAADGFkbWluUHViS2V5MgkABEwAAAACBQAAAAxhZG1pblB1YktleTMJAARMAAAAAgUAAAAMYWRtU3RhcnRTdG9wBQAAAANuaWwIBQAAAAFpAAAAD2NhbGxlclB1YmxpY0tleQkBAAAADnRocm93T25seUFkbWluAAAAAAkBAAAAB3N1c3BlbmQAAAABAgAAAA9QYXVzZWQgYnkgYWRtaW4AAAABaQEAAAAIYWN0aXZhdGUAAAAAAwUAAAAIaXNBY3RpdmUJAQAAAA10aHJvd0lzQWN0aXZlAAAAAAMJAQAAAAEhAAAAAQkBAAAAD2NvbnRhaW5zRWxlbWVudAAAAAIJAARMAAAAAgUAAAAMYWRtaW5QdWJLZXkxCQAETAAAAAIFAAAADGFkbWluUHViS2V5MgkABEwAAAACBQAAAAxhZG1pblB1YktleTMJAARMAAAAAgUAAAAMYWRtU3RhcnRTdG9wBQAAAANuaWwIBQAAAAFpAAAAD2NhbGxlclB1YmxpY0tleQkBAAAADnRocm93T25seUFkbWluAAAAAAkABEwAAAACCQEAAAAMQm9vbGVhbkVudHJ5AAAAAgUAAAAHa0FjdGl2ZQYJAARMAAAAAgkBAAAAC0RlbGV0ZUVudHJ5AAAAAQUAAAAGa0NhdXNlBQAAAANuaWwAAAABaQEAAAAZdGFrZUludG9BY2NvdW50RXh0cmFGdW5kcwAAAAAEAAAADWFtb3VudEVucm9sbEEJAABlAAAAAgUAAAAZYWNjb3VudEJhbGFuY2VXaXRoU3Rha2VkQQUAAAAIYmFsYW5jZUEEAAAADWFtb3VudEVucm9sbEIJAABlAAAAAgUAAAAZYWNjb3VudEJhbGFuY2VXaXRoU3Rha2VkQgUAAAAIYmFsYW5jZUIEAAAADGludmFyaWFudE5ldwkBAAAADWludmFyaWFudENhbGMAAAACCQAAZAAAAAIFAAAACGJhbGFuY2VBBQAAAA1hbW91bnRFbnJvbGxBCQAAZAAAAAIFAAAACGJhbGFuY2VCBQAAAA1hbW91bnRFbnJvbGxCAwkBAAAAASEAAAABBQAAAAhpc0FjdGl2ZQkBAAAAD3Rocm93SXNJbmFjdGl2ZQAAAAADCQEAAAACIT0AAAACCAUAAAABaQAAAAZjYWxsZXIFAAAADXdhbGxldEFkZHJlc3MJAAACAAAAAQIAAAAmT25seSB0aGUgd2FsbGV0IGNhbiBjYWxsIHRoaXMgZnVuY3Rpb24DAwkAAGYAAAACAAAAAAAAAAAABQAAAA1hbW91bnRFbnJvbGxBBgkAAGYAAAACAAAAAAAAAAAABQAAAA1hbW91bnRFbnJvbGxCCQEAAAAHc3VzcGVuZAAAAAECAAAAFkVu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", "height": 2943535, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: DuKuktRV5zz3yNAsj21gu9B6xw7P2PpNcSdeBXU4tV3P Next: YPFm4mAthVPQaQHZnc4sC1WDhpF9Tz71xq9suPb5rAx Diff:
OldNewDifferences
2727
2828 let kCause = "shutdown_cause"
2929
30+let keyUSDNNSBTAddress = "staking_usdnnsbt_address"
31+
32+let keyEURNAddress = "staking_eurn_address"
33+
3034 let keyAdminPubKey1 = "admin_pub_1"
3135
3236 let keyAdminPubKey2 = "admin_pub_2"
4549 }
4650
4751
48-let adm1 = getAdminPub(keyAdminPubKey1)
52+let adminPubKey1 = getAdminPub(keyAdminPubKey1)
4953
50-let adm2 = getAdminPub(keyAdminPubKey2)
54+let adminPubKey2 = getAdminPub(keyAdminPubKey2)
5155
52-let adm3 = getAdminPub(keyAdminPubKey3)
56+let adminPubKey3 = getAdminPub(keyAdminPubKey3)
5357
5458 let admStartStop = base58'EtVkT6ed8GtbUiVVEqdmEqsp2J4qbb3rre2HFgxeVYdg'
5559
5660 let admStaking = base58'Czn4yoAuUZCVCLJDRfskn8URfkwpknwBTZDbs1wFrY7h'
5761
58-let govAddr = Address(base58'3P6J84oH51DzY6xk2mT5TheXRbrCwBMxonp')
59-
60-let stakingAddress = Address(base58'3PNikM6yp4NqcSU8guxQtmR5onr2D4e8yTJ')
62+let walletAddress = Address(base58'3P6J84oH51DzY6xk2mT5TheXRbrCwBMxonp')
6163
6264 let USDN = base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p'
6365
64-let stakingFeeInUSDN = 270000
66+let EURN = base58'DUk2YTxhRoAqMJLus4G2b3fR8hMHVh6eiyFx5r29VR6t'
67+
68+let stakingAssets = [toBase58String(USDN), toBase58String(EURN)]
69+
70+let stakingUSDNNSBTAddress = Address(fromBase58String(valueOrErrorMessage(getString(oracle, keyUSDNNSBTAddress), "no usdn staking address")))
71+
72+let stakingEURNAddress = Address(fromBase58String(valueOrErrorMessage(getString(oracle, keyEURNAddress), "no usdn staking address")))
6573
6674 let isActive = getBooleanValue(this, kActive)
6775
145153 }
146154
147155
148-let stakedAmountUSDN = match getInteger(stakingAddress, ((("rpd_balance_" + toBase58String(USDN)) + "_") + toString(this))) {
149- case staked: Int =>
150- staked
151- case nothing: Unit =>
152- 0
153- case _ =>
154- throw("Match error")
155-}
156+func stakedAmount (assetId) = {
157+ let stakedAmountCalculated = match assetId {
158+ case aId: ByteVector =>
159+ if ((aId == USDN))
160+ then getInteger(stakingUSDNNSBTAddress, ((("rpd_balance_" + toBase58String(aId)) + "_") + toString(this)))
161+ else if ((aId == EURN))
162+ then getInteger(stakingEURNAddress, ((("%s%s%s__stakingBalance__" + toBase58String(aId)) + "__") + toString(this)))
163+ else 0
164+ case _: Unit =>
165+ 0
166+ case _ =>
167+ throw("Match error")
168+ }
169+ match stakedAmountCalculated {
170+ case i: Int =>
171+ i
172+ case _ =>
173+ 0
174+ }
175+ }
156176
157-let availableBalanceA = (balanceA - (if ((assetIdA == USDN))
158- then stakedAmountUSDN
159- else 0))
160177
161-let availableBalanceB = (balanceB - (if ((assetIdB == USDN))
162- then stakedAmountUSDN
163- else 0))
178+let stakedAmountA = stakedAmount(assetIdA)
164179
165-let accountBalanceWithStakedA = (accountBalance(assetIdA) + (if ((assetIdA == USDN))
166- then stakedAmountUSDN
167- else 0))
180+let stakedAmountB = stakedAmount(assetIdB)
168181
169-let accountBalanceWithStakedB = (accountBalance(assetIdB) + (if ((assetIdB == USDN))
170- then stakedAmountUSDN
171- else 0))
182+let availableBalanceA = (balanceA - stakedAmountA)
183+
184+let availableBalanceB = (balanceB - stakedAmountB)
185+
186+let accountBalanceWithStakedA = (accountBalance(assetIdA) + stakedAmountA)
187+
188+let accountBalanceWithStakedB = (accountBalance(assetIdB) + stakedAmountB)
172189
173190 let hasEnoughBalance = if ((accountBalanceWithStakedA >= balanceA))
174191 then (accountBalanceWithStakedB >= balanceB)
207224 else acc
208225
209226 let stepAmount = {
210- let $list60256068 = [1, 2, 3, 4, 5]
211- let $size60256068 = size($list60256068)
212- let $acc060256068 = -1
213- if (($size60256068 == 0))
214- then $acc060256068
215- else {
216- let $acc160256068 = getStepAmount($acc060256068, $list60256068[0])
217- if (($size60256068 == 1))
218- then $acc160256068
219- else {
220- let $acc260256068 = getStepAmount($acc160256068, $list60256068[1])
221- if (($size60256068 == 2))
222- then $acc260256068
223- else {
224- let $acc360256068 = getStepAmount($acc260256068, $list60256068[2])
225- if (($size60256068 == 3))
226- then $acc360256068
227- else {
228- let $acc460256068 = getStepAmount($acc360256068, $list60256068[3])
229- if (($size60256068 == 4))
230- then $acc460256068
231- else {
232- let $acc560256068 = getStepAmount($acc460256068, $list60256068[4])
233- if (($size60256068 == 5))
234- then $acc560256068
235- else {
236- let $acc660256068 = getStepAmount($acc560256068, $list60256068[5])
237- throw("List size exceed 5")
238- }
239- }
240- }
241- }
242- }
243- }
227+ let $l = [1, 2, 3, 4, 5]
228+ let $s = size($l)
229+ let $acc0 = -1
230+ func $f0_1 ($a,$i) = if (($i >= $s))
231+ then $a
232+ else getStepAmount($a, $l[$i])
233+
234+ func $f0_2 ($a,$i) = if (($i >= $s))
235+ then $a
236+ else throw("List size exceeds 5")
237+
238+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
244239 }
245240 if ((0 > stepAmount))
246241 then throw("something went wrong while working with amountToSend")
267262 func suspend (cause) = [BooleanEntry(kActive, false), StringEntry(kCause, cause)]
268263
269264
270-func deductStakingFee (amount,assetId) = if ((assetId == USDN))
271- then {
272- let result = (amount - stakingFeeInUSDN)
273- if ((0 >= result))
274- then throw((((("Insufficient amount " + toString(amount)) + " to deduct staking fee ") + toString(stakingFeeInUSDN)) + " USD-N"))
275- else result
276- }
277- else amount
278-
279-
280265 func throwIsActive () = throw("DApp is already active")
281266
282267
292277 func throwThreshold (threshold,amountA,amountB) = throw(((((((((("New balance in assets of the DApp is less than threshold " + toString(threshold)) + ": ") + toString(amountA)) + " ") + assetNameA) + ", ") + toString(amountB)) + " ") + assetNameB))
293278
294279
295-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"))
280+func suspendSuspicious () = suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB) + ". State: ") + toString(accountBalance(assetIdA))) + " ") + assetNameA) + ", ") + toString(accountBalance(assetIdB))) + " ") + assetNameB))
296281
297282
298-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"))
283+func calcStakingFuncAndAddres (stake,assetId) = if (stake)
284+ then if ((assetId == USDN))
285+ then $Tuple2("lockNeutrino", stakingUSDNNSBTAddress)
286+ else $Tuple2("startStaking", stakingEURNAddress)
287+ else if ((assetId == USDN))
288+ then $Tuple2("unlockNeutrino", stakingUSDNNSBTAddress)
289+ else $Tuple2("stopStaking", stakingEURNAddress)
299290
300291
301-func suspendSuspicious () = suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB) + ". State: ") + toString(accountBalance(assetIdA))) + " ") + assetNameA) + ", ") + toString(accountBalance(assetIdB))) + " ") + assetNameB))
292+func calcStakingParams (stake,amount,assetId) = if (stake)
293+ then {
294+ let $t087608826 = calcStakingFuncAndAddres(stake, assetId)
295+ let call = $t087608826._1
296+ let stakingAddr = $t087608826._2
297+ $Tuple4(call, stakingAddr, nil, [AttachedPayment(assetId, amount)])
298+ }
299+ else {
300+ let $t089128978 = calcStakingFuncAndAddres(stake, assetId)
301+ let call = $t089128978._1
302+ let stakingAddr = $t089128978._2
303+ $Tuple4(call, stakingAddr, [amount, toBase58String(assetId)], nil)
304+ }
302305
303306
304307 @Callable(i)
305308 func init () = {
306- let $t087448821 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
307- let pmtAmountA = $t087448821._1
308- let pmtAssetIdA = $t087448821._2
309- let $t088268903 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
310- let pmtAmountB = $t088268903._1
311- let pmtAssetIdB = $t088268903._2
312- let $t089088985 = getAssetInfo(pmtAssetIdA)
313- let pmtStrAssetIdA = $t089088985._1
314- let pmtAssetNameA = $t089088985._2
315- let pmtDecimalsA = $t089088985._3
316- let $t089909067 = getAssetInfo(pmtAssetIdB)
317- let pmtStrAssetIdB = $t089909067._1
318- let pmtAssetNameB = $t089909067._2
319- let pmtDecimalsB = $t089909067._3
309+ let $t090839160 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
310+ let pmtAmountA = $t090839160._1
311+ let pmtAssetIdA = $t090839160._2
312+ let $t091659242 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
313+ let pmtAmountB = $t091659242._1
314+ let pmtAssetIdB = $t091659242._2
315+ let $t092479324 = getAssetInfo(pmtAssetIdA)
316+ let pmtStrAssetIdA = $t092479324._1
317+ let pmtAssetNameA = $t092479324._2
318+ let pmtDecimalsA = $t092479324._3
319+ let $t093299406 = getAssetInfo(pmtAssetIdB)
320+ let pmtStrAssetIdB = $t093299406._1
321+ let pmtAssetNameB = $t093299406._2
322+ let pmtDecimalsB = $t093299406._3
320323 if (isDefined(getBoolean(this, kActive)))
321324 then throwIsActive()
322325 else if ((pmtAssetIdA == pmtAssetIdB))
329332 let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
330333 let shareIssueId = calculateAssetId(shareIssue)
331334 let invariantCalculated = invariantCalc(pmtAmountA, pmtAmountB)
332-[StringEntry(kVersion, version), BooleanEntry(kActive, true), StringEntry(kAssetIdA, pmtStrAssetIdA), StringEntry(kAssetIdB, pmtStrAssetIdB), IntegerEntry(kBalanceA, pmtAmountA), IntegerEntry(kBalanceB, pmtAmountB), IntegerEntry(kInvariant, invariantCalculated), IntegerEntry(kFee, fee), IntegerEntry(kFeeScaleDelimiter, feeScale6), shareIssue, StringEntry(kShareAssetId, toBase58String(shareIssueId)), IntegerEntry(kShareAssetSupply, shareInitialSupply), ScriptTransfer(i.caller, shareInitialSupply, shareIssueId)]
335+ let stake1 = if (containsElement(stakingAssets, pmtStrAssetIdA))
336+ then invoke(this, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
337+ else 0
338+ if ((stake1 == stake1))
339+ then {
340+ let stake2 = if (containsElement(stakingAssets, pmtStrAssetIdB))
341+ then invoke(this, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
342+ else 0
343+ if ((stake2 == stake2))
344+ then [StringEntry(kVersion, version), BooleanEntry(kActive, true), StringEntry(kAssetIdA, pmtStrAssetIdA), StringEntry(kAssetIdB, pmtStrAssetIdB), IntegerEntry(kBalanceA, pmtAmountA), IntegerEntry(kBalanceB, pmtAmountB), IntegerEntry(kInvariant, invariantCalculated), IntegerEntry(kFee, fee), IntegerEntry(kFeeScaleDelimiter, feeScale6), shareIssue, StringEntry(kShareAssetId, toBase58String(shareIssueId)), IntegerEntry(kShareAssetSupply, shareInitialSupply), ScriptTransfer(i.caller, shareInitialSupply, shareIssueId)]
345+ else throw("Strict value is not equal to itself.")
346+ }
347+ else throw("Strict value is not equal to itself.")
333348 }
334349 }
335350
339354 func replenishWithTwoTokens (slippageTolerance) = {
340355 let pmtAssetIdA = i.payments[0].assetId
341356 let pmtAssetIdB = i.payments[1].assetId
342- let pmtAmountA = deductStakingFee(i.payments[0].amount, pmtAssetIdA)
343- let pmtAmountB = deductStakingFee(i.payments[1].amount, pmtAssetIdB)
357+ let pmtAmountA = i.payments[0].amount
358+ let pmtAmountB = i.payments[1].amount
359+ let $t01192211999 = getAssetInfo(pmtAssetIdA)
360+ let pmtStrAssetIdA = $t01192211999._1
361+ let pmtAssetNameA = $t01192211999._2
362+ let pmtDecimalsA = $t01192211999._3
363+ let $t01200412198 = getAssetInfo(pmtAssetIdB)
364+ let pmtStrAssetIdB = $t01200412198._1
365+ let pmtAssetNameB = $t01200412198._2
366+ let pmtDecimalsB = $t01200412198._3
344367 let tokenRatio = fraction(fraction(scale8, balanceA, pmtAmountA), scale3, fraction(scale8, balanceB, pmtAmountB))
345368 let ratioShareTokensInA = fraction(scale8, pmtAmountA, balanceA)
346369 let ratioShareTokensInB = fraction(scale8, pmtAmountB, balanceB)
366389 then throw("Too small amount to replenish")
367390 else if (!(hasEnoughBalance))
368391 then ([ScriptTransfer(i.caller, pmtAmountA, pmtAssetIdA), ScriptTransfer(i.caller, pmtAmountB, pmtAssetIdB)] ++ suspendSuspicious())
369- else [IntegerEntry(kBalanceA, (balanceA + pmtAmountA)), IntegerEntry(kBalanceB, (balanceB + pmtAmountB)), IntegerEntry(kShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), IntegerEntry(kInvariant, invariantCalculated), Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId)]
392+ else {
393+ let stake1 = if (containsElement(stakingAssets, pmtStrAssetIdA))
394+ then invoke(this, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
395+ else 0
396+ if ((stake1 == stake1))
397+ then {
398+ let stake2 = if (containsElement(stakingAssets, pmtStrAssetIdB))
399+ then invoke(this, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
400+ else 0
401+ if ((stake2 == stake2))
402+ then [IntegerEntry(kBalanceA, (balanceA + pmtAmountA)), IntegerEntry(kBalanceB, (balanceB + pmtAmountB)), IntegerEntry(kShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), IntegerEntry(kInvariant, invariantCalculated), Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId)]
403+ else throw("Strict value is not equal to itself.")
404+ }
405+ else throw("Strict value is not equal to itself.")
406+ }
370407 }
371408
372409
373410
374411 @Callable(i)
375412 func replenishWithOneToken (virtualSwapTokenPay,virtualSwapTokenGet) = {
376- let $t01341013485 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
377- let pmtAmount = $t01341013485._1
378- let pmtAssetId = $t01341013485._2
413+ let $t01449714572 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
414+ let pmtAmount = $t01449714572._1
415+ let pmtAssetId = $t01449714572._2
416+ let $t01457714650 = getAssetInfo(pmtAssetId)
417+ let pmtStrAssetId = $t01457714650._1
418+ let pmtAssetName = $t01457714650._2
419+ let pmtDecimals = $t01457714650._3
379420 let pmtMinThreshold = 5000000
380421 let thresholdValueForMinTolerance = 50000000
381422 let tolerance = if ((thresholdValueForMinTolerance > pmtAmount))
397438 else false)
398439 then throwAssets()
399440 else {
400- let $t01449715262 = if ((pmtAssetId == assetIdA))
441+ let $t01566216427 = if ((pmtAssetId == assetIdA))
401442 then $Tuple7((pmtAmount - virtualSwapTokenPay), virtualSwapTokenGet, (balanceA + virtualSwapTokenPay), (balanceB - virtualSwapTokenGet), invariantCalc((balanceA + pmtAmount), balanceB), (balanceA + pmtAmount), balanceB)
402443 else $Tuple7(virtualSwapTokenGet, (pmtAmount - virtualSwapTokenPay), (balanceA - virtualSwapTokenGet), (balanceB + virtualSwapTokenPay), invariantCalc(balanceA, (balanceB + pmtAmount)), balanceA, (balanceB + pmtAmount))
403- let virtualReplenishA = $t01449715262._1
404- let virtualReplenishB = $t01449715262._2
405- let balanceAfterSwapA = $t01449715262._3
406- let balanceAfterSwapB = $t01449715262._4
407- let invariantCalculated = $t01449715262._5
408- let newBalanceA = $t01449715262._6
409- let newBalanceB = $t01449715262._7
444+ let virtualReplenishA = $t01566216427._1
445+ let virtualReplenishB = $t01566216427._2
446+ let balanceAfterSwapA = $t01566216427._3
447+ let balanceAfterSwapB = $t01566216427._4
448+ let invariantCalculated = $t01566216427._5
449+ let newBalanceA = $t01566216427._6
450+ let newBalanceB = $t01566216427._7
410451 let newBalanceEntry = if ((pmtAssetId == assetIdA))
411452 then IntegerEntry(kBalanceA, newBalanceA)
412453 else IntegerEntry(kBalanceB, newBalanceB)
427468 else (dAppThresholdAmount > newBalanceB))
428469 then throwThreshold(dAppThresholdAmount, newBalanceA, newBalanceB)
429470 else {
430- let ratioShareTokensInA = fraction(deductStakingFee(virtualReplenishA, assetIdA), scale8, balanceAfterSwapA)
431- let ratioShareTokensInB = fraction(deductStakingFee(virtualReplenishB, assetIdB), scale8, balanceAfterSwapB)
432- let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scale8)
471+ let stake1 = if (containsElement(stakingAssets, pmtStrAssetId))
472+ then invoke(this, "stakeUnstake", [true, pmtAmount, pmtStrAssetId], nil)
473+ else 0
474+ if ((stake1 == stake1))
475+ then {
476+ let ratioShareTokensInA = fraction(virtualReplenishA, scale8, balanceAfterSwapA)
477+ let ratioShareTokensInB = fraction(virtualReplenishB, scale8, balanceAfterSwapB)
478+ let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scale8)
433479 [Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId), IntegerEntry(kShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), newBalanceEntry, IntegerEntry(kInvariant, invariantCalculated)]
480+ }
481+ else throw("Strict value is not equal to itself.")
434482 }
435483 }
436484 }
439487
440488 @Callable(i)
441489 func withdraw () = {
442- let $t01740717550 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
443- let pmtAmount = $t01740717550._1
444- let pmtAssetId = $t01740717550._2
445- let amountToPayA = deductStakingFee(fraction(pmtAmount, balanceA, shareAssetSupply), assetIdA)
446- let amountToPayB = deductStakingFee(fraction(pmtAmount, balanceB, shareAssetSupply), assetIdB)
490+ let $t01865318796 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
491+ let pmtAmount = $t01865318796._1
492+ let pmtAssetId = $t01865318796._2
493+ let amountToPayA = fraction(pmtAmount, balanceA, shareAssetSupply)
494+ let amountToPayB = fraction(pmtAmount, balanceB, shareAssetSupply)
447495 let invariantCalculated = invariantCalc((balanceA - amountToPayA), (balanceB - amountToPayB))
448496 if (!(isActive))
449497 then throwIsInactive()
453501 then throw(("Incorrect asset attached. Expected: " + toBase58String(shareAssetId)))
454502 else if (!(hasEnoughBalance))
455503 then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
456- else if (if ((amountToPayA > availableBalanceA))
457- then true
458- else (amountToPayB > availableBalanceB))
459- then throwInsufficientAvailableBalances(amountToPayA, amountToPayB)
460- else [IntegerEntry(kBalanceA, (balanceA - amountToPayA)), IntegerEntry(kBalanceB, (balanceB - amountToPayB)), IntegerEntry(kShareAssetSupply, (shareAssetSupply - pmtAmount)), IntegerEntry(kInvariant, invariantCalculated), Burn(shareAssetId, pmtAmount), ScriptTransfer(i.caller, amountToPayA, assetIdA), ScriptTransfer(i.caller, amountToPayB, assetIdB)]
504+ else {
505+ let stake1 = if (containsElement(stakingAssets, strAssetIdA))
506+ then invoke(this, "stakeUnstake", [false, amountToPayA, strAssetIdA], nil)
507+ else 0
508+ if ((stake1 == stake1))
509+ then {
510+ let stake2 = if (containsElement(stakingAssets, strAssetIdB))
511+ then invoke(this, "stakeUnstake", [false, amountToPayB, strAssetIdB], nil)
512+ else 0
513+ if ((stake2 == stake2))
514+ then [IntegerEntry(kBalanceA, (balanceA - amountToPayA)), IntegerEntry(kBalanceB, (balanceB - amountToPayB)), IntegerEntry(kShareAssetSupply, (shareAssetSupply - pmtAmount)), IntegerEntry(kInvariant, invariantCalculated), Burn(shareAssetId, pmtAmount), ScriptTransfer(i.caller, amountToPayA, assetIdA), ScriptTransfer(i.caller, amountToPayB, assetIdB)]
515+ else throw("Strict value is not equal to itself.")
516+ }
517+ else throw("Strict value is not equal to itself.")
518+ }
461519 }
462520
463521
464522
465523 @Callable(i)
466524 func exchange (estimatedAmountToReceive,minAmountToReceive) = {
467- let $t01890818983 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
468- let pmtAmount = $t01890818983._1
469- let pmtAssetId = $t01890818983._2
525+ let $t02031020385 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
526+ let pmtAmount = $t02031020385._1
527+ let pmtAssetId = $t02031020385._2
470528 if (!(isActive))
471529 then throwIsInactive()
472530 else if ((0 >= estimatedAmountToReceive))
494552 let amount = calculateSendAmount(estimatedAmountToReceive, minAmountToReceive, pmtAmount, pmtAssetId)
495553 let governanceReward = fraction(amount, feeGovernance, feeScale6)
496554 let amountMinusFee = fraction(amount, (feeScale6 - fee), feeScale6)
497- let $t02040520667 = if ((pmtAssetId == assetIdA))
555+ let $t02180722069 = if ((pmtAssetId == assetIdA))
498556 then $Tuple2((balanceA + pmtAmount), ((balanceB - amountMinusFee) - governanceReward))
499557 else $Tuple2(((balanceA - amountMinusFee) - governanceReward), (balanceB + pmtAmount))
500- let newBalanceA = $t02040520667._1
501- let newBalanceB = $t02040520667._2
558+ let newBalanceA = $t02180722069._1
559+ let newBalanceB = $t02180722069._2
502560 let dAppThresholdAmount = fraction((newBalanceA + newBalanceB), dAppThreshold, (2 * dAppThresholdScale2))
503561 if (if ((dAppThresholdAmount > newBalanceA))
504562 then true
505563 else (dAppThresholdAmount > newBalanceB))
506564 then throwThreshold(dAppThresholdAmount, newBalanceA, newBalanceB)
507- else if (if (if ((assetIdA == USDN))
508- then (sendAssetId == assetIdA)
509- else false)
510- then (stakedAmountUSDN >= newBalanceA)
511- else false)
512- then throwInsufficientAvailableBalance(amountMinusFee, availableBalanceA, assetNameA)
513- else if (if (if ((assetIdB == USDN))
514- then (sendAssetId == assetIdB)
515- else false)
516- then (stakedAmountUSDN >= newBalanceB)
517- else false)
518- then throwInsufficientAvailableBalance(amountMinusFee, availableBalanceB, assetNameB)
519- else [IntegerEntry(kBalanceA, newBalanceA), IntegerEntry(kBalanceB, newBalanceB), IntegerEntry(kInvariant, invariantCalc(newBalanceA, newBalanceB)), ScriptTransfer(i.caller, amountMinusFee, sendAssetId), ScriptTransfer(govAddr, governanceReward, sendAssetId)]
565+ else {
566+ let $t02236722440 = getAssetInfo(pmtAssetId)
567+ let pmtStrAssetId = $t02236722440._1
568+ let pmtAssetName = $t02236722440._2
569+ let pmtDecimals = $t02236722440._3
570+ let $t02245322530 = getAssetInfo(sendAssetId)
571+ let sendStrAssetId = $t02245322530._1
572+ let sendAssetName = $t02245322530._2
573+ let sendDecimals = $t02245322530._3
574+ let stake1 = if (containsElement(stakingAssets, pmtStrAssetId))
575+ then invoke(this, "stakeUnstake", [true, pmtAmount, pmtStrAssetId], nil)
576+ else 0
577+ if ((stake1 == stake1))
578+ then {
579+ let stake2 = if (containsElement(stakingAssets, sendStrAssetId))
580+ then invoke(this, "stakeUnstake", [false, (amountMinusFee + governanceReward), sendStrAssetId], nil)
581+ else 0
582+ if ((stake2 == stake2))
583+ then [IntegerEntry(kBalanceA, newBalanceA), IntegerEntry(kBalanceB, newBalanceB), IntegerEntry(kInvariant, invariantCalc(newBalanceA, newBalanceB)), ScriptTransfer(i.caller, amountMinusFee, sendAssetId), ScriptTransfer(walletAddress, governanceReward, sendAssetId)]
584+ else throw("Strict value is not equal to itself.")
585+ }
586+ else throw("Strict value is not equal to itself.")
587+ }
520588 }
521589 }
522590
525593 @Callable(i)
526594 func shutdown () = if (!(isActive))
527595 then throw(("DApp is already suspended. Cause: " + valueOrElse(getString(this, kCause), "the cause wasn't specified")))
528- else if (!(containsElement([adm1, adm2, adm3, admStartStop], i.callerPublicKey)))
596+ else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, admStartStop], i.callerPublicKey)))
529597 then throwOnlyAdmin()
530598 else suspend("Paused by admin")
531599
534602 @Callable(i)
535603 func activate () = if (isActive)
536604 then throwIsActive()
537- else if (!(containsElement([adm1, adm2, adm3, admStartStop], i.callerPublicKey)))
605+ else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, admStartStop], i.callerPublicKey)))
538606 then throwOnlyAdmin()
539607 else [BooleanEntry(kActive, true), DeleteEntry(kCause)]
540608
541609
542610
543611 @Callable(i)
544-func takeIntoAccountExtraFunds (amountLeave) = {
545- let uncountableA = (accountBalanceWithStakedA - balanceA)
546- let uncountableB = (accountBalanceWithStakedB - balanceB)
547- let amountEnrollA = (uncountableA - (if ((assetIdA == unit))
548- then amountLeave
549- else 0))
550- let amountEnrollB = (uncountableB - (if ((assetIdB == unit))
551- then amountLeave
552- else 0))
612+func takeIntoAccountExtraFunds () = {
613+ let amountEnrollA = (accountBalanceWithStakedA - balanceA)
614+ let amountEnrollB = (accountBalanceWithStakedB - balanceB)
553615 let invariantNew = invariantCalc((balanceA + amountEnrollA), (balanceB + amountEnrollB))
554616 if (!(isActive))
555617 then throwIsInactive()
556- else if ((i.caller != this))
557- then throwOnlyAdmin()
558- else if ((0 > amountLeave))
559- then throw(("Argument 'amountLeave' cannot be negative. Actual: " + toString(amountLeave)))
560- else if (if ((0 > uncountableA))
561- then true
562- else (0 > uncountableB))
563- then suspend("Enroll amount negative")
564- else if (if ((0 > amountEnrollA))
565- then true
566- else (0 > amountEnrollB))
567- then throw("Too large amountLeave")
568- else [IntegerEntry(kInvariant, invariantNew), IntegerEntry(kBalanceA, (balanceA + amountEnrollA)), IntegerEntry(kBalanceB, (balanceB + amountEnrollB)), IntegerEntry(("last_income_" + strAssetIdA), amountEnrollA), IntegerEntry(("last_income_" + strAssetIdB), amountEnrollB)]
618+ else if ((i.caller != walletAddress))
619+ then throw("Only the wallet can call this function")
620+ else if (if ((0 > amountEnrollA))
621+ then true
622+ else (0 > amountEnrollB))
623+ then suspend("Enroll amount negative")
624+ else if (if ((amountEnrollA == 0))
625+ then (amountEnrollB == 0)
626+ else false)
627+ then throw("No money to take")
628+ else {
629+ let stake1 = if (if (containsElement(stakingAssets, strAssetIdA))
630+ then (amountEnrollA > 0)
631+ else false)
632+ then invoke(this, "stakeUnstake", [true, amountEnrollA, strAssetIdA], nil)
633+ else 0
634+ if ((stake1 == stake1))
635+ then {
636+ let stake2 = if (if (containsElement(stakingAssets, strAssetIdB))
637+ then (amountEnrollB > 0)
638+ else false)
639+ then invoke(this, "stakeUnstake", [true, amountEnrollB, strAssetIdB], nil)
640+ else 0
641+ if ((stake2 == stake2))
642+ then [IntegerEntry(kInvariant, invariantNew), IntegerEntry(kBalanceA, (balanceA + amountEnrollA)), IntegerEntry(kBalanceB, (balanceB + amountEnrollB)), IntegerEntry(("last_income_" + strAssetIdA), amountEnrollA), IntegerEntry(("last_income_" + strAssetIdB), amountEnrollB)]
643+ else throw("Strict value is not equal to itself.")
644+ }
645+ else throw("Strict value is not equal to itself.")
646+ }
569647 }
570648
571649
650+
651+@Callable(i)
652+func stakeUnstake (stake,amount,assetIdString) = if ((i.caller != this))
653+ then throw("Only contract itself can invoke this function")
654+ else {
655+ let $t02559225695 = calcStakingParams(stake, amount, fromBase58String(assetIdString))
656+ let call = $t02559225695._1
657+ let addr = $t02559225695._2
658+ let params = $t02559225695._3
659+ let payments = $t02559225695._4
660+ let inv = invoke(addr, call, params, payments)
661+ if ((inv == inv))
662+ then nil
663+ else throw("Strict value is not equal to itself.")
664+ }
665+
666+
667+
668+@Callable(i)
669+func stakeAll () = if (!(isActive))
670+ then throw("DApp is inactive at this moment")
671+ else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, admStartStop], i.callerPublicKey)))
672+ then throw("Only admin can call this function")
673+ else {
674+ let stake1 = if (containsElement(stakingAssets, strAssetIdA))
675+ then {
676+ let amountA = (balanceA - stakedAmountA)
677+ if ((amountA > 0))
678+ then invoke(this, "stakeUnstake", [true, amountA, strAssetIdA], nil)
679+ else 0
680+ }
681+ else 0
682+ if ((stake1 == stake1))
683+ then {
684+ let stake2 = if (containsElement(stakingAssets, strAssetIdB))
685+ then {
686+ let amountB = (balanceB - stakedAmountB)
687+ if ((amountB > 0))
688+ then invoke(this, "stakeUnstake", [true, amountB, strAssetIdB], nil)
689+ else 0
690+ }
691+ else 0
692+ if ((stake2 == stake2))
693+ then nil
694+ else throw("Strict value is not equal to itself.")
695+ }
696+ else throw("Strict value is not equal to itself.")
697+ }
698+
699+
572700 @Verifier(tx)
573-func verify () = match tx {
574- case inv: InvokeScriptTransaction =>
575- let callTakeIntoAccount = if ((inv.dApp == this))
576- then (inv.function == "takeIntoAccountExtraFunds")
577- else false
578- let callStaking = if ((inv.dApp == stakingAddress))
579- then if (if (if ((inv.function == "lockNeutrino"))
580- then (size(inv.payments) == 1)
581- else false)
582- then (inv.payments[0].assetId == USDN)
701+func verify () = {
702+ let multiSignedByAdmins = {
703+ let adminPubKey1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
704+ then 1
705+ else 0
706+ let adminPubKey2Signed = if (sigVerify(tx.bodyBytes, tx.proofs[1], adminPubKey2))
707+ then 1
708+ else 0
709+ let adminPubKey3Signed = if (sigVerify(tx.bodyBytes, tx.proofs[2], adminPubKey3))
710+ then 1
711+ else 0
712+ (((adminPubKey1Signed + adminPubKey2Signed) + adminPubKey3Signed) >= 2)
713+ }
714+ match tx {
715+ case inv: InvokeScriptTransaction =>
716+ let callTakeIntoAccount = if ((inv.dApp == this))
717+ then (inv.function == "takeIntoAccountExtraFunds")
718+ else false
719+ let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
720+ then true
721+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey2))
722+ then true
723+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey3))
724+ then true
725+ else sigVerify(tx.bodyBytes, tx.proofs[0], admStaking)
726+ if (if (callTakeIntoAccount)
727+ then signedByAdmin
583728 else false)
584729 then true
585- else if ((inv.function == "unlockNeutrino"))
586- then (size(inv.payments) == 0)
587- else false
588- else false
589- let exchangeToWaves = if (if (if ((inv.dApp == USDNToWavesExchanger))
590- then (inv.function == "exchange")
591- else false)
592- then (assetIdA == USDN)
593- else false)
594- then true
595- else if (if ((assetIdB == USDN))
596- then (size(inv.payments) == 1)
597- else false)
598- then (inv.payments[0].assetId == USDN)
599- else false
600- let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adm1))
601- then true
602- else sigVerify(tx.bodyBytes, tx.proofs[0], adm2))
603- then true
604- else sigVerify(tx.bodyBytes, tx.proofs[0], adm3))
605- then true
606- else sigVerify(tx.bodyBytes, tx.proofs[0], admStaking)
607- if (if (if (callTakeIntoAccount)
608- then true
609- else callStaking)
610- then true
611- else exchangeToWaves)
612- then signedByAdmin
613- else false
614- case _ =>
615- let adm1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adm1))
616- then 1
617- else 0
618- let adm2Signed = if (sigVerify(tx.bodyBytes, tx.proofs[1], adm2))
619- then 1
620- else 0
621- let adm3Signed = if (sigVerify(tx.bodyBytes, tx.proofs[2], adm3))
622- then 1
623- else 0
624- (((adm1Signed + adm2Signed) + adm3Signed) >= 2)
625-}
730+ else multiSignedByAdmins
731+ case _ =>
732+ multiSignedByAdmins
733+ }
734+ }
626735
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let version = "2.0.0"
55
66 let kVersion = "version"
77
88 let kActive = "active"
99
1010 let kAssetIdA = "A_asset_id"
1111
1212 let kAssetIdB = "B_asset_id"
1313
1414 let kBalanceA = "A_asset_balance"
1515
1616 let kBalanceB = "B_asset_balance"
1717
1818 let kShareAssetId = "share_asset_id"
1919
2020 let kShareAssetSupply = "share_asset_supply"
2121
2222 let kFee = "commission"
2323
2424 let kFeeScaleDelimiter = "commission_scale_delimiter"
2525
2626 let kInvariant = "invariant"
2727
2828 let kCause = "shutdown_cause"
2929
30+let keyUSDNNSBTAddress = "staking_usdnnsbt_address"
31+
32+let keyEURNAddress = "staking_eurn_address"
33+
3034 let keyAdminPubKey1 = "admin_pub_1"
3135
3236 let keyAdminPubKey2 = "admin_pub_2"
3337
3438 let keyAdminPubKey3 = "admin_pub_3"
3539
3640 let USDNToWavesExchanger = Address(base58'3PHaNgomBkrvEL2QnuJarQVJa71wjw9qiqG')
3741
3842 let oracle = Address(base58'3PEbqViERCoKnmcSULh6n2aiMvUdSQdCsom')
3943
4044 func getAdminPub (keyAdminPub) = match getString(oracle, keyAdminPub) {
4145 case string: String =>
4246 fromBase58String(string)
4347 case nothing =>
4448 throw("Admin public key is empty")
4549 }
4650
4751
48-let adm1 = getAdminPub(keyAdminPubKey1)
52+let adminPubKey1 = getAdminPub(keyAdminPubKey1)
4953
50-let adm2 = getAdminPub(keyAdminPubKey2)
54+let adminPubKey2 = getAdminPub(keyAdminPubKey2)
5155
52-let adm3 = getAdminPub(keyAdminPubKey3)
56+let adminPubKey3 = getAdminPub(keyAdminPubKey3)
5357
5458 let admStartStop = base58'EtVkT6ed8GtbUiVVEqdmEqsp2J4qbb3rre2HFgxeVYdg'
5559
5660 let admStaking = base58'Czn4yoAuUZCVCLJDRfskn8URfkwpknwBTZDbs1wFrY7h'
5761
58-let govAddr = Address(base58'3P6J84oH51DzY6xk2mT5TheXRbrCwBMxonp')
59-
60-let stakingAddress = Address(base58'3PNikM6yp4NqcSU8guxQtmR5onr2D4e8yTJ')
62+let walletAddress = Address(base58'3P6J84oH51DzY6xk2mT5TheXRbrCwBMxonp')
6163
6264 let USDN = base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p'
6365
64-let stakingFeeInUSDN = 270000
66+let EURN = base58'DUk2YTxhRoAqMJLus4G2b3fR8hMHVh6eiyFx5r29VR6t'
67+
68+let stakingAssets = [toBase58String(USDN), toBase58String(EURN)]
69+
70+let stakingUSDNNSBTAddress = Address(fromBase58String(valueOrErrorMessage(getString(oracle, keyUSDNNSBTAddress), "no usdn staking address")))
71+
72+let stakingEURNAddress = Address(fromBase58String(valueOrErrorMessage(getString(oracle, keyEURNAddress), "no usdn staking address")))
6573
6674 let isActive = getBooleanValue(this, kActive)
6775
6876 let strAssetIdA = getStringValue(this, kAssetIdA)
6977
7078 let strAssetIdB = getStringValue(this, kAssetIdB)
7179
7280 let assetIdA = if ((strAssetIdA == "WAVES"))
7381 then unit
7482 else fromBase58String(strAssetIdA)
7583
7684 let assetIdB = if ((strAssetIdB == "WAVES"))
7785 then unit
7886 else fromBase58String(strAssetIdB)
7987
8088 let assetNameA = match assetIdA {
8189 case id: ByteVector =>
8290 value(assetInfo(id)).name
8391 case waves: Unit =>
8492 "WAVES"
8593 case _ =>
8694 throw("Match error")
8795 }
8896
8997 let assetNameB = match assetIdB {
9098 case id: ByteVector =>
9199 value(assetInfo(id)).name
92100 case waves: Unit =>
93101 "WAVES"
94102 case _ =>
95103 throw("Match error")
96104 }
97105
98106 let balanceA = getIntegerValue(this, kBalanceA)
99107
100108 let balanceB = getIntegerValue(this, kBalanceB)
101109
102110 let shareAssetId = fromBase58String(getStringValue(this, kShareAssetId))
103111
104112 let shareAssetSupply = getIntegerValue(this, kShareAssetSupply)
105113
106114 let invariant = getIntegerValue(this, kInvariant)
107115
108116 let fee = 500
109117
110118 let feeGovernance = 200
111119
112120 let feeScale6 = 1000000
113121
114122 let scale3 = 1000
115123
116124 let scale8 = 100000000
117125
118126 let scale12 = 1000000000000
119127
120128 let slippageScale3 = 1000
121129
122130 let digits8 = 8
123131
124132 let dAppThreshold = 50
125133
126134 let dAppThresholdScale2 = 100
127135
128136 let exchangeRatioLimitMin = 90000000
129137
130138 let exchangeRatioLimitMax = 110000000
131139
132140 let alpha = 50
133141
134142 let alphaDigits = 2
135143
136144 let beta = 46000000
137145
138146 func accountBalance (assetId) = match assetId {
139147 case id: ByteVector =>
140148 assetBalance(this, id)
141149 case waves: Unit =>
142150 wavesBalance(this).available
143151 case _ =>
144152 throw("Match error")
145153 }
146154
147155
148-let stakedAmountUSDN = match getInteger(stakingAddress, ((("rpd_balance_" + toBase58String(USDN)) + "_") + toString(this))) {
149- case staked: Int =>
150- staked
151- case nothing: Unit =>
152- 0
153- case _ =>
154- throw("Match error")
155-}
156+func stakedAmount (assetId) = {
157+ let stakedAmountCalculated = match assetId {
158+ case aId: ByteVector =>
159+ if ((aId == USDN))
160+ then getInteger(stakingUSDNNSBTAddress, ((("rpd_balance_" + toBase58String(aId)) + "_") + toString(this)))
161+ else if ((aId == EURN))
162+ then getInteger(stakingEURNAddress, ((("%s%s%s__stakingBalance__" + toBase58String(aId)) + "__") + toString(this)))
163+ else 0
164+ case _: Unit =>
165+ 0
166+ case _ =>
167+ throw("Match error")
168+ }
169+ match stakedAmountCalculated {
170+ case i: Int =>
171+ i
172+ case _ =>
173+ 0
174+ }
175+ }
156176
157-let availableBalanceA = (balanceA - (if ((assetIdA == USDN))
158- then stakedAmountUSDN
159- else 0))
160177
161-let availableBalanceB = (balanceB - (if ((assetIdB == USDN))
162- then stakedAmountUSDN
163- else 0))
178+let stakedAmountA = stakedAmount(assetIdA)
164179
165-let accountBalanceWithStakedA = (accountBalance(assetIdA) + (if ((assetIdA == USDN))
166- then stakedAmountUSDN
167- else 0))
180+let stakedAmountB = stakedAmount(assetIdB)
168181
169-let accountBalanceWithStakedB = (accountBalance(assetIdB) + (if ((assetIdB == USDN))
170- then stakedAmountUSDN
171- else 0))
182+let availableBalanceA = (balanceA - stakedAmountA)
183+
184+let availableBalanceB = (balanceB - stakedAmountB)
185+
186+let accountBalanceWithStakedA = (accountBalance(assetIdA) + stakedAmountA)
187+
188+let accountBalanceWithStakedB = (accountBalance(assetIdB) + stakedAmountB)
172189
173190 let hasEnoughBalance = if ((accountBalanceWithStakedA >= balanceA))
174191 then (accountBalanceWithStakedB >= balanceB)
175192 else false
176193
177194 func skewness (x,y) = (((fraction(scale12, x, y) + fraction(scale12, y, x)) / 2) / 10000)
178195
179196
180197 func invariantCalc (x,y) = {
181198 let sk = skewness(x, y)
182199 (fraction((x + y), scale8, pow(sk, digits8, alpha, alphaDigits, digits8, CEILING)) + (2 * fraction(pow(fraction(x, y, scale8), 0, 5, 1, (digits8 / 2), DOWN), pow((sk - beta), digits8, alpha, alphaDigits, digits8, DOWN), scale8)))
183200 }
184201
185202
186203 func calculateSendAmount (amountToSendEstimated,minTokenReceiveAmount,tokenReceiveAmount,tokenId) = {
187204 let slippageValue = (scale8 - ((scale8 * 1) / 10000000))
188205 let deltaBetweenMaxAndMinSendValue = (amountToSendEstimated - minTokenReceiveAmount)
189206 let x = (balanceA + tokenReceiveAmount)
190207 let y = (balanceB + tokenReceiveAmount)
191208 let invariantNew = if ((tokenId == assetIdA))
192209 then invariantCalc(x, (balanceB - amountToSendEstimated))
193210 else if ((tokenId == assetIdB))
194211 then invariantCalc((balanceA - amountToSendEstimated), y)
195212 else throw("Wrong asset in payment")
196213 let invariantEstimatedRatio = fraction(scale8, invariant, invariantNew)
197214 func getStepAmount (acc,step) = if ((acc == -1))
198215 then {
199216 let amountToSend = (amountToSendEstimated - ((step * deltaBetweenMaxAndMinSendValue) / 5))
200217 let stepInvariant = if ((tokenId == assetIdA))
201218 then invariantCalc(x, (balanceB - amountToSend))
202219 else invariantCalc((balanceA - amountToSend), y)
203220 if ((stepInvariant > invariant))
204221 then amountToSend
205222 else -1
206223 }
207224 else acc
208225
209226 let stepAmount = {
210- let $list60256068 = [1, 2, 3, 4, 5]
211- let $size60256068 = size($list60256068)
212- let $acc060256068 = -1
213- if (($size60256068 == 0))
214- then $acc060256068
215- else {
216- let $acc160256068 = getStepAmount($acc060256068, $list60256068[0])
217- if (($size60256068 == 1))
218- then $acc160256068
219- else {
220- let $acc260256068 = getStepAmount($acc160256068, $list60256068[1])
221- if (($size60256068 == 2))
222- then $acc260256068
223- else {
224- let $acc360256068 = getStepAmount($acc260256068, $list60256068[2])
225- if (($size60256068 == 3))
226- then $acc360256068
227- else {
228- let $acc460256068 = getStepAmount($acc360256068, $list60256068[3])
229- if (($size60256068 == 4))
230- then $acc460256068
231- else {
232- let $acc560256068 = getStepAmount($acc460256068, $list60256068[4])
233- if (($size60256068 == 5))
234- then $acc560256068
235- else {
236- let $acc660256068 = getStepAmount($acc560256068, $list60256068[5])
237- throw("List size exceed 5")
238- }
239- }
240- }
241- }
242- }
243- }
227+ let $l = [1, 2, 3, 4, 5]
228+ let $s = size($l)
229+ let $acc0 = -1
230+ func $f0_1 ($a,$i) = if (($i >= $s))
231+ then $a
232+ else getStepAmount($a, $l[$i])
233+
234+ func $f0_2 ($a,$i) = if (($i >= $s))
235+ then $a
236+ else throw("List size exceeds 5")
237+
238+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
244239 }
245240 if ((0 > stepAmount))
246241 then throw("something went wrong while working with amountToSend")
247242 else if (if ((invariantEstimatedRatio > slippageValue))
248243 then (invariantNew > invariant)
249244 else false)
250245 then amountToSendEstimated
251246 else stepAmount
252247 }
253248
254249
255250 func getAssetInfo (assetId) = match assetId {
256251 case id: ByteVector =>
257252 let stringId = toBase58String(id)
258253 let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
259254 $Tuple3(stringId, info.name, info.decimals)
260255 case waves: Unit =>
261256 $Tuple3("WAVES", "WAVES", 8)
262257 case _ =>
263258 throw("Match error")
264259 }
265260
266261
267262 func suspend (cause) = [BooleanEntry(kActive, false), StringEntry(kCause, cause)]
268263
269264
270-func deductStakingFee (amount,assetId) = if ((assetId == USDN))
271- then {
272- let result = (amount - stakingFeeInUSDN)
273- if ((0 >= result))
274- then throw((((("Insufficient amount " + toString(amount)) + " to deduct staking fee ") + toString(stakingFeeInUSDN)) + " USD-N"))
275- else result
276- }
277- else amount
278-
279-
280265 func throwIsActive () = throw("DApp is already active")
281266
282267
283268 func throwIsInactive () = throw("DApp is inactive at this moment")
284269
285270
286271 func throwOnlyAdmin () = throw("Only admin can call this function")
287272
288273
289274 func throwAssets () = throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
290275
291276
292277 func throwThreshold (threshold,amountA,amountB) = throw(((((((((("New balance in assets of the DApp is less than threshold " + toString(threshold)) + ": ") + toString(amountA)) + " ") + assetNameA) + ", ") + toString(amountB)) + " ") + assetNameB))
293278
294279
295-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"))
280+func suspendSuspicious () = suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB) + ". State: ") + toString(accountBalance(assetIdA))) + " ") + assetNameA) + ", ") + toString(accountBalance(assetIdB))) + " ") + assetNameB))
296281
297282
298-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"))
283+func calcStakingFuncAndAddres (stake,assetId) = if (stake)
284+ then if ((assetId == USDN))
285+ then $Tuple2("lockNeutrino", stakingUSDNNSBTAddress)
286+ else $Tuple2("startStaking", stakingEURNAddress)
287+ else if ((assetId == USDN))
288+ then $Tuple2("unlockNeutrino", stakingUSDNNSBTAddress)
289+ else $Tuple2("stopStaking", stakingEURNAddress)
299290
300291
301-func suspendSuspicious () = suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB) + ". State: ") + toString(accountBalance(assetIdA))) + " ") + assetNameA) + ", ") + toString(accountBalance(assetIdB))) + " ") + assetNameB))
292+func calcStakingParams (stake,amount,assetId) = if (stake)
293+ then {
294+ let $t087608826 = calcStakingFuncAndAddres(stake, assetId)
295+ let call = $t087608826._1
296+ let stakingAddr = $t087608826._2
297+ $Tuple4(call, stakingAddr, nil, [AttachedPayment(assetId, amount)])
298+ }
299+ else {
300+ let $t089128978 = calcStakingFuncAndAddres(stake, assetId)
301+ let call = $t089128978._1
302+ let stakingAddr = $t089128978._2
303+ $Tuple4(call, stakingAddr, [amount, toBase58String(assetId)], nil)
304+ }
302305
303306
304307 @Callable(i)
305308 func init () = {
306- let $t087448821 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
307- let pmtAmountA = $t087448821._1
308- let pmtAssetIdA = $t087448821._2
309- let $t088268903 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
310- let pmtAmountB = $t088268903._1
311- let pmtAssetIdB = $t088268903._2
312- let $t089088985 = getAssetInfo(pmtAssetIdA)
313- let pmtStrAssetIdA = $t089088985._1
314- let pmtAssetNameA = $t089088985._2
315- let pmtDecimalsA = $t089088985._3
316- let $t089909067 = getAssetInfo(pmtAssetIdB)
317- let pmtStrAssetIdB = $t089909067._1
318- let pmtAssetNameB = $t089909067._2
319- let pmtDecimalsB = $t089909067._3
309+ let $t090839160 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
310+ let pmtAmountA = $t090839160._1
311+ let pmtAssetIdA = $t090839160._2
312+ let $t091659242 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
313+ let pmtAmountB = $t091659242._1
314+ let pmtAssetIdB = $t091659242._2
315+ let $t092479324 = getAssetInfo(pmtAssetIdA)
316+ let pmtStrAssetIdA = $t092479324._1
317+ let pmtAssetNameA = $t092479324._2
318+ let pmtDecimalsA = $t092479324._3
319+ let $t093299406 = getAssetInfo(pmtAssetIdB)
320+ let pmtStrAssetIdB = $t093299406._1
321+ let pmtAssetNameB = $t093299406._2
322+ let pmtDecimalsB = $t093299406._3
320323 if (isDefined(getBoolean(this, kActive)))
321324 then throwIsActive()
322325 else if ((pmtAssetIdA == pmtAssetIdB))
323326 then throw("Assets must be different")
324327 else {
325328 let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
326329 let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
327330 let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
328331 let shareInitialSupply = fraction(pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN), pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN), pow(10, 0, shareDecimals, 0, 0, DOWN))
329332 let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
330333 let shareIssueId = calculateAssetId(shareIssue)
331334 let invariantCalculated = invariantCalc(pmtAmountA, pmtAmountB)
332-[StringEntry(kVersion, version), BooleanEntry(kActive, true), StringEntry(kAssetIdA, pmtStrAssetIdA), StringEntry(kAssetIdB, pmtStrAssetIdB), IntegerEntry(kBalanceA, pmtAmountA), IntegerEntry(kBalanceB, pmtAmountB), IntegerEntry(kInvariant, invariantCalculated), IntegerEntry(kFee, fee), IntegerEntry(kFeeScaleDelimiter, feeScale6), shareIssue, StringEntry(kShareAssetId, toBase58String(shareIssueId)), IntegerEntry(kShareAssetSupply, shareInitialSupply), ScriptTransfer(i.caller, shareInitialSupply, shareIssueId)]
335+ let stake1 = if (containsElement(stakingAssets, pmtStrAssetIdA))
336+ then invoke(this, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
337+ else 0
338+ if ((stake1 == stake1))
339+ then {
340+ let stake2 = if (containsElement(stakingAssets, pmtStrAssetIdB))
341+ then invoke(this, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
342+ else 0
343+ if ((stake2 == stake2))
344+ then [StringEntry(kVersion, version), BooleanEntry(kActive, true), StringEntry(kAssetIdA, pmtStrAssetIdA), StringEntry(kAssetIdB, pmtStrAssetIdB), IntegerEntry(kBalanceA, pmtAmountA), IntegerEntry(kBalanceB, pmtAmountB), IntegerEntry(kInvariant, invariantCalculated), IntegerEntry(kFee, fee), IntegerEntry(kFeeScaleDelimiter, feeScale6), shareIssue, StringEntry(kShareAssetId, toBase58String(shareIssueId)), IntegerEntry(kShareAssetSupply, shareInitialSupply), ScriptTransfer(i.caller, shareInitialSupply, shareIssueId)]
345+ else throw("Strict value is not equal to itself.")
346+ }
347+ else throw("Strict value is not equal to itself.")
333348 }
334349 }
335350
336351
337352
338353 @Callable(i)
339354 func replenishWithTwoTokens (slippageTolerance) = {
340355 let pmtAssetIdA = i.payments[0].assetId
341356 let pmtAssetIdB = i.payments[1].assetId
342- let pmtAmountA = deductStakingFee(i.payments[0].amount, pmtAssetIdA)
343- let pmtAmountB = deductStakingFee(i.payments[1].amount, pmtAssetIdB)
357+ let pmtAmountA = i.payments[0].amount
358+ let pmtAmountB = i.payments[1].amount
359+ let $t01192211999 = getAssetInfo(pmtAssetIdA)
360+ let pmtStrAssetIdA = $t01192211999._1
361+ let pmtAssetNameA = $t01192211999._2
362+ let pmtDecimalsA = $t01192211999._3
363+ let $t01200412198 = getAssetInfo(pmtAssetIdB)
364+ let pmtStrAssetIdB = $t01200412198._1
365+ let pmtAssetNameB = $t01200412198._2
366+ let pmtDecimalsB = $t01200412198._3
344367 let tokenRatio = fraction(fraction(scale8, balanceA, pmtAmountA), scale3, fraction(scale8, balanceB, pmtAmountB))
345368 let ratioShareTokensInA = fraction(scale8, pmtAmountA, balanceA)
346369 let ratioShareTokensInB = fraction(scale8, pmtAmountB, balanceB)
347370 let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scale8)
348371 let invariantCalculated = invariantCalc((balanceA + pmtAmountA), (balanceB + pmtAmountB))
349372 if (!(isActive))
350373 then throwIsInactive()
351374 else if (if ((0 > slippageTolerance))
352375 then true
353376 else (slippageTolerance > 10))
354377 then throw("Slippage tolerance must be <= 1%")
355378 else if ((size(i.payments) != 2))
356379 then throw("Two attached assets expected")
357380 else if (if ((pmtAssetIdA != assetIdA))
358381 then true
359382 else (pmtAssetIdB != assetIdB))
360383 then throwAssets()
361384 else if (if ((((scale3 * (slippageScale3 - slippageTolerance)) / slippageScale3) > tokenRatio))
362385 then true
363386 else (tokenRatio > ((scale3 * (slippageScale3 + slippageTolerance)) / slippageScale3)))
364387 then throw("Incorrect assets amount: amounts must have the contract ratio")
365388 else if ((shareTokenToPayAmount == 0))
366389 then throw("Too small amount to replenish")
367390 else if (!(hasEnoughBalance))
368391 then ([ScriptTransfer(i.caller, pmtAmountA, pmtAssetIdA), ScriptTransfer(i.caller, pmtAmountB, pmtAssetIdB)] ++ suspendSuspicious())
369- else [IntegerEntry(kBalanceA, (balanceA + pmtAmountA)), IntegerEntry(kBalanceB, (balanceB + pmtAmountB)), IntegerEntry(kShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), IntegerEntry(kInvariant, invariantCalculated), Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId)]
392+ else {
393+ let stake1 = if (containsElement(stakingAssets, pmtStrAssetIdA))
394+ then invoke(this, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
395+ else 0
396+ if ((stake1 == stake1))
397+ then {
398+ let stake2 = if (containsElement(stakingAssets, pmtStrAssetIdB))
399+ then invoke(this, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
400+ else 0
401+ if ((stake2 == stake2))
402+ then [IntegerEntry(kBalanceA, (balanceA + pmtAmountA)), IntegerEntry(kBalanceB, (balanceB + pmtAmountB)), IntegerEntry(kShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), IntegerEntry(kInvariant, invariantCalculated), Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId)]
403+ else throw("Strict value is not equal to itself.")
404+ }
405+ else throw("Strict value is not equal to itself.")
406+ }
370407 }
371408
372409
373410
374411 @Callable(i)
375412 func replenishWithOneToken (virtualSwapTokenPay,virtualSwapTokenGet) = {
376- let $t01341013485 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
377- let pmtAmount = $t01341013485._1
378- let pmtAssetId = $t01341013485._2
413+ let $t01449714572 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
414+ let pmtAmount = $t01449714572._1
415+ let pmtAssetId = $t01449714572._2
416+ let $t01457714650 = getAssetInfo(pmtAssetId)
417+ let pmtStrAssetId = $t01457714650._1
418+ let pmtAssetName = $t01457714650._2
419+ let pmtDecimals = $t01457714650._3
379420 let pmtMinThreshold = 5000000
380421 let thresholdValueForMinTolerance = 50000000
381422 let tolerance = if ((thresholdValueForMinTolerance > pmtAmount))
382423 then 100000
383424 else 1
384425 let slippageValueMinForReplenish = (scale8 - ((scale8 * tolerance) / 10000000))
385426 let slippageValueMaxForReplenish = (scale8 + ((scale8 * tolerance) / 10000000))
386427 let slippageValueMinForSwap = (scale8 - ((scale8 * 1) / 10000000))
387428 if (!(isActive))
388429 then throwIsInactive()
389430 else if ((pmtMinThreshold > pmtAmount))
390431 then throw((((("Payment amount " + toString(pmtAmount)) + " does not exceed the minimum amount of ") + toString(pmtMinThreshold)) + " tokens"))
391432 else if ((size(i.payments) != 1))
392433 then throw("One attached payment expected")
393434 else if (!(hasEnoughBalance))
394435 then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
395436 else if (if ((pmtAssetId != assetIdA))
396437 then (pmtAssetId != assetIdB)
397438 else false)
398439 then throwAssets()
399440 else {
400- let $t01449715262 = if ((pmtAssetId == assetIdA))
441+ let $t01566216427 = if ((pmtAssetId == assetIdA))
401442 then $Tuple7((pmtAmount - virtualSwapTokenPay), virtualSwapTokenGet, (balanceA + virtualSwapTokenPay), (balanceB - virtualSwapTokenGet), invariantCalc((balanceA + pmtAmount), balanceB), (balanceA + pmtAmount), balanceB)
402443 else $Tuple7(virtualSwapTokenGet, (pmtAmount - virtualSwapTokenPay), (balanceA - virtualSwapTokenGet), (balanceB + virtualSwapTokenPay), invariantCalc(balanceA, (balanceB + pmtAmount)), balanceA, (balanceB + pmtAmount))
403- let virtualReplenishA = $t01449715262._1
404- let virtualReplenishB = $t01449715262._2
405- let balanceAfterSwapA = $t01449715262._3
406- let balanceAfterSwapB = $t01449715262._4
407- let invariantCalculated = $t01449715262._5
408- let newBalanceA = $t01449715262._6
409- let newBalanceB = $t01449715262._7
444+ let virtualReplenishA = $t01566216427._1
445+ let virtualReplenishB = $t01566216427._2
446+ let balanceAfterSwapA = $t01566216427._3
447+ let balanceAfterSwapB = $t01566216427._4
448+ let invariantCalculated = $t01566216427._5
449+ let newBalanceA = $t01566216427._6
450+ let newBalanceB = $t01566216427._7
410451 let newBalanceEntry = if ((pmtAssetId == assetIdA))
411452 then IntegerEntry(kBalanceA, newBalanceA)
412453 else IntegerEntry(kBalanceB, newBalanceB)
413454 let invariantNew = invariantCalc(balanceAfterSwapA, balanceAfterSwapB)
414455 let invariantEstimatedRatio = fraction(scale8, invariant, invariantNew)
415456 let ratioVirtualBalanceToVirtualReplenish = (fraction((scale8 * scale8), balanceAfterSwapA, balanceAfterSwapB) / fraction(scale8, virtualReplenishA, virtualReplenishB))
416457 let dAppThresholdAmount = fraction((newBalanceA + newBalanceB), dAppThreshold, (2 * dAppThresholdScale2))
417458 if (if ((slippageValueMinForSwap >= invariantEstimatedRatio))
418459 then true
419460 else (invariant > invariantNew))
420461 then throw("Incorrect virtualSwapTokenPay or virtualSwapTokenGet value")
421462 else if (if ((slippageValueMinForReplenish > ratioVirtualBalanceToVirtualReplenish))
422463 then true
423464 else (ratioVirtualBalanceToVirtualReplenish > slippageValueMaxForReplenish))
424465 then throw("Swap with virtualSwapTokenPay and virtualSwapTokenGet is possible, but ratio after virtual swap is incorrect")
425466 else if (if ((dAppThresholdAmount > newBalanceA))
426467 then true
427468 else (dAppThresholdAmount > newBalanceB))
428469 then throwThreshold(dAppThresholdAmount, newBalanceA, newBalanceB)
429470 else {
430- let ratioShareTokensInA = fraction(deductStakingFee(virtualReplenishA, assetIdA), scale8, balanceAfterSwapA)
431- let ratioShareTokensInB = fraction(deductStakingFee(virtualReplenishB, assetIdB), scale8, balanceAfterSwapB)
432- let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scale8)
471+ let stake1 = if (containsElement(stakingAssets, pmtStrAssetId))
472+ then invoke(this, "stakeUnstake", [true, pmtAmount, pmtStrAssetId], nil)
473+ else 0
474+ if ((stake1 == stake1))
475+ then {
476+ let ratioShareTokensInA = fraction(virtualReplenishA, scale8, balanceAfterSwapA)
477+ let ratioShareTokensInB = fraction(virtualReplenishB, scale8, balanceAfterSwapB)
478+ let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scale8)
433479 [Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId), IntegerEntry(kShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), newBalanceEntry, IntegerEntry(kInvariant, invariantCalculated)]
480+ }
481+ else throw("Strict value is not equal to itself.")
434482 }
435483 }
436484 }
437485
438486
439487
440488 @Callable(i)
441489 func withdraw () = {
442- let $t01740717550 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
443- let pmtAmount = $t01740717550._1
444- let pmtAssetId = $t01740717550._2
445- let amountToPayA = deductStakingFee(fraction(pmtAmount, balanceA, shareAssetSupply), assetIdA)
446- let amountToPayB = deductStakingFee(fraction(pmtAmount, balanceB, shareAssetSupply), assetIdB)
490+ let $t01865318796 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
491+ let pmtAmount = $t01865318796._1
492+ let pmtAssetId = $t01865318796._2
493+ let amountToPayA = fraction(pmtAmount, balanceA, shareAssetSupply)
494+ let amountToPayB = fraction(pmtAmount, balanceB, shareAssetSupply)
447495 let invariantCalculated = invariantCalc((balanceA - amountToPayA), (balanceB - amountToPayB))
448496 if (!(isActive))
449497 then throwIsInactive()
450498 else if ((size(i.payments) != 1))
451499 then throw("One attached payment expected")
452500 else if ((pmtAssetId != shareAssetId))
453501 then throw(("Incorrect asset attached. Expected: " + toBase58String(shareAssetId)))
454502 else if (!(hasEnoughBalance))
455503 then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
456- else if (if ((amountToPayA > availableBalanceA))
457- then true
458- else (amountToPayB > availableBalanceB))
459- then throwInsufficientAvailableBalances(amountToPayA, amountToPayB)
460- else [IntegerEntry(kBalanceA, (balanceA - amountToPayA)), IntegerEntry(kBalanceB, (balanceB - amountToPayB)), IntegerEntry(kShareAssetSupply, (shareAssetSupply - pmtAmount)), IntegerEntry(kInvariant, invariantCalculated), Burn(shareAssetId, pmtAmount), ScriptTransfer(i.caller, amountToPayA, assetIdA), ScriptTransfer(i.caller, amountToPayB, assetIdB)]
504+ else {
505+ let stake1 = if (containsElement(stakingAssets, strAssetIdA))
506+ then invoke(this, "stakeUnstake", [false, amountToPayA, strAssetIdA], nil)
507+ else 0
508+ if ((stake1 == stake1))
509+ then {
510+ let stake2 = if (containsElement(stakingAssets, strAssetIdB))
511+ then invoke(this, "stakeUnstake", [false, amountToPayB, strAssetIdB], nil)
512+ else 0
513+ if ((stake2 == stake2))
514+ then [IntegerEntry(kBalanceA, (balanceA - amountToPayA)), IntegerEntry(kBalanceB, (balanceB - amountToPayB)), IntegerEntry(kShareAssetSupply, (shareAssetSupply - pmtAmount)), IntegerEntry(kInvariant, invariantCalculated), Burn(shareAssetId, pmtAmount), ScriptTransfer(i.caller, amountToPayA, assetIdA), ScriptTransfer(i.caller, amountToPayB, assetIdB)]
515+ else throw("Strict value is not equal to itself.")
516+ }
517+ else throw("Strict value is not equal to itself.")
518+ }
461519 }
462520
463521
464522
465523 @Callable(i)
466524 func exchange (estimatedAmountToReceive,minAmountToReceive) = {
467- let $t01890818983 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
468- let pmtAmount = $t01890818983._1
469- let pmtAssetId = $t01890818983._2
525+ let $t02031020385 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
526+ let pmtAmount = $t02031020385._1
527+ let pmtAssetId = $t02031020385._2
470528 if (!(isActive))
471529 then throwIsInactive()
472530 else if ((0 >= estimatedAmountToReceive))
473531 then throw(("Estimated amount must be positive. Actual: " + toString(estimatedAmountToReceive)))
474532 else if ((minAmountToReceive > estimatedAmountToReceive))
475533 then throw(((("Minimal amount can't be greater than estimated. Estimated: " + toString(estimatedAmountToReceive)) + ". Minimal: ") + toString(minAmountToReceive)))
476534 else if ((size(i.payments) != 1))
477535 then throw("One attached payment expected")
478536 else if (!(hasEnoughBalance))
479537 then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
480538 else if (if ((pmtAssetId != assetIdA))
481539 then (pmtAssetId != assetIdB)
482540 else false)
483541 then throwAssets()
484542 else if ((10000000 > pmtAmount))
485543 then throw("Only swap of 10.000000 or more tokens is allowed")
486544 else if (if ((exchangeRatioLimitMin > fraction(scale8, minAmountToReceive, pmtAmount)))
487545 then true
488546 else (fraction(scale8, estimatedAmountToReceive, pmtAmount) > exchangeRatioLimitMax))
489547 then throw("Incorrect args and pmt ratio")
490548 else {
491549 let sendAssetId = if ((pmtAssetId == assetIdA))
492550 then assetIdB
493551 else assetIdA
494552 let amount = calculateSendAmount(estimatedAmountToReceive, minAmountToReceive, pmtAmount, pmtAssetId)
495553 let governanceReward = fraction(amount, feeGovernance, feeScale6)
496554 let amountMinusFee = fraction(amount, (feeScale6 - fee), feeScale6)
497- let $t02040520667 = if ((pmtAssetId == assetIdA))
555+ let $t02180722069 = if ((pmtAssetId == assetIdA))
498556 then $Tuple2((balanceA + pmtAmount), ((balanceB - amountMinusFee) - governanceReward))
499557 else $Tuple2(((balanceA - amountMinusFee) - governanceReward), (balanceB + pmtAmount))
500- let newBalanceA = $t02040520667._1
501- let newBalanceB = $t02040520667._2
558+ let newBalanceA = $t02180722069._1
559+ let newBalanceB = $t02180722069._2
502560 let dAppThresholdAmount = fraction((newBalanceA + newBalanceB), dAppThreshold, (2 * dAppThresholdScale2))
503561 if (if ((dAppThresholdAmount > newBalanceA))
504562 then true
505563 else (dAppThresholdAmount > newBalanceB))
506564 then throwThreshold(dAppThresholdAmount, newBalanceA, newBalanceB)
507- else if (if (if ((assetIdA == USDN))
508- then (sendAssetId == assetIdA)
509- else false)
510- then (stakedAmountUSDN >= newBalanceA)
511- else false)
512- then throwInsufficientAvailableBalance(amountMinusFee, availableBalanceA, assetNameA)
513- else if (if (if ((assetIdB == USDN))
514- then (sendAssetId == assetIdB)
515- else false)
516- then (stakedAmountUSDN >= newBalanceB)
517- else false)
518- then throwInsufficientAvailableBalance(amountMinusFee, availableBalanceB, assetNameB)
519- else [IntegerEntry(kBalanceA, newBalanceA), IntegerEntry(kBalanceB, newBalanceB), IntegerEntry(kInvariant, invariantCalc(newBalanceA, newBalanceB)), ScriptTransfer(i.caller, amountMinusFee, sendAssetId), ScriptTransfer(govAddr, governanceReward, sendAssetId)]
565+ else {
566+ let $t02236722440 = getAssetInfo(pmtAssetId)
567+ let pmtStrAssetId = $t02236722440._1
568+ let pmtAssetName = $t02236722440._2
569+ let pmtDecimals = $t02236722440._3
570+ let $t02245322530 = getAssetInfo(sendAssetId)
571+ let sendStrAssetId = $t02245322530._1
572+ let sendAssetName = $t02245322530._2
573+ let sendDecimals = $t02245322530._3
574+ let stake1 = if (containsElement(stakingAssets, pmtStrAssetId))
575+ then invoke(this, "stakeUnstake", [true, pmtAmount, pmtStrAssetId], nil)
576+ else 0
577+ if ((stake1 == stake1))
578+ then {
579+ let stake2 = if (containsElement(stakingAssets, sendStrAssetId))
580+ then invoke(this, "stakeUnstake", [false, (amountMinusFee + governanceReward), sendStrAssetId], nil)
581+ else 0
582+ if ((stake2 == stake2))
583+ then [IntegerEntry(kBalanceA, newBalanceA), IntegerEntry(kBalanceB, newBalanceB), IntegerEntry(kInvariant, invariantCalc(newBalanceA, newBalanceB)), ScriptTransfer(i.caller, amountMinusFee, sendAssetId), ScriptTransfer(walletAddress, governanceReward, sendAssetId)]
584+ else throw("Strict value is not equal to itself.")
585+ }
586+ else throw("Strict value is not equal to itself.")
587+ }
520588 }
521589 }
522590
523591
524592
525593 @Callable(i)
526594 func shutdown () = if (!(isActive))
527595 then throw(("DApp is already suspended. Cause: " + valueOrElse(getString(this, kCause), "the cause wasn't specified")))
528- else if (!(containsElement([adm1, adm2, adm3, admStartStop], i.callerPublicKey)))
596+ else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, admStartStop], i.callerPublicKey)))
529597 then throwOnlyAdmin()
530598 else suspend("Paused by admin")
531599
532600
533601
534602 @Callable(i)
535603 func activate () = if (isActive)
536604 then throwIsActive()
537- else if (!(containsElement([adm1, adm2, adm3, admStartStop], i.callerPublicKey)))
605+ else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, admStartStop], i.callerPublicKey)))
538606 then throwOnlyAdmin()
539607 else [BooleanEntry(kActive, true), DeleteEntry(kCause)]
540608
541609
542610
543611 @Callable(i)
544-func takeIntoAccountExtraFunds (amountLeave) = {
545- let uncountableA = (accountBalanceWithStakedA - balanceA)
546- let uncountableB = (accountBalanceWithStakedB - balanceB)
547- let amountEnrollA = (uncountableA - (if ((assetIdA == unit))
548- then amountLeave
549- else 0))
550- let amountEnrollB = (uncountableB - (if ((assetIdB == unit))
551- then amountLeave
552- else 0))
612+func takeIntoAccountExtraFunds () = {
613+ let amountEnrollA = (accountBalanceWithStakedA - balanceA)
614+ let amountEnrollB = (accountBalanceWithStakedB - balanceB)
553615 let invariantNew = invariantCalc((balanceA + amountEnrollA), (balanceB + amountEnrollB))
554616 if (!(isActive))
555617 then throwIsInactive()
556- else if ((i.caller != this))
557- then throwOnlyAdmin()
558- else if ((0 > amountLeave))
559- then throw(("Argument 'amountLeave' cannot be negative. Actual: " + toString(amountLeave)))
560- else if (if ((0 > uncountableA))
561- then true
562- else (0 > uncountableB))
563- then suspend("Enroll amount negative")
564- else if (if ((0 > amountEnrollA))
565- then true
566- else (0 > amountEnrollB))
567- then throw("Too large amountLeave")
568- else [IntegerEntry(kInvariant, invariantNew), IntegerEntry(kBalanceA, (balanceA + amountEnrollA)), IntegerEntry(kBalanceB, (balanceB + amountEnrollB)), IntegerEntry(("last_income_" + strAssetIdA), amountEnrollA), IntegerEntry(("last_income_" + strAssetIdB), amountEnrollB)]
618+ else if ((i.caller != walletAddress))
619+ then throw("Only the wallet can call this function")
620+ else if (if ((0 > amountEnrollA))
621+ then true
622+ else (0 > amountEnrollB))
623+ then suspend("Enroll amount negative")
624+ else if (if ((amountEnrollA == 0))
625+ then (amountEnrollB == 0)
626+ else false)
627+ then throw("No money to take")
628+ else {
629+ let stake1 = if (if (containsElement(stakingAssets, strAssetIdA))
630+ then (amountEnrollA > 0)
631+ else false)
632+ then invoke(this, "stakeUnstake", [true, amountEnrollA, strAssetIdA], nil)
633+ else 0
634+ if ((stake1 == stake1))
635+ then {
636+ let stake2 = if (if (containsElement(stakingAssets, strAssetIdB))
637+ then (amountEnrollB > 0)
638+ else false)
639+ then invoke(this, "stakeUnstake", [true, amountEnrollB, strAssetIdB], nil)
640+ else 0
641+ if ((stake2 == stake2))
642+ then [IntegerEntry(kInvariant, invariantNew), IntegerEntry(kBalanceA, (balanceA + amountEnrollA)), IntegerEntry(kBalanceB, (balanceB + amountEnrollB)), IntegerEntry(("last_income_" + strAssetIdA), amountEnrollA), IntegerEntry(("last_income_" + strAssetIdB), amountEnrollB)]
643+ else throw("Strict value is not equal to itself.")
644+ }
645+ else throw("Strict value is not equal to itself.")
646+ }
569647 }
570648
571649
650+
651+@Callable(i)
652+func stakeUnstake (stake,amount,assetIdString) = if ((i.caller != this))
653+ then throw("Only contract itself can invoke this function")
654+ else {
655+ let $t02559225695 = calcStakingParams(stake, amount, fromBase58String(assetIdString))
656+ let call = $t02559225695._1
657+ let addr = $t02559225695._2
658+ let params = $t02559225695._3
659+ let payments = $t02559225695._4
660+ let inv = invoke(addr, call, params, payments)
661+ if ((inv == inv))
662+ then nil
663+ else throw("Strict value is not equal to itself.")
664+ }
665+
666+
667+
668+@Callable(i)
669+func stakeAll () = if (!(isActive))
670+ then throw("DApp is inactive at this moment")
671+ else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, admStartStop], i.callerPublicKey)))
672+ then throw("Only admin can call this function")
673+ else {
674+ let stake1 = if (containsElement(stakingAssets, strAssetIdA))
675+ then {
676+ let amountA = (balanceA - stakedAmountA)
677+ if ((amountA > 0))
678+ then invoke(this, "stakeUnstake", [true, amountA, strAssetIdA], nil)
679+ else 0
680+ }
681+ else 0
682+ if ((stake1 == stake1))
683+ then {
684+ let stake2 = if (containsElement(stakingAssets, strAssetIdB))
685+ then {
686+ let amountB = (balanceB - stakedAmountB)
687+ if ((amountB > 0))
688+ then invoke(this, "stakeUnstake", [true, amountB, strAssetIdB], nil)
689+ else 0
690+ }
691+ else 0
692+ if ((stake2 == stake2))
693+ then nil
694+ else throw("Strict value is not equal to itself.")
695+ }
696+ else throw("Strict value is not equal to itself.")
697+ }
698+
699+
572700 @Verifier(tx)
573-func verify () = match tx {
574- case inv: InvokeScriptTransaction =>
575- let callTakeIntoAccount = if ((inv.dApp == this))
576- then (inv.function == "takeIntoAccountExtraFunds")
577- else false
578- let callStaking = if ((inv.dApp == stakingAddress))
579- then if (if (if ((inv.function == "lockNeutrino"))
580- then (size(inv.payments) == 1)
581- else false)
582- then (inv.payments[0].assetId == USDN)
701+func verify () = {
702+ let multiSignedByAdmins = {
703+ let adminPubKey1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
704+ then 1
705+ else 0
706+ let adminPubKey2Signed = if (sigVerify(tx.bodyBytes, tx.proofs[1], adminPubKey2))
707+ then 1
708+ else 0
709+ let adminPubKey3Signed = if (sigVerify(tx.bodyBytes, tx.proofs[2], adminPubKey3))
710+ then 1
711+ else 0
712+ (((adminPubKey1Signed + adminPubKey2Signed) + adminPubKey3Signed) >= 2)
713+ }
714+ match tx {
715+ case inv: InvokeScriptTransaction =>
716+ let callTakeIntoAccount = if ((inv.dApp == this))
717+ then (inv.function == "takeIntoAccountExtraFunds")
718+ else false
719+ let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
720+ then true
721+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey2))
722+ then true
723+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey3))
724+ then true
725+ else sigVerify(tx.bodyBytes, tx.proofs[0], admStaking)
726+ if (if (callTakeIntoAccount)
727+ then signedByAdmin
583728 else false)
584729 then true
585- else if ((inv.function == "unlockNeutrino"))
586- then (size(inv.payments) == 0)
587- else false
588- else false
589- let exchangeToWaves = if (if (if ((inv.dApp == USDNToWavesExchanger))
590- then (inv.function == "exchange")
591- else false)
592- then (assetIdA == USDN)
593- else false)
594- then true
595- else if (if ((assetIdB == USDN))
596- then (size(inv.payments) == 1)
597- else false)
598- then (inv.payments[0].assetId == USDN)
599- else false
600- let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adm1))
601- then true
602- else sigVerify(tx.bodyBytes, tx.proofs[0], adm2))
603- then true
604- else sigVerify(tx.bodyBytes, tx.proofs[0], adm3))
605- then true
606- else sigVerify(tx.bodyBytes, tx.proofs[0], admStaking)
607- if (if (if (callTakeIntoAccount)
608- then true
609- else callStaking)
610- then true
611- else exchangeToWaves)
612- then signedByAdmin
613- else false
614- case _ =>
615- let adm1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adm1))
616- then 1
617- else 0
618- let adm2Signed = if (sigVerify(tx.bodyBytes, tx.proofs[1], adm2))
619- then 1
620- else 0
621- let adm3Signed = if (sigVerify(tx.bodyBytes, tx.proofs[2], adm3))
622- then 1
623- else 0
624- (((adm1Signed + adm2Signed) + adm3Signed) >= 2)
625-}
730+ else multiSignedByAdmins
731+ case _ =>
732+ multiSignedByAdmins
733+ }
734+ }
626735

github/deemru/w8io/6500d08 
106.35 ms