tx · CD3W59r2172hSBAB717FDg8xMPLgSDLaPhkaoT6JmpuR

3Mr7EqUGMZjUPmZjiU4zaDR7WA3J5tJhfLA:  -0.01400000 Waves

2022.01.31 17:19 [1903224] smart account 3Mr7EqUGMZjUPmZjiU4zaDR7WA3J5tJhfLA > SELF 0.00000000 Waves

{ "type": 13, "id": "CD3W59r2172hSBAB717FDg8xMPLgSDLaPhkaoT6JmpuR", "fee": 1400000, "feeAssetId": null, "timestamp": 1643638783514, "version": 2, "chainId": 84, "sender": "3Mr7EqUGMZjUPmZjiU4zaDR7WA3J5tJhfLA", "senderPublicKey": "2XZLpZpmAaP6QkvSq4YC6rz8ckckZ3KcqJitrdDV4r9P", "proofs": [ "62gpLmDNhPYSTNeeiRcLoZ96atL8CXuGDQhnT7LgbfWbRwjMqbWyxfEhmDYdxH3Aw9KMuHXnFfX919p4kRRK8fLq", "31uWBPkD1FJrLsVpoMnABGKLrtufpL9NvMNykyqzjwwwT18r5zxCbvpW4DyNMfStLkvQSqRqcdpMLPG6ykCWak2n" ], "script": "base64:AAIFAAAAAAAAACYIAhIAEgMKAQESBAoCAQESABIECgIBARIAEgASABIFCgMEAQgSAAAAAFIAAAAAB3ZlcnNpb24CAAAABTIuMC4wAAAAAAhrVmVyc2lvbgIAAAAHdmVyc2lvbgAAAAAHa0FjdGl2ZQIAAAAGYWN0aXZlAAAAAAlrQXNzZXRJZEECAAAACkFfYXNzZXRfaWQAAAAACWtBc3NldElkQgIAAAAKQl9hc3NldF9pZAAAAAAJa0JhbGFuY2VBAgAAAA9BX2Fzc2V0X2JhbGFuY2UAAAAACWtCYWxhbmNlQgIAAAAPQl9hc3NldF9iYWxhbmNlAAAAAA1rU2hhcmVBc3NldElkAgAAAA5zaGFyZV9hc3NldF9pZAAAAAARa1NoYXJlQXNzZXRTdXBwbHkCAAAAEnNoYXJlX2Fzc2V0X3N1cHBseQAAAAAEa0ZlZQIAAAAKY29tbWlzc2lvbgAAAAASa0ZlZVNjYWxlRGVsaW1pdGVyAgAAABpjb21taXNzaW9uX3NjYWxlX2RlbGltaXRlcgAAAAAKa0ludmFyaWFudAIAAAAJaW52YXJpYW50AAAAAAZrQ2F1c2UCAAAADnNodXRkb3duX2NhdXNlAAAAABJrZXlVU0ROTlNCVEFkZHJlc3MCAAAAGHN0YWtpbmdfdXNkbm5zYnRfYWRkcmVzcwAAAAAOa2V5RVVSTkFkZHJlc3MCAAAAFHN0YWtpbmdfZXVybl9hZGRyZXNzAAAAAA9rZXlBZG1pblB1YktleTECAAAAC2FkbWluX3B1Yl8xAAAAAA9rZXlBZG1pblB1YktleTICAAAAC2FkbWluX3B1Yl8yAAAAAA9rZXlBZG1pblB1YktleTMCAAAAC2FkbWluX3B1Yl8zAAAAABRVU0ROVG9XYXZlc0V4Y2hhbmdlcgkBAAAAB0FkZHJlc3MAAAABAQAAABoBVMqWqf/XBTJ3J/JFLr/QiofqrY4qyL+FtAAAAAAGb3JhY2xlCQEAAAAHQWRkcmVzcwAAAAEBAAAAGgFU6UWqHpAvOq7xug7mLpqSXxqYhOHzYrMIAQAAAAtnZXRBZG1pblB1YgAAAAEAAAALa2V5QWRtaW5QdWIEAAAAByRtYXRjaDAJAAQdAAAAAgUAAAAGb3JhY2xlBQAAAAtrZXlBZG1pblB1YgMJAAABAAAAAgUAAAAH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ATYAAAABBQAAAAdzY2FsZTEyAQAAABNjYWxjdWxhdGVTZW5kQW1vdW50AAAABAAAABVhbW91bnRUb1NlbmRFc3RpbWF0ZWQAAAAVbWluVG9rZW5SZWNlaXZlQW1vdW50AAAAEnRva2VuUmVjZWl2ZUFtb3VudAAAAAd0b2tlbklkBAAAAA1zbGlwcGFnZVZhbHVlCQAAZQAAAAIFAAAABnNjYWxlOAkAAGkAAAACCQAAaAAAAAIFAAAABnNjYWxlOAAAAAAAAAAAAQAAAAAAAJiWgAQAAAAeZGVsdGFCZXR3ZWVuTWF4QW5kTWluU2VuZFZhbHVlCQAAZQAAAAIFAAAAFWFtb3VudFRvU2VuZEVzdGltYXRlZAUAAAAVbWluVG9rZW5SZWNlaXZlQW1vdW50BAAAAAF4CQAAZAAAAAIFAAAACGJhbGFuY2VBBQAAABJ0b2tlblJlY2VpdmVBbW91bnQEAAAAAXkJAABkAAAAAgUAAAAIYmFsYW5jZUIFAAAAEnRva2VuUmVjZWl2ZUFtb3VudAQAAAAMaW52YXJpYW50TmV3AwkAAAAAAAACBQAAAAd0b2tlbklkBQAAAAhhc3NldElkQQkBAAAADWludmFyaWFudENhbGMAAAACBQAAAAF4CQAAZQAAAAIFAAAACGJhbGFuY2VCBQAAABVhbW91bnRUb1NlbmRFc3RpbWF0ZWQDCQAAAAAAAAIFAAAAB3Rva2VuSWQFAAAACGFzc2V0SWRCCQEAAAANaW52YXJpYW50Q2FsYwAAAAIJAABlAAAAAgUAAAAIYmFsYW5jZUEFAAAAFWFtb3VudFRvU2VuZEVzdGltYXRlZAUAAAABeQkAAAIAAAABAgAAABZXcm9uZyBhc3NldCBpbiBwYXltZW50BAAAABdpbnZhcmlhbnRFc3RpbWF0ZWRSYXRpbwkAAGsAAAADBQAAAAZzY2FsZTgFAAAACWludmFyaWFudAUAAAAMaW52YXJpYW50TmV3CgEAAAANZ2V0U3RlcEFtb3VudAAAAAIAAAADYWNjAAAABHN0ZXADCQAAAAAAAAIFAAAAA2FjYwD//////////wQAAAAMYW1vdW50VG9TZW5kCQAAZQAAAAIFAAAAFWFtb3VudFRvU2VuZEVzdGltYXRlZAkAAGkAAAACCQAAaAAAAAIFAAAABHN0ZXAFAAAA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bGNTdGFraW5nRnVuY0FuZEFkZHJlcwAAAAIAAAAFc3Rha2UAAAAHYXNzZXRJZAMFAAAABXN0YWtlAwkAAAAAAAACBQAAAAdhc3NldElkBQAAAARVU0ROCQAFFAAAAAICAAAADGxvY2tOZXV0cmlubwUAAAAWc3Rha2luZ1VTRE5OU0JUQWRkcmVzcwkABRQAAAACAgAAAAxzdGFydFN0YWtpbmcFAAAAEnN0YWtpbmdFVVJOQWRkcmVzcwMJAAAAAAAAAgUAAAAHYXNzZXRJZAUAAAAEVVNETgkABRQAAAACAgAAAA51bmxvY2tOZXV0cmlubwUAAAAWc3Rha2luZ1VTRE5OU0JUQWRkcmVzcwkABRQAAAACAgAAAAtzdG9wU3Rha2luZwUAAAASc3Rha2luZ0VVUk5BZGRyZXNzAQAAABFjYWxjU3Rha2luZ1BhcmFtcwAAAAMAAAAFc3Rha2UAAAAGYW1vdW50AAAAB2Fzc2V0SWQDBQAAAAVzdGFrZQQAAAALJHQwODkyOTg5OTUJAQAAABhjYWxjU3Rha2luZ0Z1bmNBbmRBZGRyZXMAAAACBQAAAAVzdGFrZQUAAAAHYXNzZXRJZAQAAAAEY2FsbAgFAAAACyR0MDg5Mjk4OTk1AAAAAl8xBAAAAAtzdGFraW5nQWRkcggFAAAACyR0MDg5Mjk4OTk1AAAAAl8yCQAFFgAAAAQFAAAABGNhbGwFAAAAC3N0YWtpbmdBZGRyBQAAAANuaWwJAARMAAAAAgkBAAAAD0F0dGFjaGVkUGF5bWVudAAAAAIFAAAAB2Fzc2V0SWQFAAAABmFtb3VudAUAAAADbmlsBAAAAAskdDA5MDgxOTE0NwkBAAAAGGNhbGNTdGFraW5nRnVuY0FuZEFkZHJlcwAAAAIFAAAABXN0YWtlBQAAAAdhc3NldElkBAAAAARjYWxsCAUAAAALJHQwOTA4MTkxNDcAAAACXzEEAAAAC3N0YWtpbmdBZGRyCAUAAAALJHQwOTA4MTkxNDcAAAACXzIJAAUWAAAABAUAAAAEY2FsbAUAAAALc3Rha2luZ0FkZHIJAARMAAAAAgUAAAAGYW1vdW50CQAETAAAAAIJAAJYAAAAAQUAAAAHYXNzZXRJZAUAAAADbmlsBQAAAANuaWwAAAAKAAAAAWkBAAAABGluaXQAAAAABAAAAAsk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ZWxpbWl0ZXIFAAAACWZlZVNjYWxlNgkABEwAAAACBQAAAApzaGFyZUlzc3VlCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAADWtTaGFyZUFzc2V0SWQJAAJYAAAAAQUAAAAMc2hhcmVJc3N1ZUlkCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABFrU2hhcmVBc3NldFN1cHBseQUAAAASc2hhcmVJbml0aWFsU3VwcGx5CQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAASc2hhcmVJbml0aWFsU3VwcGx5BQAAAAxzaGFyZUlzc3VlSWQFAAAAA25pbAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAAAAAWkBAAAAFnJlcGxlbmlzaFdpdGhUd29Ub2tlbnMAAAABAAAAEXNsaXBwYWdlVG9sZXJhbmNlBAAAAAtwbXRBc3NldElkQQgJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAAAAAHYXNzZXRJZAQAAAALcG10QXNzZXRJZEIICQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAABAAAAB2Fzc2V0SWQEAAAACnBtdEFtb3VudEEICQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAAAAAABmFtb3VudAQAAAAKcG10QW1vdW50QggJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAEAAAAGYW1vdW50BAAAAA0kdDAxMjA5MTEyMTY4CQEAAAAMZ2V0QXNzZXRJbmZvAAAAAQUAAAALcG10QXNzZXRJZEEEAAAADnBtdFN0ckFzc2V0SWRBCAUAAAANJHQwMTIwOTExMjE2OAAAAAJfMQQAAAANcG10QXNzZXROYW1lQQgFAAAADSR0MDEyMDkxMTIxNjgAAAACXzIEAAAADHBtdERlY2ltYWxzQQgFAAAADSR0MDEyMDkxMTIxNjgAAAACXzMEAAAADSR0MDEyMTczMTIzNjcJAQAAAAxnZXRBc3NldEluZm8AAAABBQAAAAtwbXRBc3NldElkQgQAAAAOcG10U3RyQXNzZXRJZEIIBQAAAA0kdDAxMjE3MzEyMzY3AAAAAl8xBAAAAA1wbXRBc3NldE5hbWVCCAUAAAANJHQwMTIxNzMxMjM2NwAAAAJfMgQAAAAMcG10RGVjaW1hbHNCCAUAAAANJHQwMTIxNzMxMjM2NwAAAAJfMwQAAAAKdG9rZW5SYXRpbwkAAGsAAAADCQAAawAAAAMFAAAABnNjYWxlOAUAAAAIYmFsYW5jZUEFAAAACnBtdEFtb3VudEEFAAAABnNjYWxlMwkAAGsAAAADBQAAAAZzY2FsZTgFAAAACGJhbGFuY2VCBQAAAApwbXRBbW91bnRCBAAAABNyYXRpb1NoYXJlVG9rZW5zSW5BCQAAawAAAAMFAAAABnNjYWxlOAUAAAAKcG10QW1vdW50QQUAAAAIYmFsYW5jZUEEAAAAE3JhdGlvU2hhcmVUb2tlbnNJbkIJAABrAAAAAwUAAAAGc2NhbGU4BQAAAApwbXRBbW91bnRCBQAAAAhiYWxhbmNlQgQAAAAVc2hhcmVUb2tlblRvUGF5QW1vdW50CQAAawAAAAMJAAGXAAAAAQkABEwAAAACBQAAABNyYXRpb1NoYXJlVG9rZW5zSW5BCQAETAAAAAIFAAAAE3JhdGlvU2hhcmVUb2tlbnNJbkIFAAAAA25pbAUAAAAQc2hhcmVBc3NldFN1cHBseQUAAAAGc2NhbGU4BAAAABNpbnZhcmlhbnRDYWxjdWxhdGVkCQEAAAANaW52YXJpYW50Q2FsYwAAAAIJAABkAAAAAgUAAAAIYmFsYW5jZUEFAAAACnBtdEFtb3VudEEJAABkAAAAAgUAAAAIYmFsYW5jZUIFAAAACnBtdEFtb3VudEIDCQEAAAABIQAAAAEFAAAACGlzQWN0aXZlCQEAAAAPdGhyb3dJc0luYWN0aXZlAAAAAAMDCQAAZgAAAAIAAAAAAAAAAAAFAAAAEXNsaXBwYWdlVG9sZXJhbmNlBgkAAGYAAAACBQAAABFzbGlwcGFnZVRvbGVyYW5jZQAAAAAAAAAACgkAAAIAAAABAgAAACBTbGlwcGFnZSB0b2xlcmFuY2UgbXVzdCBiZSA8PSAxJQMJAQAAAAIhPQAAAAIJAAGQAAAAAQgFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAIJAAACAAAAAQIAAAAcVHdvIGF0dGFjaGVkIGFzc2V0cyBleHBlY3RlZAMDCQEAAAACIT0AAAACBQAAAAtwbXRBc3NldElkQQUAAAAIYXNzZXRJZEEGCQEAAAACIT0AAAACBQAAAAtwbXRBc3NldElkQgUAAAAIYXNzZXRJZEIJAQAAAAt0aHJvd0Fzc2V0cwAAAAADAwkAAGYAAAACCQAAaQAAAAIJAABoAAAAAgUAAAAGc2NhbGUzCQAAZQAAAAIFAAAADnNsaXBwYWdlU2NhbGUzBQAAABFzbGlwcGFnZVRvbGVyYW5jZQUAAAAOc2xpcHBhZ2VTY2FsZTMFAAAACnRva2VuUmF0aW8GCQAAZgAAAAIFAAAACnRva2VuUmF0aW8JAABpAAAAAgkAAGgAAAACBQAAAAZzY2FsZTMJAABkAAAAAgUAAAAOc2xpcHBhZ2VTY2FsZTMFAAAAEXNsaXBwYWdlVG9sZXJhbmNlBQAAAA5zbGlwcGFnZVNjYWxlMwkAAAIAAAABAgAAAD1JbmNvcnJlY3QgYXNzZXRzIGFtb3VudDogYW1vdW50cyBtdXN0IGhhdmUgdGhlIGNvbnRyYWN0IHJhdGlvAwkAAAAAAAACBQAAABVzaGFyZVRva2VuVG9QYXlBbW91bnQAAAAAAAAAAAAJAAACAAAAAQIAAAAdVG9vIHNtYWxsIGFtb3VudCB0byByZXBsZW5pc2gDCQEAAAABIQAAAAEFAAAAEGhhc0Vub3VnaEJhbGFuY2UJAAROAAAAAgkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIFAAAACnBtdEFtb3VudEEFAAAAC3BtdEFzc2V0SWRBCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAAKcG10QW1vdW50QgUAAAALcG10QXNzZXRJZEIFAAAAA25pbAkBAAAAEXN1c3BlbmRTdXNwaWNpb3VzAAAAAAQAAAAGc3Rha2UxAwkBAAAAD2NvbnRhaW5zRWxlbWVudAAAAAIFAAAADXN0YWtpbmdBc3NldHMFAAAADnBtdFN0ckFzc2V0SWRBCQAD/AAAAAQFAAAABHRoaXMCAAAADHN0YWtlVW5zdGFrZQkABEwAAAACBgkABEwAAAACBQAAAApwbXRBbW91bnRBCQAETAAAAAIFAAAADnBtdFN0ckFzc2V0SWRBBQAAAANuaWwFAAAAA25pbAAAAAAAAAAAAAMJAAAAAAAAAgUAAAAGc3Rha2UxBQAAAAZzdGFrZTEEAAAABnN0YWtlMgMJAQAAAA9jb250YWluc0VsZW1lbnQAAAACBQAAAA1zdGFraW5nQXNzZXRzBQAAAA5wbXRTdHJBc3NldElkQgkAA/wAAAAEBQAAAAR0aGlzAgAAAAxzdGFrZVVuc3Rha2UJAARMAAAAAgYJAARMAAAAAgUAAAAKcG10QW1vdW50QgkABEwAAAACBQAAAA5wbXRTdHJBc3NldElkQgUAAAADbmlsBQAAAANuaWwAAAAAAAAAAAADCQAAAAAAAAIFAAAABnN0YWtlMgUAAAAGc3Rha2UyCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAlrQmFsYW5jZUEJAABkAAAAAgUAAAAIYmFsYW5jZUEFAAAACnBtdEFtb3VudEEJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAACWtCYWxhbmNlQgkAAGQAAAACBQAAAAhiYWxhbmNlQgUAAAAKcG10QW1vdW50QgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAARa1NoYXJlQXNzZXRTdXBwbHkJAABkAAAAAgUAAAAQc2hhcmVBc3NldFN1cHBseQUAAAAVc2hhcmVUb2tlblRvUGF5QW1vdW50CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAprSW52YXJpYW50BQAAABNpbnZhcmlhbnRDYWxjdWxhdGVkCQAETAAAAAIJAQAAAAdSZWlzc3VlAAAAAwUAAAAMc2hhcmVBc3NldElkBQAAABVzaGFyZVRva2VuVG9QYXlBbW91bnQGCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAAVc2hhcmVUb2tlblRvUGF5QW1vdW50BQAAAAxzaGFyZUFzc2V0SWQFAAAAA25pbAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAAAAAWkBAAAAFXJlcGxlbmlzaFdpdGhPbmVUb2tlbgAAAAIAAAATdmlydHVhbFN3YXBUb2tlblBheQAAABN2aXJ0dWFsU3dhcFRva2VuR2V0BAAAAA0kdDAxNDY2NjE0NzQxCQAFFAAAAAIICQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAAAAAABmFtb3VudAgJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAAAAAHYXNzZXRJZAQAAAAJcG10QW1vdW50CAUAAAANJHQwMTQ2NjYxNDc0MQAAAAJfMQQAAAAKcG10QXNzZXRJZAgFAAAADSR0MDE0NjY2MTQ3NDEAAAACXzIEAAAADSR0MDE0NzQ2MTQ4MTkJAQAAAAxnZXRBc3NldEluZm8AAAABBQAAAApwbXRBc3NldElkBAAAAA1wbXRTdHJBc3NldElkCAUAAAANJHQwMTQ3NDYxNDgxOQAAAAJfMQQAAAAMcG10QXNzZXROYW1lCAUAAAANJHQwMTQ3NDYxNDgxOQAAAAJfMgQAAAALcG10RGVjaW1hbHMIBQAAAA0kdDAxNDc0NjE0ODE5AAAAAl8zBAAAAA9wbXRNaW5UaHJlc2hvbGQAAAAAAABMS0AEAAAAHXRocmVzaG9sZFZhbHVlRm9yTWluVG9sZXJhbmNlAAAAAAAC+vCABAAAAAl0b2xlcmFuY2UDCQAAZgAAAAIFAAAAHXRocmVzaG9sZFZhbHVlRm9yTWluVG9sZXJhbmNlBQAAAAlwbXRBbW91bnQAAAAAAAABhqAAAAAAAAAAAAEEAAAAHHNsaXBwYWdlVmFsdWVNaW5Gb3JSZXBsZW5pc2gJAABlAAAAAgUAAAAGc2NhbGU4CQAAaQAAAAIJAABoAAAAAgUAAAAGc2NhbGU4BQAAAAl0b2xlcmFuY2UAAAAAAACYloAEAAAAHHNsaXBwYWdlVmFsdWVNYXhGb3JSZXBsZW5pc2gJAABkAAAAAgUAAAAGc2NhbGU4CQAAaQAAAAIJAABoAAAAAgUAAAAGc2NhbGU4BQAAAAl0b2xlcmFuY2UAAAAAAACYloAEAAAAF3NsaXBwYWdlVmFsdWVNaW5Gb3JTd2FwCQAAZQAAAAIFAAAABnNjYWxlOAkAAGkAAAACCQAAaAAAAAIFAAAABnNjYWxlOAAAAAAAAAAAAQAAAAAAAJiWgAMJAQAAAAEhAAAAAQUAAAAIaXNBY3RpdmUJAQAAAA90aHJvd0lzSW5hY3RpdmUAAAAAAwkAAGYAAAACBQAAAA9wbXRNaW5UaHJlc2hvbGQFAAAACXBtdEFtb3VudAkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAD1BheW1lbnQgYW1vdW50IAkAAaQAAAABBQAAAAlwbXRBbW91bnQCAAAAJyBkb2VzIG5vdCBleGNlZWQgdGhlIG1pbmltdW0gYW1vdW50IG9mIAkAAaQAAAABBQAAAA9wbXRNaW5UaHJlc2hvbGQCAAAAByB0b2tlbnMDCQEAAAACIT0AAAACCQABkAAAAAEIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAABCQAAAgAAAAECAAAAHU9uZSBhdHRhY2hlZCBwYXltZW50IGV4cGVjdGVkAwkBAAAAASEAAAABBQAAABBoYXNFbm91Z2hCYWxhbmNlCQAETgAAAAIJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAAAlwbXRBbW91bnQFAAAACnBtdEFzc2V0SWQFAAAAA25pbAkBAAAAEXN1c3BlbmRTdXNwaWNpb3VzAAAAAAMDCQEAAAACIT0AAAACBQAAAApwbXRBc3NldElkBQAAAAhhc3NldElkQQkBAAAAAiE9AAAAAgUAAAAKcG10QXNzZXRJZAUAAAAIYXNzZXRJZEIHCQEAAAALdGhyb3dBc3NldHMAAAAABAAAAA0kdDAxNTgzMTE2NTk2AwkAAAAAAAACBQAAAApwbXRBc3NldElkBQAAAAhhc3NldElkQQkABRkAAAAHCQAAZQAAAAIFAAAACXBtdEFtb3VudAUAAAATdmlydHVhbFN3YXBUb2tlblBheQUAAAATdmlydHVhbFN3YXBUb2tlbkdldAkAAGQAAAACBQAAAAhiYWxhbmNlQQUAAAATdmlydHVhbFN3YXBUb2tlblBheQkAAGUAAAACBQAAAAhiYWxhbmNlQgUAAAATdmlydHVhbFN3YXBUb2tlbkdldAkBAAAADWludmFyaWFudENhbGMAAAACCQAAZAAAAAIFAAAACGJhbGFuY2VBBQAAAAlwbXRBbW91bnQFAAAACGJhbGFuY2VCCQAAZAAAAAIFAAAACGJhbGFuY2VBBQAAAAlwbXRBbW91bnQFAAAACGJhbGFuY2VCCQAFGQAAAAcFAAAAE3ZpcnR1YWxTd2FwVG9rZW5HZXQJAABlAAAAAgUAAAAJcG10QW1vdW50BQAAABN2aXJ0dWFsU3dhcFRva2VuUGF5CQAAZQAAAAIFAAAACGJhbGFuY2VBBQAAABN2aXJ0dWFsU3dhcFRva2VuR2V0CQAAZAAAAAIFAAAACGJhbGFuY2VCBQAAABN2aXJ0dWFsU3dhcFRva2VuUGF5CQEAAAANaW52YXJpYW50Q2FsYwAAAAIFAAAACGJhbGFuY2VBCQAAZAAAAAIFAAAACGJhbGFuY2VCBQAAAAlwbXRBbW91bnQFAAAACGJhbGFuY2VBCQAAZAAAAAIFAAAACGJhbGFuY2VCBQAAAAlwbXRBbW91bnQEAAAAEXZpcnR1YWxSZXBsZW5pc2hBCAUAAAANJHQwMTU4MzExNjU5NgAAAAJfMQQAAAARdmlydHVhbFJlcGxlbmlzaEIIBQAAAA0kdDAxNTgzMTE2NTk2AAAAAl8yBAAAABFiYWxhbmNlQWZ0ZXJTd2FwQQgFAAAADSR0MDE1ODMxMTY1OTYAAAACXzMEAAAAEWJhbGFuY2VBZnRlclN3YXBCCAUAAAANJHQwMTU4MzExNjU5NgAAAAJfNAQAAAATaW52YXJpYW50Q2FsY3VsYXRlZAgFAAAADSR0MDE1ODMxMTY1OTYAAAACXzUEAAAAC25ld0JhbGFuY2VBCAUAAAANJHQwMTU4MzExNjU5NgAAAAJfNgQAAAALbmV3QmFsYW5jZUIIBQAAAA0kdDAxNTgzMTE2NTk2AAAAAl83BAAAAA9uZXdCYWxhbmNlRW50cnkDCQAAAAAAAAIFAAAACnBtdEFzc2V0SWQFAAAACGFzc2V0SWRBCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAJa0JhbGFuY2VBBQAAAAtuZXdCYWxhbmNlQQkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAACWtCYWxhbmNlQgUAAAALbmV3QmFsYW5jZUIEAAAADGludmFyaWFudE5ldwkBAAAADWludmFyaWFudENhbGMAAAACBQAAABFiYWxhbmNlQWZ0ZXJTd2FwQQUAAAARYmFsYW5jZUFmdGVyU3dhcEIEAAAAF2ludmFyaWFudEVzdGltYXRlZFJhdGlvCQAAawAAAAMFAAAABnNjYWxlOAUAAAAJaW52YXJpYW50BQAAAAxpbnZhcmlhbnROZXcEAAAAJXJhdGlvVmlydHVhbEJhbGFuY2VUb1ZpcnR1YWxSZXBsZW5pc2gJAABpAAAAAgkAAGsAAAADCQAAaAAAAAIFAAAABnNjYWxlOAUAAAAGc2NhbGU4BQAAABFiYWxhbmNlQWZ0ZXJTd2FwQQUAAAARYmFsYW5jZUFmdGVyU3dhcEIJAABrAAAAAwUAAAAGc2NhbGU4BQAAABF2aXJ0dWFsUmVwbGVuaXNoQQUAAAARdmlydHVhbFJlcGxlbmlzaEIEAAAAE2RBcHBUaHJlc2hvbGRBbW91bnQJAABrAAAAAwkAAGQAAAACBQAAAAtuZXdCYWxhbmNlQQUAAAALbmV3QmFsYW5jZUIFAAAADWRBcHBUaHJlc2hvbGQJAABoAAAAAgAAAAAAAAAAAgUAAAATZEFwcFRocmVzaG9sZFNjYWxlMgMDCQAAZwAAAAIFAAAAF3NsaXBwYWdlVmFsdWVNaW5Gb3JTd2FwBQAAABdpbnZhcmlhbnRFc3RpbWF0ZWRSYXRpbwYJAABmAAAAAgUAAAAJaW52YXJpYW50BQAAAAxpbnZhcmlhbnROZXcJAAACAAAAAQIAAAA6SW5jb3JyZWN0IHZpcnR1YWxTd2FwVG9rZW5QYXkgb3IgdmlydHVhbFN3YXBUb2tlbkdldCB2YWx1ZQMDCQAAZgAAAAIFAAAAHHNsaXBwYWdlVmFsdWVNaW5Gb3JSZXBsZW5pc2gFAAAAJXJhdGlvVmlydHVhbEJhbGFuY2VUb1ZpcnR1YWxSZXBsZW5pc2gGCQAAZgAAAAIFAAAAJXJhdGlvVmlydHVhbEJhbGFuY2VUb1ZpcnR1YWxSZXBsZW5pc2gFAAAAHHNsaXBwYWdlVmFsdWVNYXhGb3JSZXBsZW5pc2gJAAACAAAAAQIAAABsU3dhcCB3aXRoIHZpcnR1YWxTd2FwVG9rZW5QYXkgYW5kIHZpcnR1YWxTd2FwVG9rZW5HZXQgaXMgcG9zc2libGUsIGJ1dCByYXRpbyBhZnRlciB2aXJ0dWFsIHN3YXAgaXMgaW5jb3JyZWN0AwMJAABmAAAAAgUAAAATZEFwcFRocmVzaG9sZEFtb3VudAUAAAALbmV3QmFsYW5jZUEGCQAAZgAAAAIFAAAAE2RBcHBUaHJlc2hvbGRBbW91bnQFAAAAC25ld0JhbGFuY2VCCQEAAAAOdGhyb3dUaHJlc2hvbGQAAAADBQAAABNkQXBwVGhyZXNob2xkQW1vdW50BQAAAAtuZXdCYWxhbmNlQQUAAAALbmV3QmFsYW5jZUIEAAAABnN0YWtlMQMJAQAAAA9jb250YWluc0VsZW1lbnQAAAACBQAAAA1zdGFraW5nQXNzZXRzBQAAAA1wbXRTdHJBc3NldElkCQAD/AAAAAQFAAAABHRoaXMCAAAADHN0YWtlVW5zdGFrZQkABEwAAAACBgkABEwAAAACBQAAAAlwbXRBbW91bnQJAARMAAAAAgUAAAANcG10U3RyQXNzZXRJZAUAAAADbmlsBQAAAANuaWwAAAAAAAAAAAADCQAAAAAAAAIFAAAABnN0YWtlMQUAAAAGc3Rha2UxBAAAABNyYXRpb1NoYXJlVG9rZW5zSW5BCQAAawAAAAMFAAAAEXZpcnR1YWxSZXBsZW5pc2hBBQAAAAZzY2FsZTgFAAAAEWJhbGFuY2VBZnRlclN3YXBBBAAAABNyYXRpb1NoYXJlVG9rZW5zSW5CCQAAawAAAAMFAAAAEXZpcnR1YWxSZXBsZW5pc2hCBQAAAAZzY2FsZTgFAAAAEWJhbGFuY2VBZnRlclN3YXBCBAAAABVzaGFyZVRva2VuVG9QYXlBbW91bnQJAABrAAAAAwkAAZcAAAABCQAETAAAAAIFAAAAE3JhdGlvU2hhcmVUb2tlbnNJbkEJAARMAAAAAgUAAAATcmF0aW9TaGFyZVRva2Vuc0luQgUAAAADbmlsBQAAABBzaGFyZUFzc2V0U3VwcGx5BQAAAAZzY2FsZTgJAARMAAAAAgkBAAAAB1JlaXNzdWUAAAADBQAAAAxzaGFyZUFzc2V0SWQFAAAAFXNoYXJlVG9rZW5Ub1BheUFtb3VudAYJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAABVzaGFyZVRva2VuVG9QYXlBbW91bnQFAAAADHNoYXJlQXNzZXRJZAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAARa1NoYXJlQXNzZXRTdXBwbHkJAABkAAAAAgUAAAAQc2hhcmVBc3NldFN1cHBseQUAAAAVc2hhcmVUb2tlblRvUGF5QW1vdW50CQAETAAAAAIFAAAAD25ld0JhbGFuY2VFbnRyeQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAKa0ludmFyaWFudAUAAAATaW52YXJpYW50Q2FsY3VsYXRlZAUAAAADbmlsCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAAFpAQAAAAh3aXRoZHJhdwAAAAAEAAAADSR0MDE4ODIyMTg5NjUJAAUUAAAAAggJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAAAAAGYW1vdW50CAkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAdhc3NldElkBAAAAAlwbXRBbW91bnQIBQAAAA0kdDAxODgyMjE4OTY1AAAAAl8xBAAAAApwbXRBc3NldElkCAUAAAANJHQwMTg4MjIxODk2NQAAAAJfMgQAAAAMYW1vdW50VG9QYXlBCQAAawAAAAMFAAAACXBtdEFtb3VudAUAAAAIYmFsYW5jZUEFAAAAEHNoYXJlQXNzZXRTdXBwbHkEAAAADGFtb3VudFRvUGF5QgkAAGsAAAADBQAAAAlwbXRBbW91bnQFAAAACGJhbGFuY2VCBQAAABBzaGFyZUFzc2V0U3VwcGx5BAAAABNpbnZhcmlhbnRDYWxjdWxhdGVkCQEAAAANaW52YXJpYW50Q2FsYwAAAAIJAABlAAAAAgUAAAAIYmFsYW5jZUEFAAAADGFtb3VudFRvUGF5QQkAAGUAAAACBQAAAAhiYWxhbmNlQgUAAAAMYW1vdW50VG9QYXlCAwkBAAAAASEAAAABBQAAAAhpc0FjdGl2ZQkBAAAAD3Rocm93SXNJbmFjdGl2ZQAAAAADCQEAAAACIT0AAAACCQABkAAAAAEIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAABCQAAAgAAAAECAAAAHU9uZSBhdHRh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dAUAAAAVZXhjaGFuZ2VSYXRpb0xpbWl0TWF4CQAAAgAAAAECAAAAHEluY29ycmVjdCBhcmdzIGFuZCBwbXQgcmF0aW8EAAAAC3NlbmRBc3NldElkAwkAAAAAAAACBQAAAApwbXRBc3NldElkBQAAAAhhc3NldElkQQUAAAAIYXNzZXRJZEIFAAAACGFzc2V0SWRBBAAAAAZhbW91bnQJAQAAABNjYWxjdWxhdGVTZW5kQW1vdW50AAAABAUAAAAYZXN0aW1hdGVkQW1vdW50VG9SZWNlaXZlBQAAABJtaW5BbW91bnRUb1JlY2VpdmUFAAAACXBtdEFtb3VudAUAAAAKcG10QXNzZXRJZAQAAAAQZ292ZXJuYW5jZVJld2FyZAkAAGsAAAADBQAAAAZhbW91bnQFAAAADWZlZUdvdmVybmFuY2UFAAAACWZlZVNjYWxlNgQAAAAOYW1vdW50TWludXNGZWUJAABrAAAAAwUAAAAGYW1vdW50CQAAZQAAAAIFAAAACWZlZVNjYWxlNgUAAAADZmVlBQAAAAlmZWVTY2FsZTYEAAAADSR0MDIxOTc2MjIyMzgDCQAAAAAAAAIFAAAACnBtdEFzc2V0SWQFAAAACGFzc2V0SWRBCQAFFAAAAAIJAABkAAAAAgUAAAAIYmFsYW5jZUEFAAAACXBtdEFtb3VudAkAAGUAAAACCQAAZQAAAAIFAAAACGJhbGFuY2VCBQAAAA5hbW91bnRNaW51c0ZlZQUAAAAQZ292ZXJuYW5jZVJld2FyZAkABRQAAAACCQAAZQAAAAIJAABlAAAAAgUAAAAIYmFsYW5jZUEFAAAADmFtb3VudE1pbnVzRmVlBQAAABBnb3Zlcm5hbmNlUmV3YXJkCQAAZAAAAAIFAAAACGJhbGFuY2VCBQAAAAlwbXRBbW91bnQEAAAAC25ld0JhbGFuY2VBCAUAAAANJHQwMjE5NzYyMjIzOAAAAAJfMQQAAAALbmV3QmFsYW5jZUIIBQAAAA0kdDAyMTk3NjIyMjM4AAAAAl8yBAAAABNkQXBwVGhyZXNob2xkQW1vdW50CQAAawAAAAMJAABkAAAAAgUAAAALbmV3QmFsYW5jZUEFAAAAC25ld0JhbGFuY2VCBQAAAA1kQXBwVGhyZXNob2xkCQAAaAAAAAIAAAAAAAAAAAIFAAAAE2RBcHBUaHJlc2hvbGRTY2FsZTIDAwkAAGYAAAACBQAAABNkQXBwVGhyZXNob2xkQW1vdW50BQAAAAtuZXdCYWxhbmNlQQYJAABmAAAAAgUAAAATZEFwcFRocmVzaG9sZEFtb3VudAUAAAALbmV3QmFsYW5jZUIJAQAAAA50aHJvd1RocmVzaG9sZAAAAAMFAAAAE2RBcHBUaHJlc2hvbGRBbW91bnQFAAAAC25ld0JhbGFuY2VBBQAAAAtuZXdCYWxhbmNlQgQAAAANJHQwMjI1MzYyMjYwOQkBAAAADGdldEFzc2V0SW5mbwAAAAEFAAAACnBtdEFzc2V0SWQEAAAADXBtdFN0ckFzc2V0SWQIBQAAAA0kdDAyMjUzNjIyNjA5AAAAAl8xBAAAAAxwbXRBc3NldE5hbWUIBQAAAA0kdDAyMjUzNjIyNjA5AAAAAl8yBAAAAAtwbXREZWNpbWFscwgFAAAADSR0MDIyNTM2MjI2MDkAAAACXzMEAAAADSR0MDIyNjIyMjI2OTkJAQAAAAxnZXRBc3NldEluZm8AAAABBQAAAAtzZW5kQXNzZXRJZAQAAAAOc2VuZFN0ckFzc2V0SWQIBQAAAA0kdDAyMjYyMjIyNjk5AAAAAl8xBAAAAA1zZW5kQXNzZXROYW1lCAUAAAANJHQwMjI2MjIyMjY5OQAAAAJfMgQAAAAMc2VuZERlY2ltYWxzCAUAAAANJHQwMjI2MjIyMjY5OQAAAAJfMwQAAAAGc3Rha2UxAwkBAAAAD2NvbnRhaW5zRWxlbWVudAAAAAIFAAAADXN0YWtpbmdBc3NldHMFAAAADXBtdFN0ckFzc2V0SWQJAAP8AAAABAUAAAAEdGhpcwIAAAAMc3Rha2VVbnN0YWtlCQAETAAAAAIGCQAETAAAAAIFAAAACXBtdEFtb3VudAkABEwAAAACBQAAAA1wbXRTdHJBc3NldElkBQAAAANuaWwFAAAAA25pbAAAAAAAAAAAAAMJAAAAAAAAAgUAAAAGc3Rha2UxBQAAAAZzdGFrZTEEAAAABnN0YWtlMgMJAQAAAA9jb250YWluc0VsZW1lbnQAAAACBQAAAA1zdGFraW5nQXNzZXRzBQAAAA5zZW5kU3RyQXNzZXRJZAkAA/wAAAAEBQAAAAR0aGlzAgAAAAxzdGFrZVVuc3Rha2UJAARMAAAAAgcJAARMAAAAAgkAAGQAAAACBQAAAA5hbW91bnRNaW51c0ZlZQUAAAAQZ292ZXJuYW5jZVJld2FyZAkABEwAAAACBQAAAA5zZW5kU3RyQXNzZXRJZAUAAAADbmlsBQAAAANuaWwAAAAAAAAAAAADCQAAAAAAAAIFAAAABnN0YWtlMgUAAAAGc3Rha2UyCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAlrQmFsYW5jZUEFAAAAC25ld0JhbGFuY2VBCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAlrQmFsYW5jZUIFAAAAC25ld0JhbGFuY2VCCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAprSW52YXJpYW50CQEAAAANaW52YXJpYW50Q2FsYwAAAAIFAAAAC25ld0JhbGFuY2VBBQAAAAtuZXdCYWxhbmNlQgkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIFAAAADmFtb3VudE1pbnVzRmVlBQAAAAtzZW5kQXNzZXRJZAkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADBQAAAA13YWxsZXRBZGRyZXNzBQAAABBnb3Zlcm5hbmNlUmV3YXJkBQAAAAtzZW5kQXNzZXRJZAUAAAADbmlsCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAAABaQEAAAAIc2h1dGRvd24AAAAAAwkBAAAAASEAAAABBQAAAAhpc0FjdGl2ZQkAAAIAAAABCQABLAAAAAICAAAAIkRBcHAgaXMgYWxyZWFkeSBzdXNwZW5kZWQuIENhdXNlOiAJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwUAAAAGa0NhdXNlAgAAABp0aGUgY2F1c2Ugd2Fzbid0IHNwZWNpZmllZAMJAQAAAAEhAAAAAQkBAAAAD2NvbnRhaW5zRWxlbWVudAAAAAIJAARMAAAAAgUAAAAMYWRtaW5QdWJLZXkxCQAETAAAAAIFAAAADGFkbWluUHViS2V5MgkABEwAAAACBQAAAAxhZG1pblB1YktleTMJAARMAAAAAgUAAAAMYWRtU3RhcnRTdG9wBQAAAANuaWwIBQAAAAFpAAAAD2NhbGxlclB1YmxpY0tleQkBAAAADnRocm93T25seUFkbWluAAAAAAkBAAAAB3N1c3BlbmQAAAABAgAAAA9QYXVzZWQgYnkgYWRtaW4AAAABaQEAAAAIYWN0aXZhdGUAAAAAAwUAAAAIaXNBY3RpdmUJAQAAAA10aHJvd0lzQWN0aXZlAAAAAAMJAQAAAAEhAAAAAQkBAAAAD2NvbnRhaW5zRWxlbWVudAAAAAIJAARMAAAAAgUAAAAMYWRtaW5QdWJLZXkxCQAETAAAAAIFAAAADGFkbWluUHViS2V5MgkABEwAAAACBQAAAAxhZG1pblB1YktleTMJAARMAAAAAgUAAAAMYWRtU3RhcnRTdG9wBQAAAANuaWwIBQAAAAFpAAAAD2NhbGxlclB1YmxpY0tleQkBAAAADnRocm93T25seUFkbWluAAAAAAkABEwAAAACCQEAAAAMQm9vbGVhbkVudHJ5AAAAAgUAAAAHa0FjdGl2ZQYJAARMAAAAAgkBAAAAC0RlbGV0ZUVudHJ5AAAAAQUAAAAGa0NhdXNlBQAAAANuaWwAAAABaQEAAAAZdGFrZUludG9BY2NvdW50RXh0cmFGdW5kcwAAAAAEAAAADWFtb3VudEVucm9sbEEJAABlAAAAAgUAAAAZYWNjb3VudEJhbGFuY2VXaXRoU3Rha2VkQQUAAAAIYmFsYW5jZUEEAAAADWFtb3VudEVucm9sbEIJAABlAAAAAgUAAAAZYWNjb3VudEJhbGFuY2VXaXRoU3Rha2VkQgUAAAAIYmFsYW5jZUIEAAAADGludmFyaWFudE5ldwkBAAAADWludmFyaWFudENhbGMAAAACCQAAZAAAAAIFAAAACGJhbGFuY2VBBQAAAA1hbW91bnRFbnJvbGxBCQAAZAAAAAIFAAAACGJhbGFuY2VCBQAAAA1hbW91bnRFbnJvbGxCAwkBAAAAASEAAAABBQAAAAhpc0FjdGl2ZQkBAAAAD3Rocm93SXNJbmFjdGl2ZQAAAAADCQEAAAACIT0AAAACCAUAAAABaQAAAAZjYWxsZXIFAAAADXdhbGxldEFkZHJlc3MJAAACAAAAAQIAAAAmT25s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", "height": 1903224, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: EqhJRFNgBrFo141NPSmRc9MDkngBXJLwQYWk8Qvattr7 Next: 8PVWM9TP3oSzRuiCxVPYtdwZa9eTBUdMjQsTSiH7Y4B3 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"
5559
5660 let admStaking = base58'Kn7NpzaG12dLZgcHf2ipUftU6hbJygmrhFqQYE4B7ZK'
5761
58-let govAddr = Address(base58'3N5W8da2iiijVieA6qLGo7KzCJj8B19smWU')
59-
60-let stakingAddress = Address(base58'3N6q7sCGSSLBUXDdjBdYGTJbZGZfhhh8cNg')
62+let walletAddress = Address(base58'3NAGTtZz6WpupSN89NZD5rMZwwziZEg4Kx4')
6163
6264 let USDN = base58'8UrfDVd5GreeUwm7uPk7eYz1eMv376kzR52C6sANPkwS'
6365
64-let stakingFeeInUSDN = 270000
66+let EURN = base58'ECBCkHS68DckpBrzLeoRgYbFg7sCVqR176mPqbXsj9pA'
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
147155 }
148156
149157
150-let stakedAmountUSDN = match getInteger(stakingAddress, ((("rpd_balance_" + toBase58String(USDN)) + "_") + toString(this))) {
151- case staked: Int =>
152- staked
153- case nothing: Unit =>
154- 0
155- case _ =>
156- throw("Match error")
157-}
158+func stakedAmount (assetId) = {
159+ let stakedAmountCalculated = match assetId {
160+ case aId: ByteVector =>
161+ if ((aId == USDN))
162+ then getInteger(stakingUSDNNSBTAddress, ((("rpd_balance_" + toBase58String(aId)) + "_") + toString(this)))
163+ else if ((aId == EURN))
164+ then getInteger(stakingEURNAddress, ((("%s%s%s__stakingBalance__" + toBase58String(aId)) + "__") + toString(this)))
165+ else 0
166+ case _: Unit =>
167+ 0
168+ case _ =>
169+ throw("Match error")
170+ }
171+ match stakedAmountCalculated {
172+ case i: Int =>
173+ i
174+ case _ =>
175+ 0
176+ }
177+ }
158178
159-let availableBalanceA = (balanceA - (if ((assetIdA == USDN))
160- then stakedAmountUSDN
161- else 0))
162179
163-let availableBalanceB = (balanceB - (if ((assetIdB == USDN))
164- then stakedAmountUSDN
165- else 0))
180+let stakedAmountA = stakedAmount(assetIdA)
166181
167-let accountBalanceWithStakedA = (accountBalance(assetIdA) + (if ((assetIdA == USDN))
168- then stakedAmountUSDN
169- else 0))
182+let stakedAmountB = stakedAmount(assetIdB)
170183
171-let accountBalanceWithStakedB = (accountBalance(assetIdB) + (if ((assetIdB == USDN))
172- then stakedAmountUSDN
173- else 0))
184+let availableBalanceA = (balanceA - stakedAmountA)
185+
186+let availableBalanceB = (balanceB - stakedAmountB)
187+
188+let accountBalanceWithStakedA = (accountBalance(assetIdA) + stakedAmountA)
189+
190+let accountBalanceWithStakedB = (accountBalance(assetIdB) + stakedAmountB)
174191
175192 let hasEnoughBalance = if ((accountBalanceWithStakedA >= balanceA))
176193 then (accountBalanceWithStakedB >= balanceB)
177194 else false
178195
179-func skewness (x,y) = ((fraction(scale12, x, y) + fraction(scale12, y, x)) / 2)
196+func skewness (x,y) = (((fraction(scale12, x, y) + fraction(scale12, y, x)) / 2) / 10000)
180197
181198
182199 func invariantCalc (x,y) = {
247264 func suspend (cause) = [BooleanEntry(kActive, false), StringEntry(kCause, cause)]
248265
249266
250-func deductStakingFee (amount,assetId) = if ((assetId == USDN))
251- then {
252- let result = (amount - stakingFeeInUSDN)
253- if ((0 >= result))
254- then throw((((("Insufficient amount " + toString(amount)) + " to deduct staking fee ") + toString(stakingFeeInUSDN)) + " USD-N"))
255- else result
256- }
257- else amount
258-
259-
260267 func throwIsActive () = throw("DApp is already active")
261268
262269
272279 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))
273280
274281
275-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"))
282+func suspendSuspicious () = suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB) + ". State: ") + toString(accountBalance(assetIdA))) + " ") + assetNameA) + ", ") + toString(accountBalance(assetIdB))) + " ") + assetNameB))
276283
277284
278-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"))
285+func calcStakingFuncAndAddres (stake,assetId) = if (stake)
286+ then if ((assetId == USDN))
287+ then $Tuple2("lockNeutrino", stakingUSDNNSBTAddress)
288+ else $Tuple2("startStaking", stakingEURNAddress)
289+ else if ((assetId == USDN))
290+ then $Tuple2("unlockNeutrino", stakingUSDNNSBTAddress)
291+ else $Tuple2("stopStaking", stakingEURNAddress)
279292
280293
281-func suspendSuspicious () = suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB) + ". State: ") + toString(accountBalance(assetIdA))) + " ") + assetNameA) + ", ") + toString(accountBalance(assetIdB))) + " ") + assetNameB))
294+func calcStakingParams (stake,amount,assetId) = if (stake)
295+ then {
296+ let $t089298995 = calcStakingFuncAndAddres(stake, assetId)
297+ let call = $t089298995._1
298+ let stakingAddr = $t089298995._2
299+ $Tuple4(call, stakingAddr, nil, [AttachedPayment(assetId, amount)])
300+ }
301+ else {
302+ let $t090819147 = calcStakingFuncAndAddres(stake, assetId)
303+ let call = $t090819147._1
304+ let stakingAddr = $t090819147._2
305+ $Tuple4(call, stakingAddr, [amount, toBase58String(assetId)], nil)
306+ }
282307
283308
284309 @Callable(i)
285310 func init () = {
286- let $t089299006 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
287- let pmtAmountA = $t089299006._1
288- let pmtAssetIdA = $t089299006._2
289- let $t090119088 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
290- let pmtAmountB = $t090119088._1
291- let pmtAssetIdB = $t090119088._2
292- let $t090939170 = getAssetInfo(pmtAssetIdA)
293- let pmtStrAssetIdA = $t090939170._1
294- let pmtAssetNameA = $t090939170._2
295- let pmtDecimalsA = $t090939170._3
296- let $t091759252 = getAssetInfo(pmtAssetIdB)
297- let pmtStrAssetIdB = $t091759252._1
298- let pmtAssetNameB = $t091759252._2
299- let pmtDecimalsB = $t091759252._3
311+ let $t092529329 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
312+ let pmtAmountA = $t092529329._1
313+ let pmtAssetIdA = $t092529329._2
314+ let $t093349411 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
315+ let pmtAmountB = $t093349411._1
316+ let pmtAssetIdB = $t093349411._2
317+ let $t094169493 = getAssetInfo(pmtAssetIdA)
318+ let pmtStrAssetIdA = $t094169493._1
319+ let pmtAssetNameA = $t094169493._2
320+ let pmtDecimalsA = $t094169493._3
321+ let $t094989575 = getAssetInfo(pmtAssetIdB)
322+ let pmtStrAssetIdB = $t094989575._1
323+ let pmtAssetNameB = $t094989575._2
324+ let pmtDecimalsB = $t094989575._3
300325 if (isDefined(getBoolean(this, kActive)))
301326 then throwIsActive()
302327 else if ((pmtAssetIdA == pmtAssetIdB))
309334 let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
310335 let shareIssueId = calculateAssetId(shareIssue)
311336 let invariantCalculated = invariantCalc(pmtAmountA, pmtAmountB)
312-[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)]
337+ let stake1 = if (containsElement(stakingAssets, pmtStrAssetIdA))
338+ then invoke(this, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
339+ else 0
340+ if ((stake1 == stake1))
341+ then {
342+ let stake2 = if (containsElement(stakingAssets, pmtStrAssetIdB))
343+ then invoke(this, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
344+ else 0
345+ if ((stake2 == stake2))
346+ 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)]
347+ else throw("Strict value is not equal to itself.")
348+ }
349+ else throw("Strict value is not equal to itself.")
313350 }
314351 }
315352
319356 func replenishWithTwoTokens (slippageTolerance) = {
320357 let pmtAssetIdA = i.payments[0].assetId
321358 let pmtAssetIdB = i.payments[1].assetId
322- let pmtAmountA = deductStakingFee(i.payments[0].amount, pmtAssetIdA)
323- let pmtAmountB = deductStakingFee(i.payments[1].amount, pmtAssetIdB)
359+ let pmtAmountA = i.payments[0].amount
360+ let pmtAmountB = i.payments[1].amount
361+ let $t01209112168 = getAssetInfo(pmtAssetIdA)
362+ let pmtStrAssetIdA = $t01209112168._1
363+ let pmtAssetNameA = $t01209112168._2
364+ let pmtDecimalsA = $t01209112168._3
365+ let $t01217312367 = getAssetInfo(pmtAssetIdB)
366+ let pmtStrAssetIdB = $t01217312367._1
367+ let pmtAssetNameB = $t01217312367._2
368+ let pmtDecimalsB = $t01217312367._3
324369 let tokenRatio = fraction(fraction(scale8, balanceA, pmtAmountA), scale3, fraction(scale8, balanceB, pmtAmountB))
325370 let ratioShareTokensInA = fraction(scale8, pmtAmountA, balanceA)
326371 let ratioShareTokensInB = fraction(scale8, pmtAmountB, balanceB)
346391 then throw("Too small amount to replenish")
347392 else if (!(hasEnoughBalance))
348393 then ([ScriptTransfer(i.caller, pmtAmountA, pmtAssetIdA), ScriptTransfer(i.caller, pmtAmountB, pmtAssetIdB)] ++ suspendSuspicious())
349- 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)]
394+ else {
395+ let stake1 = if (containsElement(stakingAssets, pmtStrAssetIdA))
396+ then invoke(this, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
397+ else 0
398+ if ((stake1 == stake1))
399+ then {
400+ let stake2 = if (containsElement(stakingAssets, pmtStrAssetIdB))
401+ then invoke(this, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
402+ else 0
403+ if ((stake2 == stake2))
404+ 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)]
405+ else throw("Strict value is not equal to itself.")
406+ }
407+ else throw("Strict value is not equal to itself.")
408+ }
350409 }
351410
352411
353412
354413 @Callable(i)
355414 func replenishWithOneToken (virtualSwapTokenPay,virtualSwapTokenGet) = {
356- let $t01359513670 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
357- let pmtAmount = $t01359513670._1
358- let pmtAssetId = $t01359513670._2
415+ let $t01466614741 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
416+ let pmtAmount = $t01466614741._1
417+ let pmtAssetId = $t01466614741._2
418+ let $t01474614819 = getAssetInfo(pmtAssetId)
419+ let pmtStrAssetId = $t01474614819._1
420+ let pmtAssetName = $t01474614819._2
421+ let pmtDecimals = $t01474614819._3
359422 let pmtMinThreshold = 5000000
360423 let thresholdValueForMinTolerance = 50000000
361424 let tolerance = if ((thresholdValueForMinTolerance > pmtAmount))
377440 else false)
378441 then throwAssets()
379442 else {
380- let $t01468215447 = if ((pmtAssetId == assetIdA))
443+ let $t01583116596 = if ((pmtAssetId == assetIdA))
381444 then $Tuple7((pmtAmount - virtualSwapTokenPay), virtualSwapTokenGet, (balanceA + virtualSwapTokenPay), (balanceB - virtualSwapTokenGet), invariantCalc((balanceA + pmtAmount), balanceB), (balanceA + pmtAmount), balanceB)
382445 else $Tuple7(virtualSwapTokenGet, (pmtAmount - virtualSwapTokenPay), (balanceA - virtualSwapTokenGet), (balanceB + virtualSwapTokenPay), invariantCalc(balanceA, (balanceB + pmtAmount)), balanceA, (balanceB + pmtAmount))
383- let virtualReplenishA = $t01468215447._1
384- let virtualReplenishB = $t01468215447._2
385- let balanceAfterSwapA = $t01468215447._3
386- let balanceAfterSwapB = $t01468215447._4
387- let invariantCalculated = $t01468215447._5
388- let newBalanceA = $t01468215447._6
389- let newBalanceB = $t01468215447._7
446+ let virtualReplenishA = $t01583116596._1
447+ let virtualReplenishB = $t01583116596._2
448+ let balanceAfterSwapA = $t01583116596._3
449+ let balanceAfterSwapB = $t01583116596._4
450+ let invariantCalculated = $t01583116596._5
451+ let newBalanceA = $t01583116596._6
452+ let newBalanceB = $t01583116596._7
390453 let newBalanceEntry = if ((pmtAssetId == assetIdA))
391454 then IntegerEntry(kBalanceA, newBalanceA)
392455 else IntegerEntry(kBalanceB, newBalanceB)
407470 else (dAppThresholdAmount > newBalanceB))
408471 then throwThreshold(dAppThresholdAmount, newBalanceA, newBalanceB)
409472 else {
410- let ratioShareTokensInA = fraction(deductStakingFee(virtualReplenishA, assetIdA), scale8, balanceAfterSwapA)
411- let ratioShareTokensInB = fraction(deductStakingFee(virtualReplenishB, assetIdB), scale8, balanceAfterSwapB)
412- let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scale8)
473+ let stake1 = if (containsElement(stakingAssets, pmtStrAssetId))
474+ then invoke(this, "stakeUnstake", [true, pmtAmount, pmtStrAssetId], nil)
475+ else 0
476+ if ((stake1 == stake1))
477+ then {
478+ let ratioShareTokensInA = fraction(virtualReplenishA, scale8, balanceAfterSwapA)
479+ let ratioShareTokensInB = fraction(virtualReplenishB, scale8, balanceAfterSwapB)
480+ let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scale8)
413481 [Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId), IntegerEntry(kShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), newBalanceEntry, IntegerEntry(kInvariant, invariantCalculated)]
482+ }
483+ else throw("Strict value is not equal to itself.")
414484 }
415485 }
416486 }
419489
420490 @Callable(i)
421491 func withdraw () = {
422- let $t01759217735 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
423- let pmtAmount = $t01759217735._1
424- let pmtAssetId = $t01759217735._2
425- let amountToPayA = deductStakingFee(fraction(pmtAmount, balanceA, shareAssetSupply), assetIdA)
426- let amountToPayB = deductStakingFee(fraction(pmtAmount, balanceB, shareAssetSupply), assetIdB)
492+ let $t01882218965 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
493+ let pmtAmount = $t01882218965._1
494+ let pmtAssetId = $t01882218965._2
495+ let amountToPayA = fraction(pmtAmount, balanceA, shareAssetSupply)
496+ let amountToPayB = fraction(pmtAmount, balanceB, shareAssetSupply)
427497 let invariantCalculated = invariantCalc((balanceA - amountToPayA), (balanceB - amountToPayB))
428498 if (!(isActive))
429499 then throwIsInactive()
433503 then throw(("Incorrect asset attached. Expected: " + toBase58String(shareAssetId)))
434504 else if (!(hasEnoughBalance))
435505 then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
436- else if (if ((amountToPayA > availableBalanceA))
437- then true
438- else (amountToPayB > availableBalanceB))
439- then throwInsufficientAvailableBalances(amountToPayA, amountToPayB)
440- 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)]
506+ else {
507+ let stake1 = if (containsElement(stakingAssets, strAssetIdA))
508+ then invoke(this, "stakeUnstake", [false, amountToPayA, strAssetIdA], nil)
509+ else 0
510+ if ((stake1 == stake1))
511+ then {
512+ let stake2 = if (containsElement(stakingAssets, strAssetIdB))
513+ then invoke(this, "stakeUnstake", [false, amountToPayB, strAssetIdB], nil)
514+ else 0
515+ if ((stake2 == stake2))
516+ 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)]
517+ else throw("Strict value is not equal to itself.")
518+ }
519+ else throw("Strict value is not equal to itself.")
520+ }
441521 }
442522
443523
444524
445525 @Callable(i)
446526 func exchange (estimatedAmountToReceive,minAmountToReceive) = {
447- let $t01909319168 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
448- let pmtAmount = $t01909319168._1
449- let pmtAssetId = $t01909319168._2
527+ let $t02047920554 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
528+ let pmtAmount = $t02047920554._1
529+ let pmtAssetId = $t02047920554._2
450530 if (!(isActive))
451531 then throwIsInactive()
452532 else if ((0 >= estimatedAmountToReceive))
474554 let amount = calculateSendAmount(estimatedAmountToReceive, minAmountToReceive, pmtAmount, pmtAssetId)
475555 let governanceReward = fraction(amount, feeGovernance, feeScale6)
476556 let amountMinusFee = fraction(amount, (feeScale6 - fee), feeScale6)
477- let $t02059020852 = if ((pmtAssetId == assetIdA))
557+ let $t02197622238 = if ((pmtAssetId == assetIdA))
478558 then $Tuple2((balanceA + pmtAmount), ((balanceB - amountMinusFee) - governanceReward))
479559 else $Tuple2(((balanceA - amountMinusFee) - governanceReward), (balanceB + pmtAmount))
480- let newBalanceA = $t02059020852._1
481- let newBalanceB = $t02059020852._2
560+ let newBalanceA = $t02197622238._1
561+ let newBalanceB = $t02197622238._2
482562 let dAppThresholdAmount = fraction((newBalanceA + newBalanceB), dAppThreshold, (2 * dAppThresholdScale2))
483563 if (if ((dAppThresholdAmount > newBalanceA))
484564 then true
485565 else (dAppThresholdAmount > newBalanceB))
486566 then throwThreshold(dAppThresholdAmount, newBalanceA, newBalanceB)
487- else if (if (if ((assetIdA == USDN))
488- then (sendAssetId == assetIdA)
489- else false)
490- then (stakedAmountUSDN >= newBalanceA)
491- else false)
492- then throwInsufficientAvailableBalance(amountMinusFee, availableBalanceA, assetNameA)
493- else if (if (if ((assetIdB == USDN))
494- then (sendAssetId == assetIdB)
495- else false)
496- then (stakedAmountUSDN >= newBalanceB)
497- else false)
498- then throwInsufficientAvailableBalance(amountMinusFee, availableBalanceB, assetNameB)
499- else [IntegerEntry(kBalanceA, newBalanceA), IntegerEntry(kBalanceB, newBalanceB), IntegerEntry(kInvariant, invariantCalc(newBalanceA, newBalanceB)), ScriptTransfer(i.caller, amountMinusFee, sendAssetId), ScriptTransfer(govAddr, governanceReward, sendAssetId)]
567+ else {
568+ let $t02253622609 = getAssetInfo(pmtAssetId)
569+ let pmtStrAssetId = $t02253622609._1
570+ let pmtAssetName = $t02253622609._2
571+ let pmtDecimals = $t02253622609._3
572+ let $t02262222699 = getAssetInfo(sendAssetId)
573+ let sendStrAssetId = $t02262222699._1
574+ let sendAssetName = $t02262222699._2
575+ let sendDecimals = $t02262222699._3
576+ let stake1 = if (containsElement(stakingAssets, pmtStrAssetId))
577+ then invoke(this, "stakeUnstake", [true, pmtAmount, pmtStrAssetId], nil)
578+ else 0
579+ if ((stake1 == stake1))
580+ then {
581+ let stake2 = if (containsElement(stakingAssets, sendStrAssetId))
582+ then invoke(this, "stakeUnstake", [false, (amountMinusFee + governanceReward), sendStrAssetId], nil)
583+ else 0
584+ if ((stake2 == stake2))
585+ then [IntegerEntry(kBalanceA, newBalanceA), IntegerEntry(kBalanceB, newBalanceB), IntegerEntry(kInvariant, invariantCalc(newBalanceA, newBalanceB)), ScriptTransfer(i.caller, amountMinusFee, sendAssetId), ScriptTransfer(walletAddress, governanceReward, sendAssetId)]
586+ else throw("Strict value is not equal to itself.")
587+ }
588+ else throw("Strict value is not equal to itself.")
589+ }
500590 }
501591 }
502592
521611
522612
523613 @Callable(i)
524-func takeIntoAccountExtraFunds (amountLeave) = {
525- let uncountableA = (accountBalanceWithStakedA - balanceA)
526- let uncountableB = (accountBalanceWithStakedB - balanceB)
527- let amountEnrollA = (uncountableA - (if ((assetIdA == unit))
528- then amountLeave
529- else 0))
530- let amountEnrollB = (uncountableB - (if ((assetIdB == unit))
531- then amountLeave
532- else 0))
614+func takeIntoAccountExtraFunds () = {
615+ let amountEnrollA = (accountBalanceWithStakedA - balanceA)
616+ let amountEnrollB = (accountBalanceWithStakedB - balanceB)
533617 let invariantNew = invariantCalc((balanceA + amountEnrollA), (balanceB + amountEnrollB))
534618 if (!(isActive))
535619 then throwIsInactive()
536- else if ((i.caller != this))
537- then throwOnlyAdmin()
538- else if ((0 > amountLeave))
539- then throw(("Argument 'amountLeave' cannot be negative. Actual: " + toString(amountLeave)))
540- else if (if ((0 > uncountableA))
541- then true
542- else (0 > uncountableB))
543- then suspend("Enroll amount negative")
544- else if (if ((0 > amountEnrollA))
545- then true
546- else (0 > amountEnrollB))
547- then throw("Too large amountLeave")
548- else [IntegerEntry(kInvariant, invariantNew), IntegerEntry(kBalanceA, (balanceA + amountEnrollA)), IntegerEntry(kBalanceB, (balanceB + amountEnrollB)), IntegerEntry(("last_income_" + strAssetIdA), amountEnrollA), IntegerEntry(("last_income_" + strAssetIdB), amountEnrollB)]
620+ else if ((i.caller != walletAddress))
621+ then throw("Only the wallet can call this function")
622+ else if (if ((0 > amountEnrollA))
623+ then true
624+ else (0 > amountEnrollB))
625+ then suspend("Enroll amount negative")
626+ else if (if ((amountEnrollA == 0))
627+ then (amountEnrollB == 0)
628+ else false)
629+ then throw("No money to take")
630+ else {
631+ let stake1 = if (if (containsElement(stakingAssets, strAssetIdA))
632+ then (amountEnrollA > 0)
633+ else false)
634+ then invoke(this, "stakeUnstake", [true, amountEnrollA, strAssetIdA], nil)
635+ else 0
636+ if ((stake1 == stake1))
637+ then {
638+ let stake2 = if (if (containsElement(stakingAssets, strAssetIdB))
639+ then (amountEnrollB > 0)
640+ else false)
641+ then invoke(this, "stakeUnstake", [true, amountEnrollB, strAssetIdB], nil)
642+ else 0
643+ if ((stake2 == stake2))
644+ then [IntegerEntry(kInvariant, invariantNew), IntegerEntry(kBalanceA, (balanceA + amountEnrollA)), IntegerEntry(kBalanceB, (balanceB + amountEnrollB)), IntegerEntry(("last_income_" + strAssetIdA), amountEnrollA), IntegerEntry(("last_income_" + strAssetIdB), amountEnrollB)]
645+ else throw("Strict value is not equal to itself.")
646+ }
647+ else throw("Strict value is not equal to itself.")
648+ }
549649 }
650+
651+
652+
653+@Callable(i)
654+func stakeUnstake (stake,amount,assetIdString) = if ((i.caller != this))
655+ then throw("Only contract itself can invoke this function")
656+ else {
657+ let $t02576125864 = calcStakingParams(stake, amount, fromBase58String(assetIdString))
658+ let call = $t02576125864._1
659+ let addr = $t02576125864._2
660+ let params = $t02576125864._3
661+ let payments = $t02576125864._4
662+ let inv = invoke(addr, call, params, payments)
663+ if ((inv == inv))
664+ then nil
665+ else throw("Strict value is not equal to itself.")
666+ }
667+
668+
669+
670+@Callable(i)
671+func stakeAll () = if (!(isActive))
672+ then throw("DApp is inactive at this moment")
673+ else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, admStartStop], i.callerPublicKey)))
674+ then throw("Only admin can call this function")
675+ else {
676+ let stake1 = if (containsElement(stakingAssets, strAssetIdA))
677+ then {
678+ let amountA = (balanceA - stakedAmountA)
679+ if ((amountA > 0))
680+ then invoke(this, "stakeUnstake", [true, amountA, strAssetIdA], nil)
681+ else 0
682+ }
683+ else 0
684+ if ((stake1 == stake1))
685+ then {
686+ let stake2 = if (containsElement(stakingAssets, strAssetIdB))
687+ then {
688+ let amountB = (balanceB - stakedAmountB)
689+ if ((amountB > 0))
690+ then invoke(this, "stakeUnstake", [true, amountB, strAssetIdB], nil)
691+ else 0
692+ }
693+ else 0
694+ if ((stake2 == stake2))
695+ then nil
696+ else throw("Strict value is not equal to itself.")
697+ }
698+ else throw("Strict value is not equal to itself.")
699+ }
550700
551701
552702 @Verifier(tx)
568718 let callTakeIntoAccount = if ((inv.dApp == this))
569719 then (inv.function == "takeIntoAccountExtraFunds")
570720 else false
571- let callStaking = if ((inv.dApp == stakingAddress))
572- then if (if (if ((inv.function == "lockNeutrino"))
573- then (size(inv.payments) == 1)
574- else false)
575- then (inv.payments[0].assetId == USDN)
576- else false)
577- then true
578- else if ((inv.function == "unlockNeutrino"))
579- then (size(inv.payments) == 0)
580- else false
581- else false
582- let exchangeToWaves = if (if (if ((inv.dApp == USDNToWavesExchanger))
583- then (inv.function == "exchange")
584- else false)
585- then (assetIdA == USDN)
586- else false)
587- then true
588- else if (if ((assetIdB == USDN))
589- then (size(inv.payments) == 1)
590- else false)
591- then (inv.payments[0].assetId == USDN)
592- else false
593721 let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
594722 then true
595723 else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey2))
597725 else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey3))
598726 then true
599727 else sigVerify(tx.bodyBytes, tx.proofs[0], admStaking)
600- if (if (if (if (callTakeIntoAccount)
601- then true
602- else callStaking)
603- then true
604- else exchangeToWaves)
728+ if (if (callTakeIntoAccount)
605729 then signedByAdmin
606730 else false)
607731 then true
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'3N8PGkzXhbtTvEwEQTtE2xiTJmsDEQ9XfoZ')
3741
3842 let oracle = Address(base58'3NBBWfzZtZtszaXbitTKnrB2xXwv26Bn7H9')
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
4852 let adminPubKey1 = getAdminPub(keyAdminPubKey1)
4953
5054 let adminPubKey2 = getAdminPub(keyAdminPubKey2)
5155
5256 let adminPubKey3 = getAdminPub(keyAdminPubKey3)
5357
5458 let admStartStop = base58'Kn7NpzaG12dLZgcHf2ipUftU6hbJygmrhFqQYE4B7ZK'
5559
5660 let admStaking = base58'Kn7NpzaG12dLZgcHf2ipUftU6hbJygmrhFqQYE4B7ZK'
5761
58-let govAddr = Address(base58'3N5W8da2iiijVieA6qLGo7KzCJj8B19smWU')
59-
60-let stakingAddress = Address(base58'3N6q7sCGSSLBUXDdjBdYGTJbZGZfhhh8cNg')
62+let walletAddress = Address(base58'3NAGTtZz6WpupSN89NZD5rMZwwziZEg4Kx4')
6163
6264 let USDN = base58'8UrfDVd5GreeUwm7uPk7eYz1eMv376kzR52C6sANPkwS'
6365
64-let stakingFeeInUSDN = 270000
66+let EURN = base58'ECBCkHS68DckpBrzLeoRgYbFg7sCVqR176mPqbXsj9pA'
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 digits12 = 12
125133
126134 let dAppThreshold = 50
127135
128136 let dAppThresholdScale2 = 100
129137
130138 let exchangeRatioLimitMin = 90000000
131139
132140 let exchangeRatioLimitMax = 110000000
133141
134142 let alpha = 50
135143
136144 let alphaDigits = 2
137145
138146 let beta = 460000000000
139147
140148 func accountBalance (assetId) = match assetId {
141149 case id: ByteVector =>
142150 assetBalance(this, id)
143151 case waves: Unit =>
144152 wavesBalance(this).available
145153 case _ =>
146154 throw("Match error")
147155 }
148156
149157
150-let stakedAmountUSDN = match getInteger(stakingAddress, ((("rpd_balance_" + toBase58String(USDN)) + "_") + toString(this))) {
151- case staked: Int =>
152- staked
153- case nothing: Unit =>
154- 0
155- case _ =>
156- throw("Match error")
157-}
158+func stakedAmount (assetId) = {
159+ let stakedAmountCalculated = match assetId {
160+ case aId: ByteVector =>
161+ if ((aId == USDN))
162+ then getInteger(stakingUSDNNSBTAddress, ((("rpd_balance_" + toBase58String(aId)) + "_") + toString(this)))
163+ else if ((aId == EURN))
164+ then getInteger(stakingEURNAddress, ((("%s%s%s__stakingBalance__" + toBase58String(aId)) + "__") + toString(this)))
165+ else 0
166+ case _: Unit =>
167+ 0
168+ case _ =>
169+ throw("Match error")
170+ }
171+ match stakedAmountCalculated {
172+ case i: Int =>
173+ i
174+ case _ =>
175+ 0
176+ }
177+ }
158178
159-let availableBalanceA = (balanceA - (if ((assetIdA == USDN))
160- then stakedAmountUSDN
161- else 0))
162179
163-let availableBalanceB = (balanceB - (if ((assetIdB == USDN))
164- then stakedAmountUSDN
165- else 0))
180+let stakedAmountA = stakedAmount(assetIdA)
166181
167-let accountBalanceWithStakedA = (accountBalance(assetIdA) + (if ((assetIdA == USDN))
168- then stakedAmountUSDN
169- else 0))
182+let stakedAmountB = stakedAmount(assetIdB)
170183
171-let accountBalanceWithStakedB = (accountBalance(assetIdB) + (if ((assetIdB == USDN))
172- then stakedAmountUSDN
173- else 0))
184+let availableBalanceA = (balanceA - stakedAmountA)
185+
186+let availableBalanceB = (balanceB - stakedAmountB)
187+
188+let accountBalanceWithStakedA = (accountBalance(assetIdA) + stakedAmountA)
189+
190+let accountBalanceWithStakedB = (accountBalance(assetIdB) + stakedAmountB)
174191
175192 let hasEnoughBalance = if ((accountBalanceWithStakedA >= balanceA))
176193 then (accountBalanceWithStakedB >= balanceB)
177194 else false
178195
179-func skewness (x,y) = ((fraction(scale12, x, y) + fraction(scale12, y, x)) / 2)
196+func skewness (x,y) = (((fraction(scale12, x, y) + fraction(scale12, y, x)) / 2) / 10000)
180197
181198
182199 func invariantCalc (x,y) = {
183200 let sk = skewness(x, y)
184201 (toInt(fraction(toBigInt((x + y)), toBigInt(scale12), pow(toBigInt(sk), digits12, toBigInt(alpha), alphaDigits, digits12, CEILING))) + (2 * toInt(fraction(pow(fraction(toBigInt(x), toBigInt(y), toBigInt(scale8)), 0, toBigInt(5), 1, (digits8 / 2), DOWN), pow(toBigInt((sk - beta)), digits12, toBigInt(alpha), alphaDigits, digits12, DOWN), toBigInt(scale12)))))
185202 }
186203
187204
188205 func calculateSendAmount (amountToSendEstimated,minTokenReceiveAmount,tokenReceiveAmount,tokenId) = {
189206 let slippageValue = (scale8 - ((scale8 * 1) / 10000000))
190207 let deltaBetweenMaxAndMinSendValue = (amountToSendEstimated - minTokenReceiveAmount)
191208 let x = (balanceA + tokenReceiveAmount)
192209 let y = (balanceB + tokenReceiveAmount)
193210 let invariantNew = if ((tokenId == assetIdA))
194211 then invariantCalc(x, (balanceB - amountToSendEstimated))
195212 else if ((tokenId == assetIdB))
196213 then invariantCalc((balanceA - amountToSendEstimated), y)
197214 else throw("Wrong asset in payment")
198215 let invariantEstimatedRatio = fraction(scale8, invariant, invariantNew)
199216 func getStepAmount (acc,step) = if ((acc == -1))
200217 then {
201218 let amountToSend = (amountToSendEstimated - ((step * deltaBetweenMaxAndMinSendValue) / 5))
202219 let stepInvariant = if ((tokenId == assetIdA))
203220 then invariantCalc(x, (balanceB - amountToSend))
204221 else invariantCalc((balanceA - amountToSend), y)
205222 if ((stepInvariant > invariant))
206223 then amountToSend
207224 else -1
208225 }
209226 else acc
210227
211228 let stepAmount = {
212229 let $l = [1, 2, 3, 4, 5]
213230 let $s = size($l)
214231 let $acc0 = -1
215232 func $f0_1 ($a,$i) = if (($i >= $s))
216233 then $a
217234 else getStepAmount($a, $l[$i])
218235
219236 func $f0_2 ($a,$i) = if (($i >= $s))
220237 then $a
221238 else throw("List size exceeds 5")
222239
223240 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
224241 }
225242 if ((0 > stepAmount))
226243 then throw("something went wrong while working with amountToSend")
227244 else if (if ((invariantEstimatedRatio > slippageValue))
228245 then (invariantNew > invariant)
229246 else false)
230247 then amountToSendEstimated
231248 else stepAmount
232249 }
233250
234251
235252 func getAssetInfo (assetId) = match assetId {
236253 case id: ByteVector =>
237254 let stringId = toBase58String(id)
238255 let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
239256 $Tuple3(stringId, info.name, info.decimals)
240257 case waves: Unit =>
241258 $Tuple3("WAVES", "WAVES", 8)
242259 case _ =>
243260 throw("Match error")
244261 }
245262
246263
247264 func suspend (cause) = [BooleanEntry(kActive, false), StringEntry(kCause, cause)]
248265
249266
250-func deductStakingFee (amount,assetId) = if ((assetId == USDN))
251- then {
252- let result = (amount - stakingFeeInUSDN)
253- if ((0 >= result))
254- then throw((((("Insufficient amount " + toString(amount)) + " to deduct staking fee ") + toString(stakingFeeInUSDN)) + " USD-N"))
255- else result
256- }
257- else amount
258-
259-
260267 func throwIsActive () = throw("DApp is already active")
261268
262269
263270 func throwIsInactive () = throw("DApp is inactive at this moment")
264271
265272
266273 func throwOnlyAdmin () = throw("Only admin can call this function")
267274
268275
269276 func throwAssets () = throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
270277
271278
272279 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))
273280
274281
275-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"))
282+func suspendSuspicious () = suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB) + ". State: ") + toString(accountBalance(assetIdA))) + " ") + assetNameA) + ", ") + toString(accountBalance(assetIdB))) + " ") + assetNameB))
276283
277284
278-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"))
285+func calcStakingFuncAndAddres (stake,assetId) = if (stake)
286+ then if ((assetId == USDN))
287+ then $Tuple2("lockNeutrino", stakingUSDNNSBTAddress)
288+ else $Tuple2("startStaking", stakingEURNAddress)
289+ else if ((assetId == USDN))
290+ then $Tuple2("unlockNeutrino", stakingUSDNNSBTAddress)
291+ else $Tuple2("stopStaking", stakingEURNAddress)
279292
280293
281-func suspendSuspicious () = suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB) + ". State: ") + toString(accountBalance(assetIdA))) + " ") + assetNameA) + ", ") + toString(accountBalance(assetIdB))) + " ") + assetNameB))
294+func calcStakingParams (stake,amount,assetId) = if (stake)
295+ then {
296+ let $t089298995 = calcStakingFuncAndAddres(stake, assetId)
297+ let call = $t089298995._1
298+ let stakingAddr = $t089298995._2
299+ $Tuple4(call, stakingAddr, nil, [AttachedPayment(assetId, amount)])
300+ }
301+ else {
302+ let $t090819147 = calcStakingFuncAndAddres(stake, assetId)
303+ let call = $t090819147._1
304+ let stakingAddr = $t090819147._2
305+ $Tuple4(call, stakingAddr, [amount, toBase58String(assetId)], nil)
306+ }
282307
283308
284309 @Callable(i)
285310 func init () = {
286- let $t089299006 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
287- let pmtAmountA = $t089299006._1
288- let pmtAssetIdA = $t089299006._2
289- let $t090119088 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
290- let pmtAmountB = $t090119088._1
291- let pmtAssetIdB = $t090119088._2
292- let $t090939170 = getAssetInfo(pmtAssetIdA)
293- let pmtStrAssetIdA = $t090939170._1
294- let pmtAssetNameA = $t090939170._2
295- let pmtDecimalsA = $t090939170._3
296- let $t091759252 = getAssetInfo(pmtAssetIdB)
297- let pmtStrAssetIdB = $t091759252._1
298- let pmtAssetNameB = $t091759252._2
299- let pmtDecimalsB = $t091759252._3
311+ let $t092529329 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
312+ let pmtAmountA = $t092529329._1
313+ let pmtAssetIdA = $t092529329._2
314+ let $t093349411 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
315+ let pmtAmountB = $t093349411._1
316+ let pmtAssetIdB = $t093349411._2
317+ let $t094169493 = getAssetInfo(pmtAssetIdA)
318+ let pmtStrAssetIdA = $t094169493._1
319+ let pmtAssetNameA = $t094169493._2
320+ let pmtDecimalsA = $t094169493._3
321+ let $t094989575 = getAssetInfo(pmtAssetIdB)
322+ let pmtStrAssetIdB = $t094989575._1
323+ let pmtAssetNameB = $t094989575._2
324+ let pmtDecimalsB = $t094989575._3
300325 if (isDefined(getBoolean(this, kActive)))
301326 then throwIsActive()
302327 else if ((pmtAssetIdA == pmtAssetIdB))
303328 then throw("Assets must be different")
304329 else {
305330 let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
306331 let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
307332 let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
308333 let shareInitialSupply = fraction(pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN), pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN), pow(10, 0, shareDecimals, 0, 0, DOWN))
309334 let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
310335 let shareIssueId = calculateAssetId(shareIssue)
311336 let invariantCalculated = invariantCalc(pmtAmountA, pmtAmountB)
312-[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)]
337+ let stake1 = if (containsElement(stakingAssets, pmtStrAssetIdA))
338+ then invoke(this, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
339+ else 0
340+ if ((stake1 == stake1))
341+ then {
342+ let stake2 = if (containsElement(stakingAssets, pmtStrAssetIdB))
343+ then invoke(this, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
344+ else 0
345+ if ((stake2 == stake2))
346+ 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)]
347+ else throw("Strict value is not equal to itself.")
348+ }
349+ else throw("Strict value is not equal to itself.")
313350 }
314351 }
315352
316353
317354
318355 @Callable(i)
319356 func replenishWithTwoTokens (slippageTolerance) = {
320357 let pmtAssetIdA = i.payments[0].assetId
321358 let pmtAssetIdB = i.payments[1].assetId
322- let pmtAmountA = deductStakingFee(i.payments[0].amount, pmtAssetIdA)
323- let pmtAmountB = deductStakingFee(i.payments[1].amount, pmtAssetIdB)
359+ let pmtAmountA = i.payments[0].amount
360+ let pmtAmountB = i.payments[1].amount
361+ let $t01209112168 = getAssetInfo(pmtAssetIdA)
362+ let pmtStrAssetIdA = $t01209112168._1
363+ let pmtAssetNameA = $t01209112168._2
364+ let pmtDecimalsA = $t01209112168._3
365+ let $t01217312367 = getAssetInfo(pmtAssetIdB)
366+ let pmtStrAssetIdB = $t01217312367._1
367+ let pmtAssetNameB = $t01217312367._2
368+ let pmtDecimalsB = $t01217312367._3
324369 let tokenRatio = fraction(fraction(scale8, balanceA, pmtAmountA), scale3, fraction(scale8, balanceB, pmtAmountB))
325370 let ratioShareTokensInA = fraction(scale8, pmtAmountA, balanceA)
326371 let ratioShareTokensInB = fraction(scale8, pmtAmountB, balanceB)
327372 let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scale8)
328373 let invariantCalculated = invariantCalc((balanceA + pmtAmountA), (balanceB + pmtAmountB))
329374 if (!(isActive))
330375 then throwIsInactive()
331376 else if (if ((0 > slippageTolerance))
332377 then true
333378 else (slippageTolerance > 10))
334379 then throw("Slippage tolerance must be <= 1%")
335380 else if ((size(i.payments) != 2))
336381 then throw("Two attached assets expected")
337382 else if (if ((pmtAssetIdA != assetIdA))
338383 then true
339384 else (pmtAssetIdB != assetIdB))
340385 then throwAssets()
341386 else if (if ((((scale3 * (slippageScale3 - slippageTolerance)) / slippageScale3) > tokenRatio))
342387 then true
343388 else (tokenRatio > ((scale3 * (slippageScale3 + slippageTolerance)) / slippageScale3)))
344389 then throw("Incorrect assets amount: amounts must have the contract ratio")
345390 else if ((shareTokenToPayAmount == 0))
346391 then throw("Too small amount to replenish")
347392 else if (!(hasEnoughBalance))
348393 then ([ScriptTransfer(i.caller, pmtAmountA, pmtAssetIdA), ScriptTransfer(i.caller, pmtAmountB, pmtAssetIdB)] ++ suspendSuspicious())
349- 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)]
394+ else {
395+ let stake1 = if (containsElement(stakingAssets, pmtStrAssetIdA))
396+ then invoke(this, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
397+ else 0
398+ if ((stake1 == stake1))
399+ then {
400+ let stake2 = if (containsElement(stakingAssets, pmtStrAssetIdB))
401+ then invoke(this, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
402+ else 0
403+ if ((stake2 == stake2))
404+ 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)]
405+ else throw("Strict value is not equal to itself.")
406+ }
407+ else throw("Strict value is not equal to itself.")
408+ }
350409 }
351410
352411
353412
354413 @Callable(i)
355414 func replenishWithOneToken (virtualSwapTokenPay,virtualSwapTokenGet) = {
356- let $t01359513670 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
357- let pmtAmount = $t01359513670._1
358- let pmtAssetId = $t01359513670._2
415+ let $t01466614741 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
416+ let pmtAmount = $t01466614741._1
417+ let pmtAssetId = $t01466614741._2
418+ let $t01474614819 = getAssetInfo(pmtAssetId)
419+ let pmtStrAssetId = $t01474614819._1
420+ let pmtAssetName = $t01474614819._2
421+ let pmtDecimals = $t01474614819._3
359422 let pmtMinThreshold = 5000000
360423 let thresholdValueForMinTolerance = 50000000
361424 let tolerance = if ((thresholdValueForMinTolerance > pmtAmount))
362425 then 100000
363426 else 1
364427 let slippageValueMinForReplenish = (scale8 - ((scale8 * tolerance) / 10000000))
365428 let slippageValueMaxForReplenish = (scale8 + ((scale8 * tolerance) / 10000000))
366429 let slippageValueMinForSwap = (scale8 - ((scale8 * 1) / 10000000))
367430 if (!(isActive))
368431 then throwIsInactive()
369432 else if ((pmtMinThreshold > pmtAmount))
370433 then throw((((("Payment amount " + toString(pmtAmount)) + " does not exceed the minimum amount of ") + toString(pmtMinThreshold)) + " tokens"))
371434 else if ((size(i.payments) != 1))
372435 then throw("One attached payment expected")
373436 else if (!(hasEnoughBalance))
374437 then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
375438 else if (if ((pmtAssetId != assetIdA))
376439 then (pmtAssetId != assetIdB)
377440 else false)
378441 then throwAssets()
379442 else {
380- let $t01468215447 = if ((pmtAssetId == assetIdA))
443+ let $t01583116596 = if ((pmtAssetId == assetIdA))
381444 then $Tuple7((pmtAmount - virtualSwapTokenPay), virtualSwapTokenGet, (balanceA + virtualSwapTokenPay), (balanceB - virtualSwapTokenGet), invariantCalc((balanceA + pmtAmount), balanceB), (balanceA + pmtAmount), balanceB)
382445 else $Tuple7(virtualSwapTokenGet, (pmtAmount - virtualSwapTokenPay), (balanceA - virtualSwapTokenGet), (balanceB + virtualSwapTokenPay), invariantCalc(balanceA, (balanceB + pmtAmount)), balanceA, (balanceB + pmtAmount))
383- let virtualReplenishA = $t01468215447._1
384- let virtualReplenishB = $t01468215447._2
385- let balanceAfterSwapA = $t01468215447._3
386- let balanceAfterSwapB = $t01468215447._4
387- let invariantCalculated = $t01468215447._5
388- let newBalanceA = $t01468215447._6
389- let newBalanceB = $t01468215447._7
446+ let virtualReplenishA = $t01583116596._1
447+ let virtualReplenishB = $t01583116596._2
448+ let balanceAfterSwapA = $t01583116596._3
449+ let balanceAfterSwapB = $t01583116596._4
450+ let invariantCalculated = $t01583116596._5
451+ let newBalanceA = $t01583116596._6
452+ let newBalanceB = $t01583116596._7
390453 let newBalanceEntry = if ((pmtAssetId == assetIdA))
391454 then IntegerEntry(kBalanceA, newBalanceA)
392455 else IntegerEntry(kBalanceB, newBalanceB)
393456 let invariantNew = invariantCalc(balanceAfterSwapA, balanceAfterSwapB)
394457 let invariantEstimatedRatio = fraction(scale8, invariant, invariantNew)
395458 let ratioVirtualBalanceToVirtualReplenish = (fraction((scale8 * scale8), balanceAfterSwapA, balanceAfterSwapB) / fraction(scale8, virtualReplenishA, virtualReplenishB))
396459 let dAppThresholdAmount = fraction((newBalanceA + newBalanceB), dAppThreshold, (2 * dAppThresholdScale2))
397460 if (if ((slippageValueMinForSwap >= invariantEstimatedRatio))
398461 then true
399462 else (invariant > invariantNew))
400463 then throw("Incorrect virtualSwapTokenPay or virtualSwapTokenGet value")
401464 else if (if ((slippageValueMinForReplenish > ratioVirtualBalanceToVirtualReplenish))
402465 then true
403466 else (ratioVirtualBalanceToVirtualReplenish > slippageValueMaxForReplenish))
404467 then throw("Swap with virtualSwapTokenPay and virtualSwapTokenGet is possible, but ratio after virtual swap is incorrect")
405468 else if (if ((dAppThresholdAmount > newBalanceA))
406469 then true
407470 else (dAppThresholdAmount > newBalanceB))
408471 then throwThreshold(dAppThresholdAmount, newBalanceA, newBalanceB)
409472 else {
410- let ratioShareTokensInA = fraction(deductStakingFee(virtualReplenishA, assetIdA), scale8, balanceAfterSwapA)
411- let ratioShareTokensInB = fraction(deductStakingFee(virtualReplenishB, assetIdB), scale8, balanceAfterSwapB)
412- let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scale8)
473+ let stake1 = if (containsElement(stakingAssets, pmtStrAssetId))
474+ then invoke(this, "stakeUnstake", [true, pmtAmount, pmtStrAssetId], nil)
475+ else 0
476+ if ((stake1 == stake1))
477+ then {
478+ let ratioShareTokensInA = fraction(virtualReplenishA, scale8, balanceAfterSwapA)
479+ let ratioShareTokensInB = fraction(virtualReplenishB, scale8, balanceAfterSwapB)
480+ let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scale8)
413481 [Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId), IntegerEntry(kShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), newBalanceEntry, IntegerEntry(kInvariant, invariantCalculated)]
482+ }
483+ else throw("Strict value is not equal to itself.")
414484 }
415485 }
416486 }
417487
418488
419489
420490 @Callable(i)
421491 func withdraw () = {
422- let $t01759217735 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
423- let pmtAmount = $t01759217735._1
424- let pmtAssetId = $t01759217735._2
425- let amountToPayA = deductStakingFee(fraction(pmtAmount, balanceA, shareAssetSupply), assetIdA)
426- let amountToPayB = deductStakingFee(fraction(pmtAmount, balanceB, shareAssetSupply), assetIdB)
492+ let $t01882218965 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
493+ let pmtAmount = $t01882218965._1
494+ let pmtAssetId = $t01882218965._2
495+ let amountToPayA = fraction(pmtAmount, balanceA, shareAssetSupply)
496+ let amountToPayB = fraction(pmtAmount, balanceB, shareAssetSupply)
427497 let invariantCalculated = invariantCalc((balanceA - amountToPayA), (balanceB - amountToPayB))
428498 if (!(isActive))
429499 then throwIsInactive()
430500 else if ((size(i.payments) != 1))
431501 then throw("One attached payment expected")
432502 else if ((pmtAssetId != shareAssetId))
433503 then throw(("Incorrect asset attached. Expected: " + toBase58String(shareAssetId)))
434504 else if (!(hasEnoughBalance))
435505 then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
436- else if (if ((amountToPayA > availableBalanceA))
437- then true
438- else (amountToPayB > availableBalanceB))
439- then throwInsufficientAvailableBalances(amountToPayA, amountToPayB)
440- 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)]
506+ else {
507+ let stake1 = if (containsElement(stakingAssets, strAssetIdA))
508+ then invoke(this, "stakeUnstake", [false, amountToPayA, strAssetIdA], nil)
509+ else 0
510+ if ((stake1 == stake1))
511+ then {
512+ let stake2 = if (containsElement(stakingAssets, strAssetIdB))
513+ then invoke(this, "stakeUnstake", [false, amountToPayB, strAssetIdB], nil)
514+ else 0
515+ if ((stake2 == stake2))
516+ 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)]
517+ else throw("Strict value is not equal to itself.")
518+ }
519+ else throw("Strict value is not equal to itself.")
520+ }
441521 }
442522
443523
444524
445525 @Callable(i)
446526 func exchange (estimatedAmountToReceive,minAmountToReceive) = {
447- let $t01909319168 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
448- let pmtAmount = $t01909319168._1
449- let pmtAssetId = $t01909319168._2
527+ let $t02047920554 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
528+ let pmtAmount = $t02047920554._1
529+ let pmtAssetId = $t02047920554._2
450530 if (!(isActive))
451531 then throwIsInactive()
452532 else if ((0 >= estimatedAmountToReceive))
453533 then throw(("Estimated amount must be positive. Actual: " + toString(estimatedAmountToReceive)))
454534 else if ((minAmountToReceive > estimatedAmountToReceive))
455535 then throw(((("Minimal amount can't be greater than estimated. Estimated: " + toString(estimatedAmountToReceive)) + ". Minimal: ") + toString(minAmountToReceive)))
456536 else if ((size(i.payments) != 1))
457537 then throw("One attached payment expected")
458538 else if (!(hasEnoughBalance))
459539 then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
460540 else if (if ((pmtAssetId != assetIdA))
461541 then (pmtAssetId != assetIdB)
462542 else false)
463543 then throwAssets()
464544 else if ((10000000 > pmtAmount))
465545 then throw("Only swap of 10.000000 or more tokens is allowed")
466546 else if (if ((exchangeRatioLimitMin > fraction(scale8, minAmountToReceive, pmtAmount)))
467547 then true
468548 else (fraction(scale8, estimatedAmountToReceive, pmtAmount) > exchangeRatioLimitMax))
469549 then throw("Incorrect args and pmt ratio")
470550 else {
471551 let sendAssetId = if ((pmtAssetId == assetIdA))
472552 then assetIdB
473553 else assetIdA
474554 let amount = calculateSendAmount(estimatedAmountToReceive, minAmountToReceive, pmtAmount, pmtAssetId)
475555 let governanceReward = fraction(amount, feeGovernance, feeScale6)
476556 let amountMinusFee = fraction(amount, (feeScale6 - fee), feeScale6)
477- let $t02059020852 = if ((pmtAssetId == assetIdA))
557+ let $t02197622238 = if ((pmtAssetId == assetIdA))
478558 then $Tuple2((balanceA + pmtAmount), ((balanceB - amountMinusFee) - governanceReward))
479559 else $Tuple2(((balanceA - amountMinusFee) - governanceReward), (balanceB + pmtAmount))
480- let newBalanceA = $t02059020852._1
481- let newBalanceB = $t02059020852._2
560+ let newBalanceA = $t02197622238._1
561+ let newBalanceB = $t02197622238._2
482562 let dAppThresholdAmount = fraction((newBalanceA + newBalanceB), dAppThreshold, (2 * dAppThresholdScale2))
483563 if (if ((dAppThresholdAmount > newBalanceA))
484564 then true
485565 else (dAppThresholdAmount > newBalanceB))
486566 then throwThreshold(dAppThresholdAmount, newBalanceA, newBalanceB)
487- else if (if (if ((assetIdA == USDN))
488- then (sendAssetId == assetIdA)
489- else false)
490- then (stakedAmountUSDN >= newBalanceA)
491- else false)
492- then throwInsufficientAvailableBalance(amountMinusFee, availableBalanceA, assetNameA)
493- else if (if (if ((assetIdB == USDN))
494- then (sendAssetId == assetIdB)
495- else false)
496- then (stakedAmountUSDN >= newBalanceB)
497- else false)
498- then throwInsufficientAvailableBalance(amountMinusFee, availableBalanceB, assetNameB)
499- else [IntegerEntry(kBalanceA, newBalanceA), IntegerEntry(kBalanceB, newBalanceB), IntegerEntry(kInvariant, invariantCalc(newBalanceA, newBalanceB)), ScriptTransfer(i.caller, amountMinusFee, sendAssetId), ScriptTransfer(govAddr, governanceReward, sendAssetId)]
567+ else {
568+ let $t02253622609 = getAssetInfo(pmtAssetId)
569+ let pmtStrAssetId = $t02253622609._1
570+ let pmtAssetName = $t02253622609._2
571+ let pmtDecimals = $t02253622609._3
572+ let $t02262222699 = getAssetInfo(sendAssetId)
573+ let sendStrAssetId = $t02262222699._1
574+ let sendAssetName = $t02262222699._2
575+ let sendDecimals = $t02262222699._3
576+ let stake1 = if (containsElement(stakingAssets, pmtStrAssetId))
577+ then invoke(this, "stakeUnstake", [true, pmtAmount, pmtStrAssetId], nil)
578+ else 0
579+ if ((stake1 == stake1))
580+ then {
581+ let stake2 = if (containsElement(stakingAssets, sendStrAssetId))
582+ then invoke(this, "stakeUnstake", [false, (amountMinusFee + governanceReward), sendStrAssetId], nil)
583+ else 0
584+ if ((stake2 == stake2))
585+ then [IntegerEntry(kBalanceA, newBalanceA), IntegerEntry(kBalanceB, newBalanceB), IntegerEntry(kInvariant, invariantCalc(newBalanceA, newBalanceB)), ScriptTransfer(i.caller, amountMinusFee, sendAssetId), ScriptTransfer(walletAddress, governanceReward, sendAssetId)]
586+ else throw("Strict value is not equal to itself.")
587+ }
588+ else throw("Strict value is not equal to itself.")
589+ }
500590 }
501591 }
502592
503593
504594
505595 @Callable(i)
506596 func shutdown () = if (!(isActive))
507597 then throw(("DApp is already suspended. Cause: " + valueOrElse(getString(this, kCause), "the cause wasn't specified")))
508598 else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, admStartStop], i.callerPublicKey)))
509599 then throwOnlyAdmin()
510600 else suspend("Paused by admin")
511601
512602
513603
514604 @Callable(i)
515605 func activate () = if (isActive)
516606 then throwIsActive()
517607 else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, admStartStop], i.callerPublicKey)))
518608 then throwOnlyAdmin()
519609 else [BooleanEntry(kActive, true), DeleteEntry(kCause)]
520610
521611
522612
523613 @Callable(i)
524-func takeIntoAccountExtraFunds (amountLeave) = {
525- let uncountableA = (accountBalanceWithStakedA - balanceA)
526- let uncountableB = (accountBalanceWithStakedB - balanceB)
527- let amountEnrollA = (uncountableA - (if ((assetIdA == unit))
528- then amountLeave
529- else 0))
530- let amountEnrollB = (uncountableB - (if ((assetIdB == unit))
531- then amountLeave
532- else 0))
614+func takeIntoAccountExtraFunds () = {
615+ let amountEnrollA = (accountBalanceWithStakedA - balanceA)
616+ let amountEnrollB = (accountBalanceWithStakedB - balanceB)
533617 let invariantNew = invariantCalc((balanceA + amountEnrollA), (balanceB + amountEnrollB))
534618 if (!(isActive))
535619 then throwIsInactive()
536- else if ((i.caller != this))
537- then throwOnlyAdmin()
538- else if ((0 > amountLeave))
539- then throw(("Argument 'amountLeave' cannot be negative. Actual: " + toString(amountLeave)))
540- else if (if ((0 > uncountableA))
541- then true
542- else (0 > uncountableB))
543- then suspend("Enroll amount negative")
544- else if (if ((0 > amountEnrollA))
545- then true
546- else (0 > amountEnrollB))
547- then throw("Too large amountLeave")
548- else [IntegerEntry(kInvariant, invariantNew), IntegerEntry(kBalanceA, (balanceA + amountEnrollA)), IntegerEntry(kBalanceB, (balanceB + amountEnrollB)), IntegerEntry(("last_income_" + strAssetIdA), amountEnrollA), IntegerEntry(("last_income_" + strAssetIdB), amountEnrollB)]
620+ else if ((i.caller != walletAddress))
621+ then throw("Only the wallet can call this function")
622+ else if (if ((0 > amountEnrollA))
623+ then true
624+ else (0 > amountEnrollB))
625+ then suspend("Enroll amount negative")
626+ else if (if ((amountEnrollA == 0))
627+ then (amountEnrollB == 0)
628+ else false)
629+ then throw("No money to take")
630+ else {
631+ let stake1 = if (if (containsElement(stakingAssets, strAssetIdA))
632+ then (amountEnrollA > 0)
633+ else false)
634+ then invoke(this, "stakeUnstake", [true, amountEnrollA, strAssetIdA], nil)
635+ else 0
636+ if ((stake1 == stake1))
637+ then {
638+ let stake2 = if (if (containsElement(stakingAssets, strAssetIdB))
639+ then (amountEnrollB > 0)
640+ else false)
641+ then invoke(this, "stakeUnstake", [true, amountEnrollB, strAssetIdB], nil)
642+ else 0
643+ if ((stake2 == stake2))
644+ then [IntegerEntry(kInvariant, invariantNew), IntegerEntry(kBalanceA, (balanceA + amountEnrollA)), IntegerEntry(kBalanceB, (balanceB + amountEnrollB)), IntegerEntry(("last_income_" + strAssetIdA), amountEnrollA), IntegerEntry(("last_income_" + strAssetIdB), amountEnrollB)]
645+ else throw("Strict value is not equal to itself.")
646+ }
647+ else throw("Strict value is not equal to itself.")
648+ }
549649 }
650+
651+
652+
653+@Callable(i)
654+func stakeUnstake (stake,amount,assetIdString) = if ((i.caller != this))
655+ then throw("Only contract itself can invoke this function")
656+ else {
657+ let $t02576125864 = calcStakingParams(stake, amount, fromBase58String(assetIdString))
658+ let call = $t02576125864._1
659+ let addr = $t02576125864._2
660+ let params = $t02576125864._3
661+ let payments = $t02576125864._4
662+ let inv = invoke(addr, call, params, payments)
663+ if ((inv == inv))
664+ then nil
665+ else throw("Strict value is not equal to itself.")
666+ }
667+
668+
669+
670+@Callable(i)
671+func stakeAll () = if (!(isActive))
672+ then throw("DApp is inactive at this moment")
673+ else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, admStartStop], i.callerPublicKey)))
674+ then throw("Only admin can call this function")
675+ else {
676+ let stake1 = if (containsElement(stakingAssets, strAssetIdA))
677+ then {
678+ let amountA = (balanceA - stakedAmountA)
679+ if ((amountA > 0))
680+ then invoke(this, "stakeUnstake", [true, amountA, strAssetIdA], nil)
681+ else 0
682+ }
683+ else 0
684+ if ((stake1 == stake1))
685+ then {
686+ let stake2 = if (containsElement(stakingAssets, strAssetIdB))
687+ then {
688+ let amountB = (balanceB - stakedAmountB)
689+ if ((amountB > 0))
690+ then invoke(this, "stakeUnstake", [true, amountB, strAssetIdB], nil)
691+ else 0
692+ }
693+ else 0
694+ if ((stake2 == stake2))
695+ then nil
696+ else throw("Strict value is not equal to itself.")
697+ }
698+ else throw("Strict value is not equal to itself.")
699+ }
550700
551701
552702 @Verifier(tx)
553703 func verify () = {
554704 let multiSignedByAdmins = {
555705 let adminPubKey1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
556706 then 1
557707 else 0
558708 let adminPubKey2Signed = if (sigVerify(tx.bodyBytes, tx.proofs[1], adminPubKey2))
559709 then 1
560710 else 0
561711 let adminPubKey3Signed = if (sigVerify(tx.bodyBytes, tx.proofs[2], adminPubKey3))
562712 then 1
563713 else 0
564714 (((adminPubKey1Signed + adminPubKey2Signed) + adminPubKey3Signed) >= 2)
565715 }
566716 match tx {
567717 case inv: InvokeScriptTransaction =>
568718 let callTakeIntoAccount = if ((inv.dApp == this))
569719 then (inv.function == "takeIntoAccountExtraFunds")
570720 else false
571- let callStaking = if ((inv.dApp == stakingAddress))
572- then if (if (if ((inv.function == "lockNeutrino"))
573- then (size(inv.payments) == 1)
574- else false)
575- then (inv.payments[0].assetId == USDN)
576- else false)
577- then true
578- else if ((inv.function == "unlockNeutrino"))
579- then (size(inv.payments) == 0)
580- else false
581- else false
582- let exchangeToWaves = if (if (if ((inv.dApp == USDNToWavesExchanger))
583- then (inv.function == "exchange")
584- else false)
585- then (assetIdA == USDN)
586- else false)
587- then true
588- else if (if ((assetIdB == USDN))
589- then (size(inv.payments) == 1)
590- else false)
591- then (inv.payments[0].assetId == USDN)
592- else false
593721 let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
594722 then true
595723 else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey2))
596724 then true
597725 else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey3))
598726 then true
599727 else sigVerify(tx.bodyBytes, tx.proofs[0], admStaking)
600- if (if (if (if (callTakeIntoAccount)
601- then true
602- else callStaking)
603- then true
604- else exchangeToWaves)
728+ if (if (callTakeIntoAccount)
605729 then signedByAdmin
606730 else false)
607731 then true
608732 else multiSignedByAdmins
609733 case _ =>
610734 multiSignedByAdmins
611735 }
612736 }
613737

github/deemru/w8io/873ac7e 
114.24 ms