tx · GeNcE4sbrT2XvrJngU5vHRqGqxsomEWQKGHwHCVuNL5P

3MzGPAZokuNfqjMuP7yDXFATZjhjtEP5UCa:  -0.03700000 Waves

2023.02.04 14:52 [2434846] smart account 3MzGPAZokuNfqjMuP7yDXFATZjhjtEP5UCa > SELF 0.00000000 Waves

{ "type": 13, "id": "GeNcE4sbrT2XvrJngU5vHRqGqxsomEWQKGHwHCVuNL5P", "fee": 3700000, "feeAssetId": null, "timestamp": 1675511581731, "version": 2, "chainId": 84, "sender": "3MzGPAZokuNfqjMuP7yDXFATZjhjtEP5UCa", "senderPublicKey": "4EBKd2zSCvpiSLeyovT5FUuMvGpi6oxdBAbvQybSYi6p", "proofs": [ "4segwrRgEmPARpnuAbN7JmzLzVvMHTkw6YuKHKo9ptGKKKEEwomeTcW7tVk8acbZe2jhXhmGckHsuM5MjTXD5Lhp" ], "script": "base64:BgJLCAISBAoCCAgSAwoBCBIAEgMKAQgSCgoICAEBAQEBAQgSCwoJCAEBAQgBAQEBEg0KCwgIAQEBAQEBCAgBEgMKAQESAwoBARIDCgEBOgAUa19jb29yZGluYXRvckFkZHJlc3MCFGtfY29vcmRpbmF0b3JBZGRyZXNzAA9rX2FkbWluX2FkZHJlc3MCD2tfYWRtaW5fYWRkcmVzcwANa19xdW90ZV9hc3NldAINa19xdW90ZV9hc3NldAAFa19hbW0CBWtfYW1tABFrX21hbmFnZXJfYWRkcmVzcwIRa19tYW5hZ2VyX2FkZHJlc3MAEmtfcG9zaXRpb25TZXF1ZW5jZQISa19wb3NpdGlvblNlcXVlbmNlAA5rX3Bvc2l0aW9uU2l6ZQIOa19wb3NpdGlvblNpemUABWtfZmVlAgVrX2ZlZQAQa19leGVjdXRlZE9yZGVycwIQa19leGVjdXRlZE9yZGVycwAQa19jYW5jZWxlZE9yZGVycwIQa19jYW5jZWxlZE9yZGVycwAHa19vcmRlcgIHa19vcmRlcgANa19sYXN0T3JkZXJJZAINa19sYXN0T3JkZXJJZAAQa190cmFkZXJPcmRlckNudAIQa190cmFkZXJPcmRlckNudAAQa190cmFkZXJPcmRlcklkcwIQa190cmFkZXJPcmRlcklkcwAIa19zZW5kZXICCGtfc2VuZGVyAA1rX2luaXRpYWxpemVkAg1rX2luaXRpYWxpemVkAARTVE9QAAEABFRBS0UAAgAFTElNSVQAAwAETE9ORwABAAVTSE9SVAACAAhJTkNSRUFTRQABAAhERUNSRUFTRQACABlNQVhfVFJBREVSX09SREVSU19QRVJfQU1NAAUABFRJTUUIBQlsYXN0QmxvY2sJdGltZXN0YW1wAAxERUNJTUFMX1VOSVQJAGgCAAEJAGgCCQBoAgkAaAIJAGgCCQBoAgAKAAoACgAKAAoACgAMU1BSRUFEX0xJTUlUCQBpAgUMREVDSU1BTF9VTklUAMgBAQNhYnMBAl94AwkAZgIFAl94AAAFAl94CQEBLQEFAl94AQRkaXZkAgJfeAJfeQkAbgQFAl94BQxERUNJTUFMX1VOSVQFAl95BQhIQUxGRVZFTgEEbXVsZAICX3gCX3kJAG4EBQJfeAUCX3kFDERFQ0lNQUxfVU5JVAUISEFMRkVWRU4BBG1pbnYCAl94Al95AwkAZgIFAl94BQJfeQUCX3kFAl94AQ50b0NvbXBvc2l0ZUtleQIEX2tleQhfYWRkcmVzcwkArAICCQCsAgIFBF9rZXkCAV8FCF9hZGRyZXNzARBleGVjdXRlZE9yZGVyS2V5AQhfb3JkZXJJZAkArAICCQCsAgIFEGtfZXhlY3V0ZWRPcmRlcnMCAV8JAKQDAQUIX29yZGVySWQBEGNhbmNlbGVkT3JkZXJLZXkBCF9vcmRlcklkCQCsAgIJAKwCAgUQa19jYW5jZWxlZE9yZGVycwIBXwkApAMBBQhfb3JkZXJJZAEIb3JkZXJLZXkBCF9vcmRlcklkCQEOdG9Db21wb3NpdGVLZXkCBQdrX29yZGVyCQCkAwEFCF9vcmRlcklkARN0cmFkZXJPcmRlckNvdW50S2V5AgRfYW1tB190cmFkZXIJAKwCAgkArAICCQCsAgIJAKwCAgUQa190cmFkZXJPcmRlckNudAIBXwUEX2FtbQIBXwUHX3RyYWRlcgERdHJhZGVyT3JkZXJJZHNLZXkCBF9hbW0HX3RyYWRlcgkArAICCQCsAgIJAKwCAgkArAICBRBrX3RyYWRlck9yZGVySWRzAgFfBQRfYW1tAgFfBQdfdHJhZGVyAQtjb29yZGluYXRvcgAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQERQGV4dHJOYXRpdmUoMTA1MykCBQR0aGlzBRRrX2Nvb3JkaW5hdG9yQWRkcmVzcwITQ29vcmRpbmF0b3Igbm90IHNldAEKcXVvdGVBc3NldAAJANkEAQkBEUBleHRyTmF0aXZlKDEwNTMpAgkBC2Nvb3JkaW5hdG9yAAUNa19xdW90ZV9hc3NldAEObWFuYWdlckFkZHJlc3MACQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkBEUBleHRyTmF0aXZlKDEwNTMpAgkBC2Nvb3JkaW5hdG9yAAURa19tYW5hZ2VyX2FkZHJlc3MCD01hbmFnZXIgbm90IHNldAELaXNXaGl0ZWxpc3QBCF9hZGRyZXNzCQELdmFsdWVPckVsc2UCCQCbCAIJAQtjb29yZGluYXRvcgAJAQ50b0NvbXBvc2l0ZUtleQIFBWtfYW1tBQhfYWRkcmVzcwcBC2luaXRpYWxpemVkAAkBC3ZhbHVlT3JFbHNlAgkAmwgCBQR0aGlzBQ1rX2luaXRpYWxpemVkBwEHaXNWYWxpZAEIX29yZGVySWQDCQELdmFsdWVPckVsc2UCCQCbCAIFBHRoaXMJARBleGVjdXRlZE9yZGVyS2V5AQUIX29yZGVySWQHCQACAQkArAICAhhPcmRlciBhbHJlYWR5IGV4ZWN1dGVkOiAJAKQDAQUIX29yZGVySWQDCQELdmFsdWVPckVsc2UCCQCbCAIFBHRoaXMJARBjYW5jZWxlZE9yZGVyS2V5AQUIX29yZGVySWQHCQACAQkArAICAhlPcmRlciBhbHJlYWR5IGNhbmNlbGxlZDogCQCkAwEFCF9vcmRlcklkBgEOY3VycmVudE9yZGVySWQACQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFDWtfbGFzdE9yZGVySWQAAAETZ2V0VHJhZGVyT3JkZXJDb3VudAIEX2FtbQdfdHJhZGVyBANrZXkJARN0cmFkZXJPcmRlckNvdW50S2V5AgUEX2FtbQUHX3RyYWRlcgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQNrZXkAAAESdHJhZGVyQW1tT3JkZXJzSWRzAgRfYW1tB190cmFkZXIEA2tleQkBEXRyYWRlck9yZGVySWRzS2V5AgUEX2FtbQUHX3RyYWRlcgQDdmFsCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFA2tleQIAAwkAAAIFA3ZhbAIABQNuaWwJALUJAgUDdmFsAgEsAQhnZXRPcmRlcgEIX29yZGVySWQECG9yZGVyU3RyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUEdGhpcwkBCG9yZGVyS2V5AQUIX29yZGVySWQJAKwCAgISSW52YWxpZCBvcmRlciBpZDogCQCkAwEFCF9vcmRlcklkBA1vcmRlclBhcnRMaXN0CQC1CQIFCG9yZGVyU3RyAgEsBANhbW0JAJEDAgUNb3JkZXJQYXJ0TGlzdAAABAZ0cmFkZXIJAJEDAgUNb3JkZXJQYXJ0TGlzdAABBAhhbW91bnRJbgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQC2CQEJAJEDAgUNb3JkZXJQYXJ0TGlzdAACAhBJbnZhbGlkIGFtb3VudEluBAhsZXZlcmFnZQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQC2CQEJAJEDAgUNb3JkZXJQYXJ0TGlzdAADAhBJbnZhbGlkIGxldmVyYWdlBAR0eXBlCQETdmFsdWVPckVycm9yTWVzc2FnZQIJALYJAQkAkQMCBQ1vcmRlclBhcnRMaXN0AAQCDEludmFsaWQgdHlwZQQMdHJpZ2dlclByaWNlCQETdmFsdWVPckVycm9yTWVzc2FnZQIJALYJAQkAkQMCBQ1vcmRlclBhcnRMaXN0AAUCFEludmFsaWQgdHJpZ2dlclByaWNlBAtwYXltZW50VXNkbgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQC2CQEJAJEDAgUNb3JkZXJQYXJ0TGlzdAAGAhNJbnZhbGlkIHBheW1lbnRVc2RuBARzaWRlCQETdmFsdWVPckVycm9yTWVzc2FnZQIJALYJAQkAkQMCBQ1vcmRlclBhcnRMaXN0AAcCDEludmFsaWQgc2lkZQQHcmVmTGluawkAkQMCBQ1vcmRlclBhcnRMaXN0AAgECnBvc2l0aW9uSWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAtgkBCQCRAwIFDW9yZGVyUGFydExpc3QACQISSW52YWxpZCBwb3NpdGlvbklkBApsaW1pdFByaWNlCQETdmFsdWVPckVycm9yTWVzc2FnZQIJALYJAQkAkQMCBQ1vcmRlclBhcnRMaXN0AAoCEkludmFsaWQgbGltaXRQcmljZQkAnQoLBQNhbW0FBnRyYWRlcgUIYW1vdW50SW4FCGxldmVyYWdlBQR0eXBlBQx0cmlnZ2VyUHJpY2UFC3BheW1lbnRVc2RuBQRzaWRlBQdyZWZMaW5rBQpwb3NpdGlvbklkBQpsaW1pdFByaWNlAQ5nZXRNYXJrZXRQcmljZQEEX2FtbQQBcwkA/AcECQERQGV4dHJOYXRpdmUoMTA2MikBBQRfYW1tAhBjb21wdXRlU3BvdFByaWNlBQNuaWwFA25pbAMJAAACBQFzBQFzBANyZXMEByRtYXRjaDAFAXMDCQABAgUHJG1hdGNoMAIDSW50BAF0BQckbWF0Y2gwBQF0CQACAQIfSW52YWxpZCBjb21wdXRlU3BvdFByaWNlIHJlc3VsdAkBBXZhbHVlAQUDcmVzCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQZnZXRGZWUCBF9hbW0HX3RyYWRlcgQBcwkA/AcECQERQGV4dHJOYXRpdmUoMTA2MikBBQRfYW1tAh9jb21wdXRlRmVlRm9yVHJhZGVyV2l0aEFydGlmYWN0CQDMCAIFB190cmFkZXIJAMwIAgIABQNuaWwFA25pbAMJAAACBQFzBQFzBANyZXMEByRtYXRjaDAFAXMDCQABAgUHJG1hdGNoMAIOKEludCwgQm9vbGVhbikEAXQFByRtYXRjaDAIBQF0Al8xCQACAQIuSW52YWxpZCBjb21wdXRlRmVlRm9yVHJhZGVyV2l0aEFydGlmYWN0IHJlc3VsdAkBBXZhbHVlAQUDcmVzCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQ9nZXRQb3NpdGlvblNpemUCBF9hbW0HX3RyYWRlcgQDYW1tCQERQGV4dHJOYXRpdmUoMTA2MikBBQRfYW1tBAdzaXplS2V5CQEOdG9Db21wb3NpdGVLZXkCBQ5rX3Bvc2l0aW9uU2l6ZQUHX3RyYWRlcgkBC3ZhbHVlT3JFbHNlAgkAmggCBQNhbW0FB3NpemVLZXkAAAENZ2V0UG9zaXRpb25JZAIEX2FtbQdfdHJhZGVyBANhbW0JARFAZXh0ck5hdGl2ZSgxMDYyKQEFBF9hbW0EBnNlcUtleQkBDnRvQ29tcG9zaXRlS2V5AgUSa19wb3NpdGlvblNlcXVlbmNlBQdfdHJhZGVyCQELdmFsdWVPckVsc2UCCQCaCAIFA2FtbQUGc2VxS2V5AAABCWdldFNwcmVhZAEGX3ByaWNlCQEEbXVsZAIFBl9wcmljZQUMU1BSRUFEX0xJTUlUAQlzYXZlT3JkZXIMCF9vcmRlcklkBF9hbW0HX3RyYWRlcglfYW1vdW50SW4JX2xldmVyYWdlBV90eXBlDV90cmlnZ2VyUHJpY2UMX3BheW1lbnRVc2RuBV9zaWRlCF9yZWZMaW5rC19wb3NpdGlvbklkC19saW1pdFByaWNlBAhvcmRlclN0cgkAuQkCCQDMCAIFBF9hbW0JAMwIAgUHX3RyYWRlcgkAzAgCCQCkAwEFCV9hbW91bnRJbgkAzAgCCQCkAwEFCV9sZXZlcmFnZQkAzAgCCQCkAwEFBV90eXBlCQDMCAIJAKQDAQUNX3RyaWdnZXJQcmljZQkAzAgCCQCkAwEFDF9wYXltZW50VXNkbgkAzAgCCQCkAwEFBV9zaWRlCQDMCAIFCF9yZWZMaW5rCQDMCAIJAKQDAQULX3Bvc2l0aW9uSWQJAMwIAgkApAMBBQtfbGltaXRQcmljZQUDbmlsAgEsCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQhvcmRlcktleQEFCF9vcmRlcklkBQhvcmRlclN0cgUDbmlsARBhZGRSZW1vdmVPcmRlcklkBAhfb3JkZXJJZARfYW1tB190cmFkZXIEX2FkZAQIb3JkZXJJZHMJARJ0cmFkZXJBbW1PcmRlcnNJZHMCBQRfYW1tBQdfdHJhZGVyBAtvcmRlcklkc05ldwMFBF9hZGQJAM0IAgUIb3JkZXJJZHMJAKQDAQUIX29yZGVySWQJANEIAgUIb3JkZXJJZHMJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAzwgCBQhvcmRlcklkcwkApAMBBQhfb3JkZXJJZAkArAICAhJObyBvcmRlciB3aXRoIGlkOiAJAKQDAQUIX29yZGVySWQEDm9yZGVySWRzTmV3U3RyCQC5CQIFC29yZGVySWRzTmV3AgEsCQDMCAIJAQtTdHJpbmdFbnRyeQIJARF0cmFkZXJPcmRlcklkc0tleQIFBF9hbW0FB190cmFkZXIFDm9yZGVySWRzTmV3U3RyBQNuaWwBFnVwZGF0ZVRyYWRlck9yZGVyQ291bnQDBF9hbW0HX3RyYWRlcgZfY291bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJARN0cmFkZXJPcmRlckNvdW50S2V5AgUEX2FtbQUHX3RyYWRlcgUGX2NvdW50BQNuaWwBEXVwZGF0ZUxhc3RPcmRlcklkAQxfbGFzdE9yZGVySWQJAMwIAgkBDEludGVnZXJFbnRyeQIFDWtfbGFzdE9yZGVySWQFDF9sYXN0T3JkZXJJZAUDbmlsARBtYXJrRXhlY3V0ZU9yZGVyAQhfb3JkZXJJZAkAzAgCCQEMQm9vbGVhbkVudHJ5AgkBDnRvQ29tcG9zaXRlS2V5AgUQa19leGVjdXRlZE9yZGVycwkApAMBBQhfb3JkZXJJZAYFA25pbAEPbWFya0NhbmNlbE9yZGVyAQhfb3JkZXJJZAkAzAgCCQEMQm9vbGVhbkVudHJ5AgkBDnRvQ29tcG9zaXRlS2V5AgUQa19jYW5jZWxlZE9yZGVycwkApAMBBQhfb3JkZXJJZAYFA25pbAoBaQESY2xlYW5VcFN0YWxlT3JkZXJzAgRfYW1tB190cmFkZXIEBm9yZGVycwkBEnRyYWRlckFtbU9yZGVyc0lkcwIFBF9hbW0FB190cmFkZXIECm9yZGVyQ291bnQJARNnZXRUcmFkZXJPcmRlckNvdW50AgUEX2FtbQUHX3RyYWRlcgoBCmNsZWFuVXBPbmUCBF9hY2MIX29yZGVySWQECm9yZGVySWRJbnQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAtgkBBQhfb3JkZXJJZAIQSW52YWxpZCBvcmRlciBpZAQLJHQwODI4Nzg0ODIJAQhnZXRPcmRlcgEFCm9yZGVySWRJbnQEA194MQgFCyR0MDgyODc4NDgyAl8xBANfeDIIBQskdDA4Mjg3ODQ4MgJfMgQDX3gzCAULJHQwODI4Nzg0ODICXzMEA194NAgFCyR0MDgyODc4NDgyAl80BAVfdHlwZQgFCyR0MDgyODc4NDgyAl81BANfeDUIBQskdDA4Mjg3ODQ4MgJfNgQDX3g2CAULJHQwODI4Nzg0ODICXzcEA194NwgFCyR0MDgyODc4NDgyAl84BANfeDgIBQskdDA4Mjg3ODQ4MgJfOQQLX3Bvc2l0aW9uSWQIBQskdDA4Mjg3ODQ4MgNfMTAEA194OQgFCyR0MDgyODc4NDgyA18xMQQMcG9zaXRpb25TaXplCQEPZ2V0UG9zaXRpb25TaXplAgUEX2FtbQUHX3RyYWRlcgQRY3VycmVudFBvc2l0aW9uSWQDCQECIT0CBQxwb3NpdGlvblNpemUAAAkBDWdldFBvc2l0aW9uSWQCBQRfYW1tBQdfdHJhZGVyAAADAwMJAAACBQVfdHlwZQUEU1RPUAYJAAACBQVfdHlwZQUEVEFLRQkBAiE9AgURY3VycmVudFBvc2l0aW9uSWQFC19wb3NpdGlvbklkBwQGY2hhbmdlCQDOCAIJAQ9tYXJrQ2FuY2VsT3JkZXIBBQpvcmRlcklkSW50CQEQYWRkUmVtb3ZlT3JkZXJJZAQFCm9yZGVySWRJbnQFBF9hbW0FB190cmFkZXIHCQCUCgIJAGQCCAUEX2FjYwJfMQABCQDOCAIIBQRfYWNjAl8yBQZjaGFuZ2UFBF9hY2MEBnJlc3VsdAoAAiRsBQZvcmRlcnMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgIAAAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQpjbGVhblVwT25lAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA1CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQkAzggCCAUGcmVzdWx0Al8yCQEWdXBkYXRlVHJhZGVyT3JkZXJDb3VudAMFBF9hbW0FB190cmFkZXIJAGUCBQpvcmRlckNvdW50CAUGcmVzdWx0Al8xAWkBCnNldENvbnRleHQBB19zZW5kZXIDCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAg5Pbmx5IHNlbGYtY2FsbAkAzAgCCQELU3RyaW5nRW50cnkCBQhrX3NlbmRlcgUHX3NlbmRlcgUDbmlsAWkBDHJlc2V0Q29udGV4dAADCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAg5Pbmx5IHNlbGYtY2FsbAkAzAgCCQELRGVsZXRlRW50cnkBBQhrX3NlbmRlcgUDbmlsAWkBCmluaXRpYWxpemUBDF9jb29yZGluYXRvcgMDCQELaW5pdGlhbGl6ZWQABgkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIUVW5hYmxlIHRvIGluaXRpYWxpemUJAMwIAgkBC1N0cmluZ0VudHJ5AgUUa19jb29yZGluYXRvckFkZHJlc3MJAKUIAQkBEUBleHRyTmF0aXZlKDEwNjIpAQUMX2Nvb3JkaW5hdG9yCQDMCAIJAQxCb29sZWFuRW50cnkCBQ1rX2luaXRpYWxpemVkBgUDbmlsAWkBC2NyZWF0ZU9yZGVyCARfYW1tBV90eXBlDV90cmlnZ2VyUHJpY2ULX2xpbWl0UHJpY2UJX2Ftb3VudEluCV9sZXZlcmFnZQVfc2lkZQhfcmVmTGluawQHX3RyYWRlcgkApQgBCAUBaQZjYWxsZXIEB2NsZWFuVXAJAPwHBAUEdGhpcwISY2xlYW5VcFN0YWxlT3JkZXJzCQDMCAIFBF9hbW0JAMwIAgUHX3RyYWRlcgUDbmlsBQNuaWwDCQAAAgUHY2xlYW5VcAUHY2xlYW5VcAMJAGYCCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAjVJbnZhbGlkIGNyZWF0ZU9yZGVyIHBhcmFtZXRlcnM6IGludmFsaWQgcGF5bWVudCBjb3VudAQNJHQwMTAyNDcxMDQ5OQMJAAACCQCQAwEIBQFpCHBheW1lbnRzAAEJAJQKAgkA2AQBCQETdmFsdWVPckVycm9yTWVzc2FnZQIICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAIQSW52YWxpZCBhc3NldCBpZAgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQJAJQKAgIAAAAEDnBheW1lbnRBc3NldElkCAUNJHQwMTAyNDcxMDQ5OQJfMQQNcGF5bWVudEFtb3VudAgFDSR0MDEwMjQ3MTA0OTkCXzIEBmRvQ2FsbAkA/AcEBQR0aGlzAhNpbnRlcm5hbENyZWF0ZU9yZGVyCQDMCAIFB190cmFkZXIJAMwIAgUEX2FtbQkAzAgCBQVfdHlwZQkAzAgCBQ1fdHJpZ2dlclByaWNlCQDMCAIFC19saW1pdFByaWNlCQDMCAIFCV9hbW91bnRJbgkAzAgCBQlfbGV2ZXJhZ2UJAMwIAgUFX3NpZGUJAMwIAgUIX3JlZkxpbmsJAMwIAgUOcGF5bWVudEFzc2V0SWQJAMwIAgUNcGF5bWVudEFtb3VudAUDbmlsBQNuaWwDCQAAAgUGZG9DYWxsBQZkb0NhbGwFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARxpbmNyZWFzZVBvc2l0aW9uV2l0aFN0b3BMb3NzCQRfYW1tCl9kaXJlY3Rpb24JX2xldmVyYWdlE19taW5CYXNlQXNzZXRBbW91bnQIX3JlZkxpbmsRX3N0b3BUcmlnZ2VyUHJpY2UPX3N0b3BMaW1pdFByaWNlEV90YWtlVHJpZ2dlclByaWNlD190YWtlTGltaXRQcmljZQQHX3RyYWRlcgkApQgBCAUBaQZjYWxsZXIEB2NsZWFuVXAJAPwHBAUEdGhpcwISY2xlYW5VcFN0YWxlT3JkZXJzCQDMCAIFBF9hbW0JAMwIAgUHX3RyYWRlcgUDbmlsBQNuaWwDCQAAAgUHY2xlYW5VcAUHY2xlYW5VcAMDCQEBIQEJAQtpbml0aWFsaXplZAAGCQEBIQEJAQtpc1doaXRlbGlzdAEFBF9hbW0JAAIBAi9JbnZhbGlkIGluY3JlYXNlUG9zaXRpb25XaXRoU3RvcExvc3MgcGFyYW1ldGVycwQMcG9zaXRpb25TaXplCQEPZ2V0UG9zaXRpb25TaXplAgUEX2FtbQUHX3RyYWRlcgMJAQIhPQIFDHBvc2l0aW9uU2l6ZQAACQACAQJCSW52YWxpZCBpbmNyZWFzZVBvc2l0aW9uV2l0aFN0b3BMb3NzIHBhcmFtZXRlcnM6IG9ubHkgbmV3IHBvc2l0aW9uBAxkb1NldENvbnRleHQJAPwHBAUEdGhpcwIKc2V0Q29udGV4dAkAzAgCBQdfdHJhZGVyBQNuaWwFA25pbAMJAAACBQxkb1NldENvbnRleHQFDGRvU2V0Q29udGV4dAQPZG9DbG9zZVBvc2l0aW9uCQD8BwQJARFAZXh0ck5hdGl2ZSgxMDYyKQEFBF9hbW0CEGluY3JlYXNlUG9zaXRpb24JAMwIAgUKX2RpcmVjdGlvbgkAzAgCBQlfbGV2ZXJhZ2UJAMwIAgUTX21pbkJhc2VBc3NldEFtb3VudAkAzAgCBQhfcmVmTGluawUDbmlsCAUBaQhwYXltZW50cwMJAAACBQ9kb0Nsb3NlUG9zaXRpb24FD2RvQ2xvc2VQb3NpdGlvbgQOZG9SZXNldENvbnRleHQJAPwHBAUEdGhpcwIMcmVzZXRDb250ZXh0BQNuaWwFA25pbAMJAAACBQ5kb1Jlc2V0Q29udGV4dAUOZG9SZXNldENvbnRleHQEEm9wZW5lZFBvc2l0aW9uU2l6ZQkBD2dldFBvc2l0aW9uU2l6ZQIFBF9hbW0FB190cmFkZXIDCQAAAgUSb3BlbmVkUG9zaXRpb25TaXplBRJvcGVuZWRQb3NpdGlvblNpemUECGFtb3VudEluCQEDYWJzAQUSb3BlbmVkUG9zaXRpb25TaXplBAxzdG9wTG9zc1NpZGUDCQBmAgAABRJvcGVuZWRQb3NpdGlvblNpemUFBExPTkcFBVNIT1JUBBFkb0NyZWF0ZVN0b3BPcmRlcgMJAGYCBRFfc3RvcFRyaWdnZXJQcmljZQAABBFkb0NyZWF0ZVN0b3BPcmRlcgkA/AcEBQR0aGlzAhNpbnRlcm5hbENyZWF0ZU9yZGVyCQDMCAIFB190cmFkZXIJAMwIAgUEX2FtbQkAzAgCBQRTVE9QCQDMCAIFEV9zdG9wVHJpZ2dlclByaWNlCQDMCAIFD19zdG9wTGltaXRQcmljZQkAzAgCBQhhbW91bnRJbgkAzAgCAAAJAMwIAgUMc3RvcExvc3NTaWRlCQDMCAIFCF9yZWZMaW5rCQDMCAICAAkAzAgCAAAFA25pbAUDbmlsAwkAAAIFEWRvQ3JlYXRlU3RvcE9yZGVyBRFkb0NyZWF0ZVN0b3BPcmRlcgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBQNuaWwDCQAAAgURZG9DcmVhdGVTdG9wT3JkZXIFEWRvQ3JlYXRlU3RvcE9yZGVyBBFkb0NyZWF0ZVRha2VPcmRlcgMJAGYCBRFfdGFrZVRyaWdnZXJQcmljZQAABBFkb0NyZWF0ZVRha2VPcmRlcgkA/AcEBQR0aGlzAhNpbnRlcm5hbENyZWF0ZU9yZGVyCQDMCAIFB190cmFkZXIJAMwIAgUEX2FtbQkAzAgCBQRUQUtFCQDMCAIFEV90YWtlVHJpZ2dlclByaWNlCQDMCAIFD190YWtlTGltaXRQcmljZQkAzAgCBQhhbW91bnRJbgkAzAgCAAAJAMwIAgUMc3RvcExvc3NTaWRlCQDMCAIFCF9yZWZMaW5rCQDMCAICAAkAzAgCAAAFA25pbAUDbmlsAwkAAAIFEWRvQ3JlYXRlVGFrZU9yZGVyBRFkb0NyZWF0ZVRha2VPcmRlcgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBQNuaWwDCQAAAgURZG9DcmVhdGVUYWtlT3JkZXIFEWRvQ3JlYXRlVGFrZU9yZGVyBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQETaW50ZXJuYWxDcmVhdGVPcmRlcgsHX3RyYWRlcgRfYW1tBV90eXBlDV90cmlnZ2VyUHJpY2ULX2xpbWl0UHJpY2UJX2Ftb3VudEluCV9sZXZlcmFnZQVfc2lkZQhfcmVmTGluaw9fcGF5bWVudEFzc2V0SWQOX3BheW1lbnRBbW91bnQDAwMDAwMDAwMJAQEhAQkBC2luaXRpYWxpemVkAAYJAQEhAQkBC2lzV2hpdGVsaXN0AQUEX2FtbQYJAGcCAAAFDV90cmlnZ2VyUHJpY2UGCQBmAgAABQtfbGltaXRQcmljZQYJAGcCAAAFCV9hbW91bnRJbgYJAGYCAAAFCV9sZXZlcmFnZQYJAQEhAQMJAAACBQVfc2lkZQUETE9ORwYJAAACBQVfc2lkZQUFU0hPUlQGCQEBIQEDCQAAAgUFX3R5cGUFBFNUT1AGCQAAAgUFX3R5cGUFBFRBS0UGCQEBIQEJAAACCAUBaQZjYWxsZXIFBHRoaXMJAAIBAh5JbnZhbGlkIGNyZWF0ZU9yZGVyIHBhcmFtZXRlcnMEB29yZGVySWQJAGQCCQEOY3VycmVudE9yZGVySWQAAAEEE25ld1RyYWRlck9yZGVyQ291bnQJAGQCCQETZ2V0VHJhZGVyT3JkZXJDb3VudAIFBF9hbW0FB190cmFkZXIAAQQMcG9zaXRpb25TaXplCQEPZ2V0UG9zaXRpb25TaXplAgUEX2FtbQUHX3RyYWRlcgQKX2RpcmVjdGlvbgMDAwkAAAIFDHBvc2l0aW9uU2l6ZQAABgMJAGYCBQxwb3NpdGlvblNpemUAAAkAAAIFBV9zaWRlBQRMT05HBwYDCQBmAgAABQxwb3NpdGlvblNpemUJAAACBQVfc2lkZQUFU0hPUlQHBQhJTkNSRUFTRQUIREVDUkVBU0UDAwkAAAIFDHBvc2l0aW9uU2l6ZQAAAwkAAAIFBV90eXBlBQRTVE9QBgkAAAIFBV90eXBlBQRUQUtFBwkAAgECK0NhbiBub3QgY3JlYXRlIFNUT1AvVEFLRSBvcmRlcjogbm8gcG9zaXRpb24EC3VzZG5QYXltZW50AwkAAAIFCl9kaXJlY3Rpb24FCElOQ1JFQVNFAwMJAQIhPQIFD19wYXltZW50QXNzZXRJZAkA2AQBCQEKcXVvdGVBc3NldAAGCQECIT0CBQ5fcGF5bWVudEFtb3VudAUJX2Ftb3VudEluCQACAQI0SW52YWxpZCBjcmVhdGVMaW1pdE9yZGVyIHBhcmFtZXRlcnM6IGludmFsaWQgcGF5bWVudAQFc3Rha2UJAPwHBAkBDm1hbmFnZXJBZGRyZXNzAAIHZGVwb3NpdAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCCQEKcXVvdGVBc3NldAAFDl9wYXltZW50QW1vdW50BQNuaWwDCQAAAgUFc3Rha2UFBXN0YWtlBQ5fcGF5bWVudEFtb3VudAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAwkAAAIFC3VzZG5QYXltZW50BQt1c2RuUGF5bWVudAQKcG9zaXRpb25JZAMJAQIhPQIFDHBvc2l0aW9uU2l6ZQAACQENZ2V0UG9zaXRpb25JZAIFBF9hbW0FB190cmFkZXIAAAMJAGYCBRNuZXdUcmFkZXJPcmRlckNvdW50BRlNQVhfVFJBREVSX09SREVSU19QRVJfQU1NCQACAQIwSW52YWxpZCBjcmVhdGVMaW1pdE9yZGVyIHBhcmFtZXRlcnM6IG9yZGVyIGNvdW50CQDOCAIJAM4IAgkAzggCCQEJc2F2ZU9yZGVyDAUHb3JkZXJJZAUEX2FtbQUHX3RyYWRlcgUJX2Ftb3VudEluBQlfbGV2ZXJhZ2UFBV90eXBlBQ1fdHJpZ2dlclByaWNlBQt1c2RuUGF5bWVudAUFX3NpZGUFCF9yZWZMaW5rBQpwb3NpdGlvbklkBQtfbGltaXRQcmljZQkBEGFkZFJlbW92ZU9yZGVySWQEBQdvcmRlcklkBQRfYW1tBQdfdHJhZGVyBgkBFnVwZGF0ZVRyYWRlck9yZGVyQ291bnQDBQRfYW1tBQdfdHJhZGVyBRNuZXdUcmFkZXJPcmRlckNvdW50CQERdXBkYXRlTGFzdE9yZGVySWQBBQdvcmRlcklkCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBC2NhbmNlbE9yZGVyAQhfb3JkZXJJZAQNJHQwMTU4NTAxNjA2OQkBCGdldE9yZGVyAQUIX29yZGVySWQEBF9hbW0IBQ0kdDAxNTg1MDE2MDY5Al8xBAdfdHJhZGVyCAUNJHQwMTU4NTAxNjA2OQJfMgQJX2Ftb3VudEluCAUNJHQwMTU4NTAxNjA2OQJfMwQJX2xldmVyYWdlCAUNJHQwMTU4NTAxNjA2OQJfNAQFX3R5cGUIBQ0kdDAxNTg1MDE2MDY5Al81BA1fdHJpZ2dlclByaWNlCAUNJHQwMTU4NTAxNjA2OQJfNgQLX2Ftb3VudFVzZG4IBQ0kdDAxNTg1MDE2MDY5Al83BAVfc2lkZQgFDSR0MDE1ODUwMTYwNjkCXzgECF9yZWZMaW5rCAUNJHQwMTU4NTAxNjA2OQJfOQQLX3Bvc2l0aW9uSWQIBQ0kdDAxNTg1MDE2MDY5A18xMAQLX2xpbWl0UHJpY2UIBQ0kdDAxNTg1MDE2MDY5A18xMQMDAwkBASEBCQELaW5pdGlhbGl6ZWQABgkBASEBCQEHaXNWYWxpZAEFCF9vcmRlcklkBgkBASEBCQAAAgkApQgBCAUBaQZjYWxsZXIFB190cmFkZXIJAAIBAh5JbnZhbGlkIGNhbmNlbE9yZGVyIHBhcmFtZXRlcnMEB2NsZWFuVXAJAPwHBAUEdGhpcwISY2xlYW5VcFN0YWxlT3JkZXJzCQDMCAIFBF9hbW0JAMwIAgUHX3RyYWRlcgUDbmlsBQNuaWwDCQAAAgUHY2xlYW5VcAUHY2xlYW5VcAQTbmV3VHJhZGVyT3JkZXJDb3VudAkAZQIJARNnZXRUcmFkZXJPcmRlckNvdW50AgUEX2FtbQUHX3RyYWRlcgABBAh3aXRoZHJhdwMJAGYCBQtfYW1vdW50VXNkbgAABAd1bnN0YWtlCQD8BwQJAQ5tYW5hZ2VyQWRkcmVzcwACCHdpdGhkcmF3CQDMCAIJANgEAQkBCnF1b3RlQXNzZXQACQDMCAIFC19hbW91bnRVc2RuBQNuaWwFA25pbAMJAAACBQd1bnN0YWtlBQd1bnN0YWtlBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FA25pbAMJAAACBQh3aXRoZHJhdwUId2l0aGRyYXcJAM4IAgkAzggCCQDOCAIJAQ9tYXJrQ2FuY2VsT3JkZXIBBQhfb3JkZXJJZAkBEGFkZFJlbW92ZU9yZGVySWQEBQhfb3JkZXJJZAUEX2FtbQUHX3RyYWRlcgcJARZ1cGRhdGVUcmFkZXJPcmRlckNvdW50AwUEX2FtbQUHX3RyYWRlcgUTbmV3VHJhZGVyT3JkZXJDb3VudAMJAGYCBQtfYW1vdW50VXNkbgAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgULX2Ftb3VudFVzZG4JAQpxdW90ZUFzc2V0AAUDbmlsBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEMZXhlY3V0ZU9yZGVyAQhfb3JkZXJJZAQNJHQwMTcwNDAxNzI1OQkBCGdldE9yZGVyAQUIX29yZGVySWQEBF9hbW0IBQ0kdDAxNzA0MDE3MjU5Al8xBAdfdHJhZGVyCAUNJHQwMTcwNDAxNzI1OQJfMgQJX2Ftb3VudEluCAUNJHQwMTcwNDAxNzI1OQJfMwQJX2xldmVyYWdlCAUNJHQwMTcwNDAxNzI1OQJfNAQFX3R5cGUIBQ0kdDAxNzA0MDE3MjU5Al81BA1fdHJpZ2dlclByaWNlCAUNJHQwMTcwNDAxNzI1OQJfNgQLX2Ftb3VudFVzZG4IBQ0kdDAxNzA0MDE3MjU5Al83BAVfc2lkZQgFDSR0MDE3MDQwMTcyNTkCXzgECF9yZWZMaW5rCAUNJHQwMTcwNDAxNzI1OQJfOQQLX3Bvc2l0aW9uSWQIBQ0kdDAxNzA0MDE3MjU5A18xMAQLX2xpbWl0UHJpY2UIBQ0kdDAxNzA0MDE3MjU5A18xMQQHY2xlYW5VcAkA/AcEBQR0aGlzAhJjbGVhblVwU3RhbGVPcmRlcnMJAMwIAgUEX2FtbQkAzAgCBQdfdHJhZGVyBQNuaWwFA25pbAMJAAACBQdjbGVhblVwBQdjbGVhblVwAwMJAQEhAQkBC2luaXRpYWxpemVkAAYJAQEhAQkBB2lzVmFsaWQBBQhfb3JkZXJJZAkAAgECH0ludmFsaWQgZXhlY3V0ZU9yZGVyIHBhcmFtZXRlcnMEDHBvc2l0aW9uU2l6ZQkBD2dldFBvc2l0aW9uU2l6ZQIFBF9hbW0FB190cmFkZXIEEWN1cnJlbnRQb3NpdGlvbklkAwkBAiE9AgUMcG9zaXRpb25TaXplAAAJAQ1nZXRQb3NpdGlvbklkAgUEX2FtbQUHX3RyYWRlcgAABA0kdDAxNzY2MzIxNTA1AwkAAAIFBV90eXBlBQRTVE9QBBJfcG9zaXRpb25EaXJlY3Rpb24DCQBmAgUMcG9zaXRpb25TaXplAAAFBExPTkcDCQBmAgAABQxwb3NpdGlvblNpemUFBVNIT1JUCQACAQIsQ2FuIG5vdCBleGVjdXRlIFNUT1Agb3JkZXI6IG5vIG9wZW4gcG9zaXRpb24EC21hcmtldFByaWNlCQEOZ2V0TWFya2V0UHJpY2UBBQRfYW1tBAxpc0V4ZWN1dGFibGUDCQAAAgUFX3NpZGUFEl9wb3NpdGlvbkRpcmVjdGlvbgkAAgECJ0NhbiBub3QgZXhlY3V0ZSBTVE9QIG9yZGVyOiByZWR1Y2Ugb25seQMJAQIhPQIFEWN1cnJlbnRQb3NpdGlvbklkBQtfcG9zaXRpb25JZAkAAgECK0NhbiBub3QgZXhlY3V0ZSBTVE9QIG9yZGVyOiBwb3NpdGlvbiBjbG9zZWQDCQAAAgUSX3Bvc2l0aW9uRGlyZWN0aW9uBQRMT05HCQBnAgUNX3RyaWdnZXJQcmljZQULbWFya2V0UHJpY2UJAGcCBQttYXJrZXRQcmljZQUNX3RyaWdnZXJQcmljZQMFDGlzRXhlY3V0YWJsZQkAlQoDAg1jbG9zZVBvc2l0aW9uCQDMCAIJAQRtaW52AgUJX2Ftb3VudEluCQEDYWJzAQUMcG9zaXRpb25TaXplCQDMCAIJAQRtdWxkAgULX2xpbWl0UHJpY2UJAQNhYnMBBQxwb3NpdGlvblNpemUJAMwIAgcFA25pbAUDbmlsCQACAQIxQ2FuIG5vdCBleGVjdXRlIFNUT1Agb3JkZXI6IHRyaWdnZXJQcmljZSBtaXNtYXRjaAMJAAACBQVfdHlwZQUEVEFLRQQSX3Bvc2l0aW9uRGlyZWN0aW9uAwkAZgIFDHBvc2l0aW9uU2l6ZQAABQRMT05HAwkAZgIAAAUMcG9zaXRpb25TaXplBQVTSE9SVAkAAgECLENhbiBub3QgZXhlY3V0ZSBTVE9QIG9yZGVyOiBubyBvcGVuIHBvc2l0aW9uBAttYXJrZXRQcmljZQkBDmdldE1hcmtldFByaWNlAQUEX2FtbQQMaXNFeGVjdXRhYmxlAwkAAAIFBV9zaWRlBRJfcG9zaXRpb25EaXJlY3Rpb24JAAIBAidDYW4gbm90IGV4ZWN1dGUgVEFLRSBvcmRlcjogcmVkdWNlIG9ubHkDCQECIT0CBRFjdXJyZW50UG9zaXRpb25JZAULX3Bvc2l0aW9uSWQJAAIBCQCsAgIJAKwCAgkArAICAixDYW4gbm90IGV4ZWN1dGUgVEFLRSBvcmRlcjogcG9zaXRpb24gY2xvc2VkIAkApAMBBRFjdXJyZW50UG9zaXRpb25JZAICIT0JAKQDAQULX3Bvc2l0aW9uSWQDCQAAAgUSX3Bvc2l0aW9uRGlyZWN0aW9uBQRMT05HCQBnAgULbWFya2V0UHJpY2UFDV90cmlnZ2VyUHJpY2UJAGcCBQ1fdHJpZ2dlclByaWNlBQttYXJrZXRQcmljZQMFDGlzRXhlY3V0YWJsZQkAlQoDAg1jbG9zZVBvc2l0aW9uCQDMCAIJAQRtaW52AgUJX2Ftb3VudEluCQEDYWJzAQUMcG9zaXRpb25TaXplCQDMCAIJAQRtdWxkAgULX2xpbWl0UHJpY2UJAQNhYnMBBQxwb3NpdGlvblNpemUJAMwIAgcFA25pbAUDbmlsCQACAQIxQ2FuIG5vdCBleGVjdXRlIFRBS0Ugb3JkZXI6IHRyaWdnZXJQcmljZSBtaXNtYXRjaAMJAAACBQVfdHlwZQUFTElNSVQEC21hcmtldFByaWNlCQEOZ2V0TWFya2V0UHJpY2UBBQRfYW1tBAZzcHJlYWQDCQAAAgULX2xpbWl0UHJpY2UAAAkBCWdldFNwcmVhZAEFDV90cmlnZ2VyUHJpY2UJAQNhYnMBCQBlAgUNX3RyaWdnZXJQcmljZQULX2xpbWl0UHJpY2UEDGlzRXhlY3V0YWJsZQMJAGcCBQttYXJrZXRQcmljZQkAZQIFDV90cmlnZ2VyUHJpY2UFBnNwcmVhZAkAZwIJAGQCBQ1fdHJpZ2dlclByaWNlBQZzcHJlYWQFC21hcmtldFByaWNlBwMFDGlzRXhlY3V0YWJsZQQSX3Bvc2l0aW9uRGlyZWN0aW9uAwkAZgIFDHBvc2l0aW9uU2l6ZQAABQRMT05HAwkAZgIAAAUMcG9zaXRpb25TaXplBQVTSE9SVAD///////////8BBAlkaXJlY3Rpb24DCQAAAgUMcG9zaXRpb25TaXplAAAFCElOQ1JFQVNFAwkAAAIFEl9wb3NpdGlvbkRpcmVjdGlvbgUFX3NpZGUFCElOQ1JFQVNFBQhERUNSRUFTRQMJAAACBQlkaXJlY3Rpb24FCElOQ1JFQVNFBA9hbW91bnRJbldpdGhGZWUJAGUCBQtfYW1vdW50VXNkbgkBBG11bGQCBQtfYW1vdW50VXNkbgkBBmdldEZlZQIFBF9hbW0FB190cmFkZXIJAJUKAwIQaW5jcmVhc2VQb3NpdGlvbgkAzAgCBQVfc2lkZQkAzAgCBQlfbGV2ZXJhZ2UJAMwIAgMJAAACBQtfbGltaXRQcmljZQAAAAAJAQRkaXZkAgUPYW1vdW50SW5XaXRoRmVlBQtfbGltaXRQcmljZQkAzAgCBQhfcmVmTGluawUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCCQEKcXVvdGVBc3NldAAFC19hbW91bnRVc2RuBQNuaWwJAJUKAwINY2xvc2VQb3NpdGlvbgkAzAgCBQlfYW1vdW50SW4JAMwIAgkBBG11bGQCBQlfYW1vdW50SW4FC19saW1pdFByaWNlCQDMCAIHBQNuaWwFA25pbAkAAgECMkNhbiBub3QgZXhlY3V0ZSBMSU1JVCBvcmRlcjogdHJpZ2dlclByaWNlIG1pc21hdGNoCQACAQkArAICAhRJbnZhbGlkIG9yZGVyIHR5cGU6IAkApAMBBQVfdHlwZQQGbWV0aG9kCAUNJHQwMTc2NjMyMTUwNQJfMQQEYXJncwgFDSR0MDE3NjYzMjE1MDUCXzIECHBheW1lbnRzCAUNJHQwMTc2NjMyMTUwNQJfMwQId2l0aGRyYXcDCQAAAgkAkAMBBQhwYXltZW50cwABBAd1bnN0YWtlCQD8BwQJAQ5tYW5hZ2VyQWRkcmVzcwACCHdpdGhkcmF3CQDMCAIJANgEAQkBCnF1b3RlQXNzZXQACQDMCAIICQCRAwIFCHBheW1lbnRzAAAGYW1vdW50BQNuaWwFA25pbAMJAAACBQd1bnN0YWtlBQd1bnN0YWtlBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FA25pbAMJAAACBQh3aXRoZHJhdwUId2l0aGRyYXcEDGRvU2V0Q29udGV4dAkA/AcEBQR0aGlzAgpzZXRDb250ZXh0CQDMCAIFB190cmFkZXIFA25pbAUDbmlsAwkAAAIFDGRvU2V0Q29udGV4dAUMZG9TZXRDb250ZXh0BA9kb0Nsb3NlUG9zaXRpb24JAPwHBAkBEUBleHRyTmF0aXZlKDEwNjIpAQUEX2FtbQUGbWV0aG9kBQRhcmdzBQhwYXltZW50cwMJAAACBQ9kb0Nsb3NlUG9zaXRpb24FD2RvQ2xvc2VQb3NpdGlvbgQOZG9SZXNldENvbnRleHQJAPwHBAUEdGhpcwIMcmVzZXRDb250ZXh0BQNuaWwFA25pbAMJAAACBQ5kb1Jlc2V0Q29udGV4dAUOZG9SZXNldENvbnRleHQEE25ld1RyYWRlck9yZGVyQ291bnQJAGUCCQETZ2V0VHJhZGVyT3JkZXJDb3VudAIFBF9hbW0FB190cmFkZXIAAQkAzggCCQDOCAIJARZ1cGRhdGVUcmFkZXJPcmRlckNvdW50AwUEX2FtbQUHX3RyYWRlcgUTbmV3VHJhZGVyT3JkZXJDb3VudAkBEGFkZFJlbW92ZU9yZGVySWQEBQhfb3JkZXJJZAUEX2FtbQUHX3RyYWRlcgcJARBtYXJrRXhlY3V0ZU9yZGVyAQUIX29yZGVySWQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEUdmlld19jYW5FeGVjdXRlT3JkZXIBCF9vcmRlcklkBAFzCQD8BwQFBHRoaXMCDGV4ZWN1dGVPcmRlcgkAzAgCBQhfb3JkZXJJZAUDbmlsBQNuaWwDCQAAAgUBcwUBcwkAAgECB1N1Y2Nlc3MJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAnR4AQZ2ZXJpZnkABA5jb29yZGluYXRvclN0cgkAnQgCBQR0aGlzBRRrX2Nvb3JkaW5hdG9yQWRkcmVzcwMJAQlpc0RlZmluZWQBBQ5jb29yZGluYXRvclN0cgQFYWRtaW4JAJ0IAgkBEUBleHRyTmF0aXZlKDEwNjIpAQkBBXZhbHVlAQUOY29vcmRpbmF0b3JTdHIFD2tfYWRtaW5fYWRkcmVzcwMJAQlpc0RlZmluZWQBBQVhZG1pbgkBC3ZhbHVlT3JFbHNlAgkAmwgCCQERQGV4dHJOYXRpdmUoMTA2MikBCQEFdmFsdWUBBQVhZG1pbgkArAICCQCsAgIJAKwCAgIHc3RhdHVzXwkApQgBBQR0aGlzAgFfCQDYBAEIBQJ0eAJpZAcJAAIBAi51bmFibGUgdG8gdmVyaWZ5OiBhZG1pbiBub3Qgc2V0IGluIGNvb3JkaW5hdG9yCQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwAACAUCdHgPc2VuZGVyUHVibGljS2V5UVgb+g==", "height": 2434846, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: JAco3pQugD5qhd1Mc8q5S4gFRzpcvjbSBKy3PhxfXvcR Next: 38uueL58LQ3CAXPXJbX7wEcHzX2EZgUbgo41CgqVgUYN Diff:
OldNewDifferences
33 {-# CONTENT_TYPE DAPP #-}
44 let k_coordinatorAddress = "k_coordinatorAddress"
55
6-let k_admin_public_key = "k_admin_public_key"
6+let k_admin_address = "k_admin_address"
77
88 let k_quote_asset = "k_quote_asset"
99
9999
100100
101101 func isWhitelist (_address) = valueOrElse(getBoolean(coordinator(), toCompositeKey(k_amm, _address)), false)
102-
103-
104-func adminPublicKey () = fromBase58String(getStringValue(coordinator(), k_admin_public_key))
105102
106103
107104 func initialized () = valueOrElse(getBoolean(this, k_initialized), false)
233230 let orderCount = getTraderOrderCount(_amm, _trader)
234231 func cleanUpOne (_acc,_orderId) = {
235232 let orderIdInt = valueOrErrorMessage(parseInt(_orderId), "Invalid order id")
236- let $t083838578 = getOrder(orderIdInt)
237- let _x1 = $t083838578._1
238- let _x2 = $t083838578._2
239- let _x3 = $t083838578._3
240- let _x4 = $t083838578._4
241- let _type = $t083838578._5
242- let _x5 = $t083838578._6
243- let _x6 = $t083838578._7
244- let _x7 = $t083838578._8
245- let _x8 = $t083838578._9
246- let _positionId = $t083838578._10
247- let _x9 = $t083838578._11
233+ let $t082878482 = getOrder(orderIdInt)
234+ let _x1 = $t082878482._1
235+ let _x2 = $t082878482._2
236+ let _x3 = $t082878482._3
237+ let _x4 = $t082878482._4
238+ let _type = $t082878482._5
239+ let _x5 = $t082878482._6
240+ let _x6 = $t082878482._7
241+ let _x7 = $t082878482._8
242+ let _x8 = $t082878482._9
243+ let _positionId = $t082878482._10
244+ let _x9 = $t082878482._11
248245 let positionSize = getPositionSize(_amm, _trader)
249246 let currentPositionId = if ((positionSize != 0))
250247 then getPositionId(_amm, _trader)
295292
296293
297294 @Callable(i)
298-func initialize (_coordinator) = if (initialized())
299- then throw("Already initialized")
300- else [StringEntry(k_coordinatorAddress, _coordinator), BooleanEntry(k_initialized, true)]
295+func initialize (_coordinator) = if (if (initialized())
296+ then true
297+ else (i.caller != this))
298+ then throw("Unable to initialize")
299+ else [StringEntry(k_coordinatorAddress, toString(addressFromStringValue(_coordinator))), BooleanEntry(k_initialized, true)]
301300
302301
303302
309308 then if ((size(i.payments) > 1))
310309 then throw("Invalid createOrder parameters: invalid payment count")
311310 else {
312- let $t01028710539 = if ((size(i.payments) == 1))
311+ let $t01024710499 = if ((size(i.payments) == 1))
313312 then $Tuple2(toBase58String(valueOrErrorMessage(i.payments[0].assetId, "Invalid asset id")), i.payments[0].amount)
314313 else $Tuple2("", 0)
315- let paymentAssetId = $t01028710539._1
316- let paymentAmount = $t01028710539._2
314+ let paymentAssetId = $t01024710499._1
315+ let paymentAmount = $t01024710499._2
317316 let doCall = invoke(this, "internalCreateOrder", [_trader, _amm, _type, _triggerPrice, _limitPrice, _amountIn, _leverage, _side, _refLink, paymentAssetId, paymentAmount], nil)
318317 if ((doCall == doCall))
319318 then nil
409408 then true
410409 else (_side == SHORT)))
411410 then true
412- else !(if (if ((_type == STOP))
411+ else !(if ((_type == STOP))
413412 then true
414- else (_type == TAKE))
415- then true
416- else (_type == LIMIT)))
413+ else (_type == TAKE)))
417414 then true
418415 else !((i.caller == this)))
419416 then throw("Invalid createOrder parameters")
468465
469466 @Callable(i)
470467 func cancelOrder (_orderId) = {
471- let $t01590816127 = getOrder(_orderId)
472- let _amm = $t01590816127._1
473- let _trader = $t01590816127._2
474- let _amountIn = $t01590816127._3
475- let _leverage = $t01590816127._4
476- let _type = $t01590816127._5
477- let _triggerPrice = $t01590816127._6
478- let _amountUsdn = $t01590816127._7
479- let _side = $t01590816127._8
480- let _refLink = $t01590816127._9
481- let _positionId = $t01590816127._10
482- let _limitPrice = $t01590816127._11
468+ let $t01585016069 = getOrder(_orderId)
469+ let _amm = $t01585016069._1
470+ let _trader = $t01585016069._2
471+ let _amountIn = $t01585016069._3
472+ let _leverage = $t01585016069._4
473+ let _type = $t01585016069._5
474+ let _triggerPrice = $t01585016069._6
475+ let _amountUsdn = $t01585016069._7
476+ let _side = $t01585016069._8
477+ let _refLink = $t01585016069._9
478+ let _positionId = $t01585016069._10
479+ let _limitPrice = $t01585016069._11
483480 if (if (if (!(initialized()))
484481 then true
485482 else !(isValid(_orderId)))
513510
514511 @Callable(i)
515512 func executeOrder (_orderId) = {
516- let $t01709817317 = getOrder(_orderId)
517- let _amm = $t01709817317._1
518- let _trader = $t01709817317._2
519- let _amountIn = $t01709817317._3
520- let _leverage = $t01709817317._4
521- let _type = $t01709817317._5
522- let _triggerPrice = $t01709817317._6
523- let _amountUsdn = $t01709817317._7
524- let _side = $t01709817317._8
525- let _refLink = $t01709817317._9
526- let _positionId = $t01709817317._10
527- let _limitPrice = $t01709817317._11
513+ let $t01704017259 = getOrder(_orderId)
514+ let _amm = $t01704017259._1
515+ let _trader = $t01704017259._2
516+ let _amountIn = $t01704017259._3
517+ let _leverage = $t01704017259._4
518+ let _type = $t01704017259._5
519+ let _triggerPrice = $t01704017259._6
520+ let _amountUsdn = $t01704017259._7
521+ let _side = $t01704017259._8
522+ let _refLink = $t01704017259._9
523+ let _positionId = $t01704017259._10
524+ let _limitPrice = $t01704017259._11
528525 let cleanUp = invoke(this, "cleanUpStaleOrders", [_amm, _trader], nil)
529526 if ((cleanUp == cleanUp))
530527 then if (if (!(initialized()))
536533 let currentPositionId = if ((positionSize != 0))
537534 then getPositionId(_amm, _trader)
538535 else 0
539- let $t01772121563 = if ((_type == STOP))
536+ let $t01766321505 = if ((_type == STOP))
540537 then {
541538 let _positionDirection = if ((positionSize > 0))
542539 then LONG
607604 else throw("Can not execute LIMIT order: triggerPrice mismatch")
608605 }
609606 else throw(("Invalid order type: " + toString(_type)))
610- let method = $t01772121563._1
611- let args = $t01772121563._2
612- let payments = $t01772121563._3
607+ let method = $t01766321505._1
608+ let args = $t01766321505._2
609+ let payments = $t01766321505._3
613610 let withdraw = if ((size(payments) == 1))
614611 then {
615612 let unstake = invoke(managerAddress(), "withdraw", [toBase58String(quoteAsset()), payments[0].amount], nil)
655652
656653
657654 @Verifier(tx)
658-func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], adminPublicKey())
655+func verify () = {
656+ let coordinatorStr = getString(this, k_coordinatorAddress)
657+ if (isDefined(coordinatorStr))
658+ then {
659+ let admin = getString(addressFromStringValue(value(coordinatorStr)), k_admin_address)
660+ if (isDefined(admin))
661+ then valueOrElse(getBoolean(addressFromStringValue(value(admin)), ((("status_" + toString(this)) + "_") + toBase58String(tx.id))), false)
662+ else throw("unable to verify: admin not set in coordinator")
663+ }
664+ else sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
665+ }
659666
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let k_coordinatorAddress = "k_coordinatorAddress"
55
6-let k_admin_public_key = "k_admin_public_key"
6+let k_admin_address = "k_admin_address"
77
88 let k_quote_asset = "k_quote_asset"
99
1010 let k_amm = "k_amm"
1111
1212 let k_manager_address = "k_manager_address"
1313
1414 let k_positionSequence = "k_positionSequence"
1515
1616 let k_positionSize = "k_positionSize"
1717
1818 let k_fee = "k_fee"
1919
2020 let k_executedOrders = "k_executedOrders"
2121
2222 let k_canceledOrders = "k_canceledOrders"
2323
2424 let k_order = "k_order"
2525
2626 let k_lastOrderId = "k_lastOrderId"
2727
2828 let k_traderOrderCnt = "k_traderOrderCnt"
2929
3030 let k_traderOrderIds = "k_traderOrderIds"
3131
3232 let k_sender = "k_sender"
3333
3434 let k_initialized = "k_initialized"
3535
3636 let STOP = 1
3737
3838 let TAKE = 2
3939
4040 let LIMIT = 3
4141
4242 let LONG = 1
4343
4444 let SHORT = 2
4545
4646 let INCREASE = 1
4747
4848 let DECREASE = 2
4949
5050 let MAX_TRADER_ORDERS_PER_AMM = 5
5151
5252 let TIME = lastBlock.timestamp
5353
5454 let DECIMAL_UNIT = (1 * (((((10 * 10) * 10) * 10) * 10) * 10))
5555
5656 let SPREAD_LIMIT = (DECIMAL_UNIT / 200)
5757
5858 func abs (_x) = if ((_x > 0))
5959 then _x
6060 else -(_x)
6161
6262
6363 func divd (_x,_y) = fraction(_x, DECIMAL_UNIT, _y, HALFEVEN)
6464
6565
6666 func muld (_x,_y) = fraction(_x, _y, DECIMAL_UNIT, HALFEVEN)
6767
6868
6969 func minv (_x,_y) = if ((_x > _y))
7070 then _y
7171 else _x
7272
7373
7474 func toCompositeKey (_key,_address) = ((_key + "_") + _address)
7575
7676
7777 func executedOrderKey (_orderId) = ((k_executedOrders + "_") + toString(_orderId))
7878
7979
8080 func canceledOrderKey (_orderId) = ((k_canceledOrders + "_") + toString(_orderId))
8181
8282
8383 func orderKey (_orderId) = toCompositeKey(k_order, toString(_orderId))
8484
8585
8686 func traderOrderCountKey (_amm,_trader) = ((((k_traderOrderCnt + "_") + _amm) + "_") + _trader)
8787
8888
8989 func traderOrderIdsKey (_amm,_trader) = ((((k_traderOrderIds + "_") + _amm) + "_") + _trader)
9090
9191
9292 func coordinator () = valueOrErrorMessage(addressFromString(getStringValue(this, k_coordinatorAddress)), "Coordinator not set")
9393
9494
9595 func quoteAsset () = fromBase58String(getStringValue(coordinator(), k_quote_asset))
9696
9797
9898 func managerAddress () = valueOrErrorMessage(addressFromString(getStringValue(coordinator(), k_manager_address)), "Manager not set")
9999
100100
101101 func isWhitelist (_address) = valueOrElse(getBoolean(coordinator(), toCompositeKey(k_amm, _address)), false)
102-
103-
104-func adminPublicKey () = fromBase58String(getStringValue(coordinator(), k_admin_public_key))
105102
106103
107104 func initialized () = valueOrElse(getBoolean(this, k_initialized), false)
108105
109106
110107 func isValid (_orderId) = if (valueOrElse(getBoolean(this, executedOrderKey(_orderId)), false))
111108 then throw(("Order already executed: " + toString(_orderId)))
112109 else if (valueOrElse(getBoolean(this, canceledOrderKey(_orderId)), false))
113110 then throw(("Order already cancelled: " + toString(_orderId)))
114111 else true
115112
116113
117114 func currentOrderId () = valueOrElse(getInteger(this, k_lastOrderId), 0)
118115
119116
120117 func getTraderOrderCount (_amm,_trader) = {
121118 let key = traderOrderCountKey(_amm, _trader)
122119 valueOrElse(getInteger(this, key), 0)
123120 }
124121
125122
126123 func traderAmmOrdersIds (_amm,_trader) = {
127124 let key = traderOrderIdsKey(_amm, _trader)
128125 let val = valueOrElse(getString(this, key), "")
129126 if ((val == ""))
130127 then nil
131128 else split(val, ",")
132129 }
133130
134131
135132 func getOrder (_orderId) = {
136133 let orderStr = valueOrErrorMessage(getString(this, orderKey(_orderId)), ("Invalid order id: " + toString(_orderId)))
137134 let orderPartList = split(orderStr, ",")
138135 let amm = orderPartList[0]
139136 let trader = orderPartList[1]
140137 let amountIn = valueOrErrorMessage(parseInt(orderPartList[2]), "Invalid amountIn")
141138 let leverage = valueOrErrorMessage(parseInt(orderPartList[3]), "Invalid leverage")
142139 let type = valueOrErrorMessage(parseInt(orderPartList[4]), "Invalid type")
143140 let triggerPrice = valueOrErrorMessage(parseInt(orderPartList[5]), "Invalid triggerPrice")
144141 let paymentUsdn = valueOrErrorMessage(parseInt(orderPartList[6]), "Invalid paymentUsdn")
145142 let side = valueOrErrorMessage(parseInt(orderPartList[7]), "Invalid side")
146143 let refLink = orderPartList[8]
147144 let positionId = valueOrErrorMessage(parseInt(orderPartList[9]), "Invalid positionId")
148145 let limitPrice = valueOrErrorMessage(parseInt(orderPartList[10]), "Invalid limitPrice")
149146 $Tuple11(amm, trader, amountIn, leverage, type, triggerPrice, paymentUsdn, side, refLink, positionId, limitPrice)
150147 }
151148
152149
153150 func getMarketPrice (_amm) = {
154151 let s = invoke(addressFromStringValue(_amm), "computeSpotPrice", nil, nil)
155152 if ((s == s))
156153 then {
157154 let res = match s {
158155 case t: Int =>
159156 t
160157 case _ =>
161158 throw("Invalid computeSpotPrice result")
162159 }
163160 value(res)
164161 }
165162 else throw("Strict value is not equal to itself.")
166163 }
167164
168165
169166 func getFee (_amm,_trader) = {
170167 let s = invoke(addressFromStringValue(_amm), "computeFeeForTraderWithArtifact", [_trader, ""], nil)
171168 if ((s == s))
172169 then {
173170 let res = match s {
174171 case t: (Int, Boolean) =>
175172 t._1
176173 case _ =>
177174 throw("Invalid computeFeeForTraderWithArtifact result")
178175 }
179176 value(res)
180177 }
181178 else throw("Strict value is not equal to itself.")
182179 }
183180
184181
185182 func getPositionSize (_amm,_trader) = {
186183 let amm = addressFromStringValue(_amm)
187184 let sizeKey = toCompositeKey(k_positionSize, _trader)
188185 valueOrElse(getInteger(amm, sizeKey), 0)
189186 }
190187
191188
192189 func getPositionId (_amm,_trader) = {
193190 let amm = addressFromStringValue(_amm)
194191 let seqKey = toCompositeKey(k_positionSequence, _trader)
195192 valueOrElse(getInteger(amm, seqKey), 0)
196193 }
197194
198195
199196 func getSpread (_price) = muld(_price, SPREAD_LIMIT)
200197
201198
202199 func saveOrder (_orderId,_amm,_trader,_amountIn,_leverage,_type,_triggerPrice,_paymentUsdn,_side,_refLink,_positionId,_limitPrice) = {
203200 let orderStr = makeString([_amm, _trader, toString(_amountIn), toString(_leverage), toString(_type), toString(_triggerPrice), toString(_paymentUsdn), toString(_side), _refLink, toString(_positionId), toString(_limitPrice)], ",")
204201 [StringEntry(orderKey(_orderId), orderStr)]
205202 }
206203
207204
208205 func addRemoveOrderId (_orderId,_amm,_trader,_add) = {
209206 let orderIds = traderAmmOrdersIds(_amm, _trader)
210207 let orderIdsNew = if (_add)
211208 then (orderIds :+ toString(_orderId))
212209 else removeByIndex(orderIds, valueOrErrorMessage(indexOf(orderIds, toString(_orderId)), ("No order with id: " + toString(_orderId))))
213210 let orderIdsNewStr = makeString(orderIdsNew, ",")
214211 [StringEntry(traderOrderIdsKey(_amm, _trader), orderIdsNewStr)]
215212 }
216213
217214
218215 func updateTraderOrderCount (_amm,_trader,_count) = [IntegerEntry(traderOrderCountKey(_amm, _trader), _count)]
219216
220217
221218 func updateLastOrderId (_lastOrderId) = [IntegerEntry(k_lastOrderId, _lastOrderId)]
222219
223220
224221 func markExecuteOrder (_orderId) = [BooleanEntry(toCompositeKey(k_executedOrders, toString(_orderId)), true)]
225222
226223
227224 func markCancelOrder (_orderId) = [BooleanEntry(toCompositeKey(k_canceledOrders, toString(_orderId)), true)]
228225
229226
230227 @Callable(i)
231228 func cleanUpStaleOrders (_amm,_trader) = {
232229 let orders = traderAmmOrdersIds(_amm, _trader)
233230 let orderCount = getTraderOrderCount(_amm, _trader)
234231 func cleanUpOne (_acc,_orderId) = {
235232 let orderIdInt = valueOrErrorMessage(parseInt(_orderId), "Invalid order id")
236- let $t083838578 = getOrder(orderIdInt)
237- let _x1 = $t083838578._1
238- let _x2 = $t083838578._2
239- let _x3 = $t083838578._3
240- let _x4 = $t083838578._4
241- let _type = $t083838578._5
242- let _x5 = $t083838578._6
243- let _x6 = $t083838578._7
244- let _x7 = $t083838578._8
245- let _x8 = $t083838578._9
246- let _positionId = $t083838578._10
247- let _x9 = $t083838578._11
233+ let $t082878482 = getOrder(orderIdInt)
234+ let _x1 = $t082878482._1
235+ let _x2 = $t082878482._2
236+ let _x3 = $t082878482._3
237+ let _x4 = $t082878482._4
238+ let _type = $t082878482._5
239+ let _x5 = $t082878482._6
240+ let _x6 = $t082878482._7
241+ let _x7 = $t082878482._8
242+ let _x8 = $t082878482._9
243+ let _positionId = $t082878482._10
244+ let _x9 = $t082878482._11
248245 let positionSize = getPositionSize(_amm, _trader)
249246 let currentPositionId = if ((positionSize != 0))
250247 then getPositionId(_amm, _trader)
251248 else 0
252249 if (if (if ((_type == STOP))
253250 then true
254251 else (_type == TAKE))
255252 then (currentPositionId != _positionId)
256253 else false)
257254 then {
258255 let change = (markCancelOrder(orderIdInt) ++ addRemoveOrderId(orderIdInt, _amm, _trader, false))
259256 $Tuple2((_acc._1 + 1), (_acc._2 ++ change))
260257 }
261258 else _acc
262259 }
263260
264261 let result = {
265262 let $l = orders
266263 let $s = size($l)
267264 let $acc0 = $Tuple2(0, nil)
268265 func $f0_1 ($a,$i) = if (($i >= $s))
269266 then $a
270267 else cleanUpOne($a, $l[$i])
271268
272269 func $f0_2 ($a,$i) = if (($i >= $s))
273270 then $a
274271 else throw("List size exceeds 5")
275272
276273 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
277274 }
278275 (result._2 ++ updateTraderOrderCount(_amm, _trader, (orderCount - result._1)))
279276 }
280277
281278
282279
283280 @Callable(i)
284281 func setContext (_sender) = if ((i.caller != this))
285282 then throw("Only self-call")
286283 else [StringEntry(k_sender, _sender)]
287284
288285
289286
290287 @Callable(i)
291288 func resetContext () = if ((i.caller != this))
292289 then throw("Only self-call")
293290 else [DeleteEntry(k_sender)]
294291
295292
296293
297294 @Callable(i)
298-func initialize (_coordinator) = if (initialized())
299- then throw("Already initialized")
300- else [StringEntry(k_coordinatorAddress, _coordinator), BooleanEntry(k_initialized, true)]
295+func initialize (_coordinator) = if (if (initialized())
296+ then true
297+ else (i.caller != this))
298+ then throw("Unable to initialize")
299+ else [StringEntry(k_coordinatorAddress, toString(addressFromStringValue(_coordinator))), BooleanEntry(k_initialized, true)]
301300
302301
303302
304303 @Callable(i)
305304 func createOrder (_amm,_type,_triggerPrice,_limitPrice,_amountIn,_leverage,_side,_refLink) = {
306305 let _trader = toString(i.caller)
307306 let cleanUp = invoke(this, "cleanUpStaleOrders", [_amm, _trader], nil)
308307 if ((cleanUp == cleanUp))
309308 then if ((size(i.payments) > 1))
310309 then throw("Invalid createOrder parameters: invalid payment count")
311310 else {
312- let $t01028710539 = if ((size(i.payments) == 1))
311+ let $t01024710499 = if ((size(i.payments) == 1))
313312 then $Tuple2(toBase58String(valueOrErrorMessage(i.payments[0].assetId, "Invalid asset id")), i.payments[0].amount)
314313 else $Tuple2("", 0)
315- let paymentAssetId = $t01028710539._1
316- let paymentAmount = $t01028710539._2
314+ let paymentAssetId = $t01024710499._1
315+ let paymentAmount = $t01024710499._2
317316 let doCall = invoke(this, "internalCreateOrder", [_trader, _amm, _type, _triggerPrice, _limitPrice, _amountIn, _leverage, _side, _refLink, paymentAssetId, paymentAmount], nil)
318317 if ((doCall == doCall))
319318 then nil
320319 else throw("Strict value is not equal to itself.")
321320 }
322321 else throw("Strict value is not equal to itself.")
323322 }
324323
325324
326325
327326 @Callable(i)
328327 func increasePositionWithStopLoss (_amm,_direction,_leverage,_minBaseAssetAmount,_refLink,_stopTriggerPrice,_stopLimitPrice,_takeTriggerPrice,_takeLimitPrice) = {
329328 let _trader = toString(i.caller)
330329 let cleanUp = invoke(this, "cleanUpStaleOrders", [_amm, _trader], nil)
331330 if ((cleanUp == cleanUp))
332331 then if (if (!(initialized()))
333332 then true
334333 else !(isWhitelist(_amm)))
335334 then throw("Invalid increasePositionWithStopLoss parameters")
336335 else {
337336 let positionSize = getPositionSize(_amm, _trader)
338337 if ((positionSize != 0))
339338 then throw("Invalid increasePositionWithStopLoss parameters: only new position")
340339 else {
341340 let doSetContext = invoke(this, "setContext", [_trader], nil)
342341 if ((doSetContext == doSetContext))
343342 then {
344343 let doClosePosition = invoke(addressFromStringValue(_amm), "increasePosition", [_direction, _leverage, _minBaseAssetAmount, _refLink], i.payments)
345344 if ((doClosePosition == doClosePosition))
346345 then {
347346 let doResetContext = invoke(this, "resetContext", nil, nil)
348347 if ((doResetContext == doResetContext))
349348 then {
350349 let openedPositionSize = getPositionSize(_amm, _trader)
351350 if ((openedPositionSize == openedPositionSize))
352351 then {
353352 let amountIn = abs(openedPositionSize)
354353 let stopLossSide = if ((0 > openedPositionSize))
355354 then LONG
356355 else SHORT
357356 let doCreateStopOrder = if ((_stopTriggerPrice > 0))
358357 then {
359358 let doCreateStopOrder = invoke(this, "internalCreateOrder", [_trader, _amm, STOP, _stopTriggerPrice, _stopLimitPrice, amountIn, 0, stopLossSide, _refLink, "", 0], nil)
360359 if ((doCreateStopOrder == doCreateStopOrder))
361360 then nil
362361 else throw("Strict value is not equal to itself.")
363362 }
364363 else nil
365364 if ((doCreateStopOrder == doCreateStopOrder))
366365 then {
367366 let doCreateTakeOrder = if ((_takeTriggerPrice > 0))
368367 then {
369368 let doCreateTakeOrder = invoke(this, "internalCreateOrder", [_trader, _amm, TAKE, _takeTriggerPrice, _takeLimitPrice, amountIn, 0, stopLossSide, _refLink, "", 0], nil)
370369 if ((doCreateTakeOrder == doCreateTakeOrder))
371370 then nil
372371 else throw("Strict value is not equal to itself.")
373372 }
374373 else nil
375374 if ((doCreateTakeOrder == doCreateTakeOrder))
376375 then nil
377376 else throw("Strict value is not equal to itself.")
378377 }
379378 else throw("Strict value is not equal to itself.")
380379 }
381380 else throw("Strict value is not equal to itself.")
382381 }
383382 else throw("Strict value is not equal to itself.")
384383 }
385384 else throw("Strict value is not equal to itself.")
386385 }
387386 else throw("Strict value is not equal to itself.")
388387 }
389388 }
390389 else throw("Strict value is not equal to itself.")
391390 }
392391
393392
394393
395394 @Callable(i)
396395 func internalCreateOrder (_trader,_amm,_type,_triggerPrice,_limitPrice,_amountIn,_leverage,_side,_refLink,_paymentAssetId,_paymentAmount) = if (if (if (if (if (if (if (if (if (!(initialized()))
397396 then true
398397 else !(isWhitelist(_amm)))
399398 then true
400399 else (0 >= _triggerPrice))
401400 then true
402401 else (0 > _limitPrice))
403402 then true
404403 else (0 >= _amountIn))
405404 then true
406405 else (0 > _leverage))
407406 then true
408407 else !(if ((_side == LONG))
409408 then true
410409 else (_side == SHORT)))
411410 then true
412- else !(if (if ((_type == STOP))
411+ else !(if ((_type == STOP))
413412 then true
414- else (_type == TAKE))
415- then true
416- else (_type == LIMIT)))
413+ else (_type == TAKE)))
417414 then true
418415 else !((i.caller == this)))
419416 then throw("Invalid createOrder parameters")
420417 else {
421418 let orderId = (currentOrderId() + 1)
422419 let newTraderOrderCount = (getTraderOrderCount(_amm, _trader) + 1)
423420 let positionSize = getPositionSize(_amm, _trader)
424421 let _direction = if (if (if ((positionSize == 0))
425422 then true
426423 else if ((positionSize > 0))
427424 then (_side == LONG)
428425 else false)
429426 then true
430427 else if ((0 > positionSize))
431428 then (_side == SHORT)
432429 else false)
433430 then INCREASE
434431 else DECREASE
435432 if (if ((positionSize == 0))
436433 then if ((_type == STOP))
437434 then true
438435 else (_type == TAKE)
439436 else false)
440437 then throw("Can not create STOP/TAKE order: no position")
441438 else {
442439 let usdnPayment = if ((_direction == INCREASE))
443440 then if (if ((_paymentAssetId != toBase58String(quoteAsset())))
444441 then true
445442 else (_paymentAmount != _amountIn))
446443 then throw("Invalid createLimitOrder parameters: invalid payment")
447444 else {
448445 let stake = invoke(managerAddress(), "deposit", nil, [AttachedPayment(quoteAsset(), _paymentAmount)])
449446 if ((stake == stake))
450447 then _paymentAmount
451448 else throw("Strict value is not equal to itself.")
452449 }
453450 else 0
454451 if ((usdnPayment == usdnPayment))
455452 then {
456453 let positionId = if ((positionSize != 0))
457454 then getPositionId(_amm, _trader)
458455 else 0
459456 if ((newTraderOrderCount > MAX_TRADER_ORDERS_PER_AMM))
460457 then throw("Invalid createLimitOrder parameters: order count")
461458 else (((saveOrder(orderId, _amm, _trader, _amountIn, _leverage, _type, _triggerPrice, usdnPayment, _side, _refLink, positionId, _limitPrice) ++ addRemoveOrderId(orderId, _amm, _trader, true)) ++ updateTraderOrderCount(_amm, _trader, newTraderOrderCount)) ++ updateLastOrderId(orderId))
462459 }
463460 else throw("Strict value is not equal to itself.")
464461 }
465462 }
466463
467464
468465
469466 @Callable(i)
470467 func cancelOrder (_orderId) = {
471- let $t01590816127 = getOrder(_orderId)
472- let _amm = $t01590816127._1
473- let _trader = $t01590816127._2
474- let _amountIn = $t01590816127._3
475- let _leverage = $t01590816127._4
476- let _type = $t01590816127._5
477- let _triggerPrice = $t01590816127._6
478- let _amountUsdn = $t01590816127._7
479- let _side = $t01590816127._8
480- let _refLink = $t01590816127._9
481- let _positionId = $t01590816127._10
482- let _limitPrice = $t01590816127._11
468+ let $t01585016069 = getOrder(_orderId)
469+ let _amm = $t01585016069._1
470+ let _trader = $t01585016069._2
471+ let _amountIn = $t01585016069._3
472+ let _leverage = $t01585016069._4
473+ let _type = $t01585016069._5
474+ let _triggerPrice = $t01585016069._6
475+ let _amountUsdn = $t01585016069._7
476+ let _side = $t01585016069._8
477+ let _refLink = $t01585016069._9
478+ let _positionId = $t01585016069._10
479+ let _limitPrice = $t01585016069._11
483480 if (if (if (!(initialized()))
484481 then true
485482 else !(isValid(_orderId)))
486483 then true
487484 else !((toString(i.caller) == _trader)))
488485 then throw("Invalid cancelOrder parameters")
489486 else {
490487 let cleanUp = invoke(this, "cleanUpStaleOrders", [_amm, _trader], nil)
491488 if ((cleanUp == cleanUp))
492489 then {
493490 let newTraderOrderCount = (getTraderOrderCount(_amm, _trader) - 1)
494491 let withdraw = if ((_amountUsdn > 0))
495492 then {
496493 let unstake = invoke(managerAddress(), "withdraw", [toBase58String(quoteAsset()), _amountUsdn], nil)
497494 if ((unstake == unstake))
498495 then nil
499496 else throw("Strict value is not equal to itself.")
500497 }
501498 else nil
502499 if ((withdraw == withdraw))
503500 then (((markCancelOrder(_orderId) ++ addRemoveOrderId(_orderId, _amm, _trader, false)) ++ updateTraderOrderCount(_amm, _trader, newTraderOrderCount)) ++ (if ((_amountUsdn > 0))
504501 then [ScriptTransfer(i.caller, _amountUsdn, quoteAsset())]
505502 else nil))
506503 else throw("Strict value is not equal to itself.")
507504 }
508505 else throw("Strict value is not equal to itself.")
509506 }
510507 }
511508
512509
513510
514511 @Callable(i)
515512 func executeOrder (_orderId) = {
516- let $t01709817317 = getOrder(_orderId)
517- let _amm = $t01709817317._1
518- let _trader = $t01709817317._2
519- let _amountIn = $t01709817317._3
520- let _leverage = $t01709817317._4
521- let _type = $t01709817317._5
522- let _triggerPrice = $t01709817317._6
523- let _amountUsdn = $t01709817317._7
524- let _side = $t01709817317._8
525- let _refLink = $t01709817317._9
526- let _positionId = $t01709817317._10
527- let _limitPrice = $t01709817317._11
513+ let $t01704017259 = getOrder(_orderId)
514+ let _amm = $t01704017259._1
515+ let _trader = $t01704017259._2
516+ let _amountIn = $t01704017259._3
517+ let _leverage = $t01704017259._4
518+ let _type = $t01704017259._5
519+ let _triggerPrice = $t01704017259._6
520+ let _amountUsdn = $t01704017259._7
521+ let _side = $t01704017259._8
522+ let _refLink = $t01704017259._9
523+ let _positionId = $t01704017259._10
524+ let _limitPrice = $t01704017259._11
528525 let cleanUp = invoke(this, "cleanUpStaleOrders", [_amm, _trader], nil)
529526 if ((cleanUp == cleanUp))
530527 then if (if (!(initialized()))
531528 then true
532529 else !(isValid(_orderId)))
533530 then throw("Invalid executeOrder parameters")
534531 else {
535532 let positionSize = getPositionSize(_amm, _trader)
536533 let currentPositionId = if ((positionSize != 0))
537534 then getPositionId(_amm, _trader)
538535 else 0
539- let $t01772121563 = if ((_type == STOP))
536+ let $t01766321505 = if ((_type == STOP))
540537 then {
541538 let _positionDirection = if ((positionSize > 0))
542539 then LONG
543540 else if ((0 > positionSize))
544541 then SHORT
545542 else throw("Can not execute STOP order: no open position")
546543 let marketPrice = getMarketPrice(_amm)
547544 let isExecutable = if ((_side == _positionDirection))
548545 then throw("Can not execute STOP order: reduce only")
549546 else if ((currentPositionId != _positionId))
550547 then throw("Can not execute STOP order: position closed")
551548 else if ((_positionDirection == LONG))
552549 then (_triggerPrice >= marketPrice)
553550 else (marketPrice >= _triggerPrice)
554551 if (isExecutable)
555552 then $Tuple3("closePosition", [minv(_amountIn, abs(positionSize)), muld(_limitPrice, abs(positionSize)), false], nil)
556553 else throw("Can not execute STOP order: triggerPrice mismatch")
557554 }
558555 else if ((_type == TAKE))
559556 then {
560557 let _positionDirection = if ((positionSize > 0))
561558 then LONG
562559 else if ((0 > positionSize))
563560 then SHORT
564561 else throw("Can not execute STOP order: no open position")
565562 let marketPrice = getMarketPrice(_amm)
566563 let isExecutable = if ((_side == _positionDirection))
567564 then throw("Can not execute TAKE order: reduce only")
568565 else if ((currentPositionId != _positionId))
569566 then throw(((("Can not execute TAKE order: position closed " + toString(currentPositionId)) + "!=") + toString(_positionId)))
570567 else if ((_positionDirection == LONG))
571568 then (marketPrice >= _triggerPrice)
572569 else (_triggerPrice >= marketPrice)
573570 if (isExecutable)
574571 then $Tuple3("closePosition", [minv(_amountIn, abs(positionSize)), muld(_limitPrice, abs(positionSize)), false], nil)
575572 else throw("Can not execute TAKE order: triggerPrice mismatch")
576573 }
577574 else if ((_type == LIMIT))
578575 then {
579576 let marketPrice = getMarketPrice(_amm)
580577 let spread = if ((_limitPrice == 0))
581578 then getSpread(_triggerPrice)
582579 else abs((_triggerPrice - _limitPrice))
583580 let isExecutable = if ((marketPrice >= (_triggerPrice - spread)))
584581 then ((_triggerPrice + spread) >= marketPrice)
585582 else false
586583 if (isExecutable)
587584 then {
588585 let _positionDirection = if ((positionSize > 0))
589586 then LONG
590587 else if ((0 > positionSize))
591588 then SHORT
592589 else -1
593590 let direction = if ((positionSize == 0))
594591 then INCREASE
595592 else if ((_positionDirection == _side))
596593 then INCREASE
597594 else DECREASE
598595 if ((direction == INCREASE))
599596 then {
600597 let amountInWithFee = (_amountUsdn - muld(_amountUsdn, getFee(_amm, _trader)))
601598 $Tuple3("increasePosition", [_side, _leverage, if ((_limitPrice == 0))
602599 then 0
603600 else divd(amountInWithFee, _limitPrice), _refLink], [AttachedPayment(quoteAsset(), _amountUsdn)])
604601 }
605602 else $Tuple3("closePosition", [_amountIn, muld(_amountIn, _limitPrice), false], nil)
606603 }
607604 else throw("Can not execute LIMIT order: triggerPrice mismatch")
608605 }
609606 else throw(("Invalid order type: " + toString(_type)))
610- let method = $t01772121563._1
611- let args = $t01772121563._2
612- let payments = $t01772121563._3
607+ let method = $t01766321505._1
608+ let args = $t01766321505._2
609+ let payments = $t01766321505._3
613610 let withdraw = if ((size(payments) == 1))
614611 then {
615612 let unstake = invoke(managerAddress(), "withdraw", [toBase58String(quoteAsset()), payments[0].amount], nil)
616613 if ((unstake == unstake))
617614 then nil
618615 else throw("Strict value is not equal to itself.")
619616 }
620617 else nil
621618 if ((withdraw == withdraw))
622619 then {
623620 let doSetContext = invoke(this, "setContext", [_trader], nil)
624621 if ((doSetContext == doSetContext))
625622 then {
626623 let doClosePosition = invoke(addressFromStringValue(_amm), method, args, payments)
627624 if ((doClosePosition == doClosePosition))
628625 then {
629626 let doResetContext = invoke(this, "resetContext", nil, nil)
630627 if ((doResetContext == doResetContext))
631628 then {
632629 let newTraderOrderCount = (getTraderOrderCount(_amm, _trader) - 1)
633630 ((updateTraderOrderCount(_amm, _trader, newTraderOrderCount) ++ addRemoveOrderId(_orderId, _amm, _trader, false)) ++ markExecuteOrder(_orderId))
634631 }
635632 else throw("Strict value is not equal to itself.")
636633 }
637634 else throw("Strict value is not equal to itself.")
638635 }
639636 else throw("Strict value is not equal to itself.")
640637 }
641638 else throw("Strict value is not equal to itself.")
642639 }
643640 else throw("Strict value is not equal to itself.")
644641 }
645642
646643
647644
648645 @Callable(i)
649646 func view_canExecuteOrder (_orderId) = {
650647 let s = invoke(this, "executeOrder", [_orderId], nil)
651648 if ((s == s))
652649 then throw("Success")
653650 else throw("Strict value is not equal to itself.")
654651 }
655652
656653
657654 @Verifier(tx)
658-func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], adminPublicKey())
655+func verify () = {
656+ let coordinatorStr = getString(this, k_coordinatorAddress)
657+ if (isDefined(coordinatorStr))
658+ then {
659+ let admin = getString(addressFromStringValue(value(coordinatorStr)), k_admin_address)
660+ if (isDefined(admin))
661+ then valueOrElse(getBoolean(addressFromStringValue(value(admin)), ((("status_" + toString(this)) + "_") + toBase58String(tx.id))), false)
662+ else throw("unable to verify: admin not set in coordinator")
663+ }
664+ else sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
665+ }
659666

github/deemru/w8io/873ac7e 
101.15 ms