2021.07.30 11:46 [2700951] smart account 3PC9BfRwJWWiw9AREE2B3eWzCks3CYtg4yo > SELF 0.00000000 Waves

{ "type": 13, "id": "6oobFxdMxQno2NcJ5GpmwxLHKfnLtnSDV3wnVKBVAkFG", "fee": 14000000, "feeAssetId": null, "timestamp": 1627636289811, "version": 1, "sender": "3PC9BfRwJWWiw9AREE2B3eWzCks3CYtg4yo", "senderPublicKey": "BRnVwSVctnV8pge5vRpsJdWnkjWEJspFb6QvrmZvu3Ht", "proofs": [ "4qWfpiPVyo9oCSqkjtsqopFxzhZwjMgsHDpyRF7fiw7MRRn3uHHcNB4YuKRrrFzBEPzBKH8EFjzbSiYg32twkUgq", "2VF9dFuDXBPBUaqyAEhjwztK3AX7xPWNof7bVP6nwUsvRRhHTnbiLwFyaXEEHJ9JhLDaq8bt8a9G5YzKyL1bG8g4", "eoXSeDfPwzEpcGpXZ15BQvCWinSf5pRe3MD72PAkEpKpfDL9KrWZdhF6jggb5UBX1RHb8yfVdQ6Y3FP6bNjCxkN", "5jJJkNJF4JEvVQ8WH7tRQ4B2MdvLs6eAfpcHRgFCPpzjthNmWVKyrC5Y1vFe9BmE61vMoCBfkCULC6fFkq5ZSgAN" ], "script": "base64:AAIFAAAAAAAAACAIAhIAEgASBQoDCAEIEgYKBAgBCAISABIAEgUKAwgBAQAAAGsBAAAADmdldE51bWJlckJ5S2V5AAAAAQAAAANrZXkJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAADa2V5AAAAAAAAAAAAAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEAAAADa2V5CQEAAAALdmFsdWVPckVsc2UAAAACCQAEHQAAAAIFAAAABHRoaXMFAAAAA2tleQIAAAAAAQAAAAxnZXRCb29sQnlLZXkAAAABAAAAA2tleQkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBsAAAACBQAAAAR0aGlzBQAAAANrZXkHAQAAABhnZXROdW1iZXJCeUFkZHJlc3NBbmRLZXkAAAACAAAAB2FkZHJlc3MAAAADa2V5CQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEFAAAAB2FkZHJlc3MFAAAAA2tleQAAAAAAAAAAAAEAAAAYZ2V0U3RyaW5nQnlBZGRyZXNzQW5kS2V5AAAAAgAAAAdhZGRyZXNzAAAAA2tleQkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABB0AAAACCQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABBQAAAAdhZGRyZXNzBQAAAANrZXkCAAAAAAEAAAAWZ2V0Qm9vbEJ5QWRkcmVzc0FuZEtleQAAAAIAAAAHYWRkcmVzcwAAAANrZXkJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQbAAAAAgkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQUAAAAHYWRkcmVzcwUAAAADa2V5BwAAAAAQcHViS2V5QWRtaW5zTGlzdAkABEwAAAACAgAAACxHSmRMU2FMaXY1Szd4dWVqYWM4bWNSY0hveW8zZFByRVNydmt0RzNhNk1BUgkABEwAAAACAgAAACxGV1ZmZllyMkFMbUhNZWpabTNXcWVMejZTZHltM2dMRkd0Sm40S1R3eVU1eAkABEwAAAACAgAAACwzV2gyTGFXY2I1Z2c3SzJwUGNXM0VwNkVBdVJCellrQWdyZHB0NDNqVERGYQkABEwAAAACAgAAACw1V1JYRlNqd2NUYk5mS2NKczhacVhtU1NXWXNTVkpVdE12TXFaajVoSDROYwUAAAADbmlsAAAAAANTRVACAAAAAl9fAAAAAAdXQVZFTEVUAAAAAAAF9eEAAAAAAAVQQVVMSQAAAAAAAA9CQAAAAAAIUFJJQ0VMRVQAAAAAAAAPQkAAAAAADkRFRkFVTFRTV0FQRkVFAAAAAAAAAE4gAAAAAAxJZHhOZXRBbW91bnQAAAAAAAAAAAAAAAAADElkeEZlZUFtb3VudAAAAAAAAAAAAQAAAAAOSWR4R3Jvc3NBbW91bnQAAAAAAAAAAAIAAAAAEk5ldXRyaW5vQXNzZXRJZEtleQIAAAARbmV1dHJpbm9fYXNzZXRfaWQAAAAADkJvbmRBc3NldElkS2V5AgAAAA1ib25kX2Fzc2V0X2lkAAAAABJBdWN0aW9uQ29udHJhY3RLZXkCAAAAEGF1Y3Rpb25fY29udHJhY3QAAAAAFkxpcXVpZGF0aW9uQ29udHJhY3RLZXkCAAAAFGxpcXVpZGF0aW9uX2NvbnRyYWN0AAAAAA5SUERDb250cmFjdEtleQIAAAAMcnBkX2NvbnRyYWN0AAAAABFDb250b2xDb250cmFjdEtleQIAAAAQY29udHJvbF9jb250cmFjdAAAAAAbQmFsYW5jZVdhdmVzTG9ja0ludGVydmFsS2V5AgAAABtiYWxhbmNlX3dhdmVzX2xvY2tfaW50ZXJ2YWwAAAAAHkJhbGFuY2VOZXV0cmlub0xvY2tJbnRlcnZhbEtleQIAAAAeYmFsYW5jZV9uZXV0cmlub19sb2NrX2ludGVydmFsAAAAABVNaW5XYXZlc1N3YXBBbW91bnRLZXkCAAAAFW1pbl93YXZlc19zd2FwX2Ftb3VudAAAAAAYTWluTmV1dHJpbm9Td2FwQW1vdW50S2V5AgAAABhtaW5fbmV1dHJpbm9fc3dhcF9hbW91bnQAAAAAG05vZGVPcmFjbGVQcm92aWRlclB1YktleUtleQIAAAAUbm9kZV9vcmFjbGVfcHJvdmlkZXIAAAAAFU5ldXRyaW5vT3V0RmVlUGFydEtleQIAAAAYbmV1dHJpbm9PdXRfc3dhcF9mZWVQYXJ0AAAAABJXYXZlc091dEZlZVBhcnRLZXkCAAAAFXdhdmVzT3V0X3N3YXBfZmVlUGFydAAAAAAVRmVlc01hbmFn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AAR0aGlzCQEAAAAQbWluU3dhcEFtb3VudEtFWQAAAAEFAAAACHN3YXBUeXBlAAAAAAAAAAAAAQAAAA90b3RhbExvY2tlZFJFQUQAAAABAAAACHN3YXBUeXBlCQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMJAQAAAA50b3RhbExvY2tlZEtFWQAAAAEFAAAACHN3YXBUeXBlAAAAAAAAAAAAAQAAABV0b3RhbExvY2tlZEJ5VXNlclJFQUQAAAACAAAACHN3YXBUeXBlAAAABW93bmVyCQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMJAQAAABR0b3RhbExvY2tlZEJ5VXNlcktFWQAAAAIFAAAACHN3YXBUeXBlBQAAAAVvd25lcgAAAAAAAAAAAAEAAAAXYmFsYW5jZUxvY2tJbnRlcnZhbFJFQUQAAAABAAAACHN3YXBUeXBlCQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMJAQAAABZiYWxhbmNlTG9ja0ludGVydmFsS0VZAAAAAQUAAAAIc3dhcFR5cGUAAAAAAAAABaABAAAAGm1pbkJhbGFuY2VMb2NrSW50ZXJ2YWxSRUFEAAAAAQAAAAhzd2FwVHlwZQkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzCQEAAAAZbWluQmFsYW5jZUxvY2tJbnRlcnZhbEtFWQAAAAEFAAAACHN3YXBUeXBlAAAAAAAAAAA8AQAAABVmZWVNYW5hZ2VyQWRkcmVzc1JFQUQAAAAACQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQmAAAAAQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAABHRoaXMFAAAAFUZlZXNNYW5hZ2VyQWRkcmVzc0tleQkAASwAAAACBQAAABVGZWVzTWFuYWdlckFkZHJlc3NLZXkCAAAAESBpcyBub3Qgc3BlY2lmaWVkCQABLAAAAAIFAAAAFUZlZXNNYW5hZ2VyQWRkcmVzc0tleQIAAAAXIGludmFsaWQgYWRkcmVzcyBmb3JtYXQBAAAAFmNvbnZlcnROZXV0cmlub1RvV2F2ZXMAAAACAAAABmFtb3VudAAAAAVwcmljZQkAAGsAAAADCQAAawAAAAMFAAAABmFtb3VudAUAAAAIUFJJQ0VMRVQFAAAABXByaWNlBQAAAAdXQVZFTEVUBQAAAAVQQVVMSQEAAAAWY29udmVydFdhdmVzVG9OZXV0cmlubwAAAAIAAAAGYW1vdW50AAAABXByaWNlCQAAawAAAAMJAABrAAAAAwUAAAAGYW1vdW50BQAAAAVwcmljZQUAAAAIUFJJQ0VMRVQFAAAABVBBVUxJBQAAAAdXQVZFTEVUAQAAABJjb252ZXJ0V2F2ZXNUb0JvbmQAAAACAAAABmFtb3VudAAAAAVwcmljZQkBAAAAFmNvbnZlcnRXYXZlc1RvTmV1dHJpbm8AAAACBQAAAAZhbW91bnQFAAAABXByaWNlAQAAABZjb252ZXJ0SnNvbkFycmF5VG9MaXN0AAAAAQAAAAlqc29uQXJyYXkJAAS1AAAAAgUAAAAJanNvbkFycmF5AgAAAAEsAQAAABFtaW5Td2FwQW1vdW50RkFJTAAAAAIAAAAIc3dhcFR5cGUAAAANbWluU3dhcEFtb3VudAkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAABhUaGUgc3BlY2lmaWVkIGFtb3VudCBpbiAFAAAACHN3YXBUeXBlAgAAACsgc3dhcCBpcyBsZXNzIHRoYW4gdGhlIHJlcXVpcmVkIG1pbmltdW0gb2YgCQABpAAAAAEFAAAADW1pblN3YXBBbW91bnQBAAAAFWVtZXJnZW5jeVNodXRkb3duRkFJTAAAAAAJAAACAAAAAQIAAABaY29udHJhY3QgaXMgYmxvY2tlZCBieSBFTUVSR0VOQ1kgU0hVVERPV04gYWN0aW9ucyB1bnRpbGwgcmVhY3RpdmF0aW9uIGJ5IGVtZXJnZW5jeSBvcmFjbGVzAQAAAA5wcmljZUluZGV4RkFJTAAAAAUAAAAFaW5kZXgAAAAKcHJpY2VJbmRleAAAAAtpbmRleEhlaWdodAAAAAx1bmxvY2tIZWlnaHQAAAAPcHJldkluZGV4SGVpZ2h0CQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAI2ludmFsaWQgcHJpY2UgaGlzdG9yeSBpbmRleDogaW5kZXg9CQABpAAAAAEFAAAABWluZGV4AgAAAAwgcHJpY2VJbmRleD0JAAGkAAAAAQUAAAAKcHJpY2VJbmRleAIAAAANIGluZGV4SGVpZ2h0PQkAAaQAAAABBQAAAAtpbmRleEhlaWdodAIAAAAOIHVubG9ja0hlaWdodD0JAAGkAAAAAQUAAAAMdW5sb2NrSGVpZ2h0AgAAABEgcHJldkluZGV4SGVpZ2h0PQkAAaQAAAABBQAAAA9wcmV2SW5kZXhIZWlnaHQAAAAAE2xpcXVpZGF0aW9uQ29udHJhY3QJAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEFAAAAFkxpcXVpZGF0aW9uQ29udHJhY3RLZXkAAAAAD25ldXRyaW5vQXNzZXRJZAkAAlkAAAABCQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABBQAAABJOZXV0cmlub0Fzc2V0SWRLZXkAAAAAD2F1Y3Rpb25Db250cmFjdAkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQUAAAASQXVjdGlvbkNvbnRyYWN0S2V5AAAAAAtycGRDb250cmFjdAkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQUAAAAOUlBEQ29udHJhY3RLZXkAAAAAD2NvbnRyb2xDb250cmFjdAkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQUAAAARQ29udG9sQ29udHJhY3RLZXkAAAAACnByaWNlSW5kZXgJAQAAABhnZXROdW1iZXJCeUFkZHJlc3NBbmRLZXkAAAACBQAAAA9jb250cm9sQ29udHJhY3QFAAAADVByaWNlSW5kZXhLZXkAAAAACWlzQmxvY2tlZAkBAAAAFmdldEJvb2xCeUFkZHJlc3NBbmRLZXkAAAACBQAAAA9jb250cm9sQ29udHJhY3QFAAAADElzQmxvY2tlZEtleQAAAAAYbm9kZU9yYWNsZVByb3ZpZGVyUHViS2V5CQACWQAAAAEJAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEFAAAAG05vZGVPcmFjbGVQcm92aWRlclB1YktleUtleQAAAAALYm9uZEFzc2V0SWQJAAJZAAAAAQIAAAAsNm5TcFZ5Tkg3eU02OWVnNDQ2d3JRUjk0aXBiYmNtWk1VMUVOUHdhbkM5N2cAAAAAFWRlcHJlY2F0ZWRCb25kQXNzZXRJZAkAAlkAAAABAgAAACw5NzVha1pCZm5NajUxM1U3TVphSEt6UXJtc0V4NWFFM3dkV0tUckhCaGJqRgAAAAAGcnNhUHViCQACWwAAAAEJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAAAR0aGlzBQAAABJSc2FSYW5kUHVibGljNThLZXkCAAAAJVJTQSBwdWJsaWMga2V5IGhhcyBub3QgYmVlbiBzcGVjaWZpZWQAAAAAEG5ldXRyaW5vQ29udHJhY3QFAAAABHRoaXMAAAAADGN1cnJlbnRQcmljZQkBAAAAGGdldE51bWJlckJ5QWRkcmVzc0FuZEtleQAAAAIFAAAAD2NvbnRyb2xDb250cmFjdAUAAAAIUHJpY2VLZXkAAAAAFW5ldXRyaW5vTG9ja2VkQmFsYW5jZQkBAAAAD3RvdGFsTG9ja2VkUkVBRAAAAAECAAAACG5ldXRyaW5vAAAAABJ3YXZlc0xvY2tlZEJhbGFuY2UJAQAAAA90b3RhbExvY2tlZFJFQUQAAAABAgAAAAV3YXZlcwAAAAAHcmVzZXJ2ZQkAAGUAAAACCAkAA+8AAAABBQAAABBuZXV0cmlub0NvbnRyYWN0AAAAB3JlZ3VsYXIFAAAAEndhdmVzTG9ja2VkQmFsYW5jZQAAAAAObmV1dHJpbm9TdXBwbHkJAABlAAAAAgkAAGUAAAACCQAAZAAAAAIFAAAAFW5ldXRyaW5vTG9ja2VkQmFsYW5jZQgJAQAAAAV2YWx1ZQAAAAEJAAPsAAAAAQUAAAAPbmV1dHJpbm9Bc3NldElkAAAACHF1YW50aXR5CQAD8AAAAAIFAAAAEG5ldXRyaW5vQ29udHJhY3QFAAAAD25ldXRyaW5vQXNzZXRJZAkAA/AAAAACCQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABBQAAABNsaXF1aWRhdGlvbkNvbnRyYWN0BQAAAA9uZXV0cmlub0Fzc2V0SWQAAAAAB3N1cnBsdXMJAABlAAAAAgkBAAAAFmNvbnZlcnRXYXZlc1RvTmV1dHJpbm8AAAACBQAAAAdyZXNlcnZlBQAAAAxjdXJyZW50UHJpY2UFAAAADm5ldXRyaW5vU3VwcGx5AAAAAAdkZWZpY2l0CQAAZQAAAAIFAAAADm5ldXRyaW5vU3VwcGx5CQEAAAAWY29udmVydFdhdmVzVG9OZXV0cmlubwAAAAIFAAAAB3Jlc2VydmUFAAAADGN1cnJlbnRQcmljZQEAAAAbY2hlY2tJc1ZhbGlkTWluU3BvbnNvcmVkRmVlAAAAAQAAAAJ0eAQAAAAOTUlOVFJBTlNGRVJGRUUAAAAAAAABhqAEAAAAFlNwb25zb3JlZEZlZVVwcGVyQm91bmQAAAAAAAAAA+gEAAAAD3JlYWxOZXV0cmlub0ZlZQkBAAAAFmNvbnZlcnRXYXZlc1RvTmV1dHJpbm8AAAACBQAAAA5NSU5UUkFOU0ZFUkZFRQUAAAAMY3VycmVudFByaWNlBAAAAA5taW5OZXV0cmlub0ZlZQkAAGgAAAACBQAAAA9yZWFsTmV1dHJpbm9GZWUAAAAAAAAAAAIEAAAADm1heE5ldXRyaW5vRmVlCQAAawAAAAMFAAAAD3JlYWxOZXV0cmlub0ZlZQUAAAAWU3BvbnNvcmVkRmVlVXBwZXJCb3VuZAAAAAAAAAAAZAQAAAAIaW5wdXRGZWUJAQAAAAV2YWx1ZQAAAAEIBQAAAAJ0eAAAABRtaW5TcG9uc29yZWRBc3NldEZlZQMDCQAAZwAAAAIFAAAACGlucHV0RmVlBQAAAA5taW5OZXV0cmlub0ZlZQkAAGcAAAACBQAAAA5tYXhOZXV0cmlub0ZlZQUAAAAIaW5wdXRGZWUHCQAAAAAAAAIIBQAAAAJ0eAAAAAdhc3NldElkBQAAAA9uZXV0cmlub0Fzc2V0SWQHAQAAAA9nZXRQcmljZUhpc3RvcnkAAAABAAAABWJsb2NrCQEAAAAYZ2V0TnVtYmVyQnlBZGRyZXNzQW5kS2V5AAAAAgUAAAAPY29udHJvbENvbnRyYWN0CQEAAAASZ2V0UHJpY2VIaXN0b3J5S2V5AAAAAQUAAAAFYmxvY2sBAAAAFWdldEhlaWdodFByaWNlQnlJbmRleAAAAAEAAAAFaW5kZXgJAQAAABhnZXROdW1iZXJCeUFkZHJlc3NBbmRLZXkAAAACBQAAAA9jb250cm9sQ29udHJhY3QJAQAAABhnZXRIZWlnaHRQcmljZUJ5SW5kZXhLZXkAAAABBQAAAAVpbmRleAAAAAAMc0lkeFN3YXBUeXBlAAAAAAAAAAABAAAAAApzSWR4U3RhdHVzAAAAAAAAAAACAAAAAAxzSWR4SW5BbW91bnQAAAAAAAAAAAMAAAAACXNJZHhQcmljZQAAAAAAAAAABAAAAAAQc0lkeE91dE5ldEFtb3VudAAAAAAAAAAABQAAAAAQc0lkeE91dEZlZUFtb3VudAAAAAAAAAAABgAAAAAPc0lkeFN0YXJ0SGVpZ2h0AAAAAAAAAAAHAAAAABJzSWR4U3RhcnRUaW1lc3RhbXAAAAAAAAAAAAgAAAAADXNJZHhFbmRIZWlnaHQAAAAAAAAAAAkAAAAAEHNJZHhFbmRUaW1lc3RhbXAAAAAAAAAAAAoAAAAAFHNJZHhTZWxmVW5sb2NrSGVpZ2h0AAAAAAAAAAALAAAAABRzSWR4UmFuZFVubG9ja0hlaWdodAAAAAAAAAAADAAAAAAJc0lkeEluZGV4AAAAAAAAAAANAAAAABBzSWR4V2l0aGRyYXdUeElkAAAAAAAAAAAOAQAAAAdzd2FwS0VZAAAAAgAAAAt1c2VyQWRkcmVzcwAAAAR0eElkCQAEuQAAAAIJAARMAAAAAgIAAAAEJXMlcwkABEwAAAACBQAAAAt1c2VyQWRkcmVzcwkABEwAAAACBQAAAAR0eElkBQAAAANuaWwFAAAAA1NFUAEAAAALc3RyU3dhcERBVEEAAAAOAAAACHN3YXBUeXBlAAAABnN0YXR1cwAAAAhpbkFtb3VudAAAAAVwcmljZQAAAAxvdXROZXRBbW91bnQAAAAMb3V0RmVlQW1vdW50AAAAC3N0YXJ0SGVpZ2h0AAAADnN0YXJ0VGltZXN0YW1wAAAACWVuZEhlaWdodAAAAAxlbmRUaW1lc3RhbXAAAAAQc2VsZlVubG9ja0hlaWdodAAAABByYW5kVW5sb2NrSGVpZ2h0AAAABWluZGV4AAAADHdpdGhkcmF3VHhJZAkABLkAAAACCQAETAAAAAICAAAAHCVzJXMlZCVkJWQlZCVkJWQlZCVkJWQlZCVkJXMJAARMAAAAAgUAAAAIc3dhcFR5cGUJAARMAAAAAgUAAAAGc3RhdHVzCQAETAAAAAIFAAAACGluQW1vdW50CQAETAAAAAIFAAAABXByaWNlCQAETAAAAAIFAAAADG91dE5ldEFtb3VudAkABEwAAAACBQAAAAxvdXRGZWVBbW91bnQJAARMAAAAAgUAAAALc3RhcnRIZWlnaHQJAARMAAAAAgUAAAAOc3RhcnRUaW1lc3RhbXAJAARMAAAAAgUAAAAJZW5kSGVpZ2h0CQAETAAAAAIFAAAADGVuZFRpbWVzdGFtcAkABEwAAAACBQAAABBzZWxmVW5sb2NrSGVpZ2h0CQAETAAAAAIFAAAAEHJhbmRVbmxvY2tIZWlnaHQJAARMAAAAAgUAAAAFaW5kZXgJAARMAAAAAgUAAAAMd2l0aGRyYXdUeElkBQAAAANuaWwFAAAAA1NFUAEAAAAPcGVuZGluZ1N3YXBEQVRBAAAAAwAAAAhzd2FwVHlwZQAAAA1pbkFzc2V0QW1vdW50AAAAEHNlbGZVbmxvY2tIZWlnaHQJAQAAAAtzdHJTd2FwREFUQQAAAA4FAAAACHN3YXBUeXBlAgAAAAdQRU5ESU5HCQABpAAAAAEFAAAADWluQXNzZXRBbW91bnQCAAAAATACAAAAATACAAAAATAJAAGkAAAAAQUAAAAGaGVpZ2h0CQABpAAAAAEIBQAAAAlsYXN0QmxvY2sAAAAJdGltZXN0YW1wAgAAAAEwAgAAAAEwCQABpAAAAAEFAAAAEHNlbGZVbmxvY2tIZWlnaHQCAAAAATACAAAAATACAAAABE5VTEwBAAAADmZpbmlzaFN3YXBEQVRBAAAABwAAAAlkYXRhQXJyYXkAAAAFcHJpY2UAAAAMb3V0TmV0QW1vdW50AAAADG91dEZlZUFtb3VudAAAABByYW5kVW5sb2NrSGVpZ2h0AAAABWluZGV4AAAADHdpdGhkcmF3VHhJZAkBAAAAC3N0clN3YXBEQVRBAAAADgkAAZEAAAACBQAAAAlkYXRhQXJyYXkFAAAADHNJZHhTd2FwVHlwZQIAAAAIRklOSVNIRUQJAAGRAAAAAgUAAAAJZGF0YUFycmF5BQAAAAxzSWR4SW5BbW91bnQJAAGkAAAAAQUAAAAFcHJpY2UJAAGkAAAAAQUAAAAMb3V0TmV0QW1vdW50CQABpAAAAAEFAAAADG91dEZlZUFtb3VudAkAAZEAAAACBQAAAAlkYXRhQXJyYXkFAAAAD3NJZHhTdGFydEhlaWdodAkAAZEAAAACBQAAAAlkYXRhQXJyYXkFAAAAEnNJZHhTdGFydFRpbWVzdGFtcAkAAaQAAAABBQAAAAZoZWlnaHQJAAGkAAAAAQgFAAAACWxhc3RCbG9jawAAAAl0aW1lc3RhbXAJAAGRAAAAAgUAAAAJZGF0YUFycmF5BQAAABRzSWR4U2VsZlVubG9ja0hlaWdodAkAAaQAAAABBQAAABByYW5kVW5sb2NrSGVpZ2h0CQABpAAAAAEFAAAABWluZGV4BQAAAAx3aXRoZHJhd1R4SWQBAAAAEnN3YXBEYXRhRmFpbE9yUkVBRAAAAAIAAAALdXNlckFkZHJlc3MAAAAIc3dhcFR4SWQEAAAAB3N3YXBLZXkJAQAAAAdzd2FwS0VZAAAAAgUAAAALdXNlckFkZHJlc3MFAAAACHN3YXBUeElkCQAEtQAAAAIJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAAAR0aGlzBQAAAAdzd2FwS2V5CQABLAAAAAICAAAAEW5vIHN3YXAgZGF0YSBmb3IgBQAAAAdzd2FwS2V5BQAAAANTRVABAAAACWFwcGx5RmVlcwAAAAIAAAALYW1vdW50R3Jvc3MAAAAHZmVlUGFydAQAAAAJZmVlQW1vdW50CQAAawAAAAMFAAAAC2Ftb3VudEdyb3NzBQAAAAdmZWVQYXJ0BQAAAAVQQVVMSQkABEwAAAACCQAAZQAAAAIFAAAAC2Ftb3VudEdyb3NzBQAAAAlmZWVBbW91bnQJAARMAAAAAgUAAAAJZmVlQW1vdW50CQAETAAAAAIFAAAAC2Ftb3VudEdyb3NzBQAAAANuaWwBAAAAFnJhbmRVbmxvY2tIZWlnaHRPckZhaWwAAAAEAAAABHR4SWQAAAAGcnNhU2lnAAAACHN3YXBUeXBlAAAAC3N0YXJ0SGVpZ2h0BAAAAAppc1JzYVZhbGlkCQAKKAAAAAQFAAAABlNIQTI1NgkAAZsAAAABBQAAAAR0eElkBQAAAAZyc2FTaWcFAAAABnJzYVB1YgMJAQAAAAEhAAAAAQUAAAAKaXNSc2FWYWxpZAkAAAIAAAABAgAAABVpbnZhbGlkIFJTQSBzaWduYXR1cmUEAAAAFm1heEJhbGFuY2VMb2NrSW50ZXJ2YWwJAQAAABdiYWxhbmNlTG9ja0ludGVydmFsUkVBRAAAAAEFAAAACHN3YXBUeXBlBAAAABZtaW5CYWxhbmNlTG9ja0ludGVydmFsCQEAAAAabWluQmFsYW5jZUxv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DEludGVnZXJFbnRyeQAAAAIJAQAAABFnZXRMZWFzZUFtb3VudEtleQAAAAEFAAAACW5vZGVJbmRleAUAAAAObmV3TGVhc2VBbW91bnQFAAAAA25pbAUAAAADbmlsAQAAAApjb21tb25Td2FwAAAAAgAAAAhzd2FwVHlwZQAAAAFpBAAAAANwbXQJAQAAAAV2YWx1ZQAAAAEJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAEAAAAB2FjY291bnQJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyBAAAAAZ0eElkNTgJAAJYAAAAAQgFAAAAAWkAAAANdHJhbnNhY3Rpb25JZAQAAAANbWluU3dhcEFtb3VudAkBAAAAEW1pblN3YXBBbW91bnRSRUFEAAAAAQUAAAAIc3dhcFR5cGUEAAAAC3RvdGFsTG9ja2VkCQEAAAAPdG90YWxMb2NrZWRSRUFEAAAAAQUAAAAIc3dhcFR5cGUEAAAAEXRvdGFsTG9ja2VkQnlVc2VyCQEAAAAVdG90YWxMb2NrZWRCeVVzZXJSRUFEAAAAAgUAAAAIc3dhcFR5cGUFAAAAB2FjY291bnQEAAAAFmJhbGFuY2VMb2NrTWF4SW50ZXJ2YWwJAQAAABdiYWxhbmNlTG9ja0ludGVydmFsUkVBRAAAAAEFAAAACHN3YXBUeXBlBAAAABBzZWxmVW5sb2NrSGVpZ2h0CQAAZAAAAAIFAAAABmhlaWdodAUAAAAWYmFsYW5jZUxvY2tNYXhJbnRlcnZhbAMJAABmAAAAAgUAAAANbWluU3dhcEFtb3VudAgFAAAAA3BtdAAAAAZhbW91bnQJAQAAABFtaW5Td2FwQW1vdW50RkFJTAAAAAIFAAAACHN3YXBUeXBlBQAAAA1taW5Td2FwQW1vdW50AwUAAAAJaXNCbG9ja2VkCQEAAAAVZW1lcmdlbmN5U2h1dGRvd25GQUlMAAAAAAQAAAAJbGVhc2VQYXJ0AwkAAAAAAAACBQAAAAhzd2FwVHlwZQIAAAAFd2F2ZXMJAQAAABZwcmVwYXJlVW5sZWFzZUFuZExlYXNlAAAAAQAAAAAAAAAAAAUAAAADbmlsCQAFFAAAAAIJAAROAAAAAgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAAFHRvdGFsTG9ja2VkQnlVc2VyS0VZAAAAAgUAAAAIc3dhcFR5cGUFAAAAB2FjY291bnQJAABkAAAAAgUAAAARdG90YWxMb2NrZWRCeVVzZXIIBQAAAANwbXQAAAAGYW1vdW50CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAAYZ2V0QmFsYW5jZVVubG9ja0Jsb2NrS2V5AAAAAQUAAAAHYWNjb3VudAkAAGQAAAACBQAAAAZoZWlnaHQFAAAAFmJhbGFuY2VMb2NrTWF4SW50ZXJ2YWwJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAAA50b3RhbExvY2tlZEtFWQAAAAEFAAAACHN3YXBUeXBlCQAAZAAAAAIFAAAAC3RvdGFsTG9ja2VkCAUAAAADcG10AAAABmFtb3VudAkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAAHc3dhcEtFWQAAAAIFAAAAB2FjY291bnQFAAAABnR4SWQ1OAkBAAAAD3BlbmRpbmdTd2FwREFUQQAAAAMFAAAACHN3YXBUeXBlCAUAAAADcG10AAAABmFtb3VudAUAAAAQc2VsZlVubG9ja0hlaWdodAUAAAADbmlsBQAAAAlsZWFzZVBhcnQFAAAABHVuaXQBAAAADmNvbW1vbldpdGhkcmF3AAAABQAAAAdhY2NvdW50AAAABWluZGV4AAAACHN3YXBUeElkAAAADHJzYVNpZ09yVW5pdAAAAAFpBAAAAAt1c2VyQWRkcmVzcwkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQUAAAAHYWNjb3VudAQAAAARZmVlTWFuYWdlckFkZHJlc3MJAQAAABVmZWVNYW5hZ2VyQWRkcmVzc1JFQUQAAAAABAAAAAlkYXRhQXJyYXkJAQAAABJzd2FwRGF0YUZhaWxPclJFQUQAAAACBQAAAAdhY2NvdW50BQAAAAhzd2FwVHhJZAQAAAAQc2VsZlVubG9ja0hlaWdodAkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAAUc0lkeFNlbGZVbmxvY2tIZWlnaHQEAAAACHN3YXBUeXBlCQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAAMc0lkeFN3YXBUeXBlBAAAAAhpbkFtb3VudAkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAAMc0lkeEluQW1vdW50BAAAAApzd2FwU3RhdHVzCQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAAKc0lkeFN0YXR1cwQAAAALc3RhcnRIZWlnaHQJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAAlkYXRhQXJyYXkFAAAAD3NJZHhTdGFydEhlaWdodAQAAAAKb3V0RmVlUGFydAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzCQEAAAANb3V0RmVlUGFydEtFWQAAAAEFAAAACHN3YXBUeXBlBQAAAA5ERUZBVUxUU1dBUEZFRQQAAAALdG90YWxMb2NrZWQJAQAAAA90b3RhbExvY2tlZFJFQUQAAAABBQAAAAhzd2FwVHlwZQQAAAARdG90YWxMb2NrZWRCeVVzZXIJAQAAABV0b3RhbExvY2tlZEJ5VXNlclJFQUQAAAACBQAAAAhzd2FwVHlwZQUAAAAHYWNjb3VudAQAAAAMdW5sb2NrSGVpZ2h0BAAAAAckbWF0Y2gwBQAAAAxyc2FTaWdPclVuaXQDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAACkJ5dGVWZWN0b3IEAAAABnJzYVNpZwUAAAAHJG1hdGNoMAkBAAAAFnJhbmRVbmxvY2tIZWlnaHRPckZhaWwAAAAEBQAAAAhzd2FwVHhJZAUAAAAGcnNhU2lnBQAAAAhzd2FwVHlwZQUAAAALc3RhcnRIZWlnaHQDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABFVuaXQFAAAAEHNlbGZVbmxvY2tIZWlnaHQJAAACAAAAAQIAAAALTWF0Y2ggZXJyb3IEAAAAC2luZGV4SGVpZ2h0CQEAAAAVZ2V0SGVpZ2h0UHJpY2VCeUluZGV4AAAAAQUAAAAFaW5kZXgEAAAAD3ByZXZJbmRleEhlaWdodAkBAAAAFWdldEhlaWdodFByaWNlQnlJbmRleAAAAAEJAABlAAAAAgUAAAAFaW5kZXgAAAAAAAAAAAEEAAAADHByaWNlQnlJbmRleAkBAAAAD2dldFByaWNlSGlzdG9yeQAAAAEFAAAAC2luZGV4SGVpZ2h0BAAAABNvdXRBbW91bnRHcm9zc1R1cGxlAwkAAAAAAAACBQAAAAhzd2FwVHlwZQIAAAAFd2F2ZXMJAAUUAAAAAgkBAAAAFmNvbnZlcnRXYXZlc1RvTmV1dHJpbm8AAAACBQAAAAhpbkFtb3VudAUAAAAMcHJpY2VCeUluZGV4BQAAAA9uZXV0cmlub0Fzc2V0SWQDCQAAAAAAAAIFAAAACHN3YXBUeXBlAgAAAAhuZXV0cmlubwkABRQAAAACCQEAAAAWY29udmVydE5ldXRyaW5vVG9XYXZlcwAAAAIFAAAACGluQW1vdW50BQAAAAxwcmljZUJ5SW5kZXgFAAAABHVuaXQJAAACAAAAAQkAASwAAAACAgAAABZVbnN1cHBvcnRlZCBzd2FwIHR5cGUgBQAAAAhzd2FwVHlwZQQAAAAMcGF5b3V0c0FycmF5CQEAAAAJYXBwbHlGZWVzAAAAAggFAAAAE291dEFtb3VudEdyb3NzVHVwbGUAAAACXzEFAAAACm91dEZlZVBhcnQEAAAADG91dE5ldEFtb3VudAkAAZEAAAACBQAAAAxwYXlvdXRzQXJyYXkFAAAADElkeE5ldEFtb3VudAQAAAAMb3V0RmVlQW1vdW50CQABkQAAAAIFAAAADHBheW91dHNBcnJheQUAAAAMSWR4RmVlQW1vdW50AwUAAAAJaXNCbG9ja2VkCQEAAAAVZW1lcmdlbmN5U2h1dGRvd25GQUlMAAAAAAMJAQAAAAIhPQAAAAIFAAAACnN3YXBTdGF0dXMCAAAAB1BFTkRJTkcJAAACAAAAAQIAAAAfc3dhcCBoYXMgYmVlbiBhbHJlYWR5IHByb2Nlc3NlZAMJAABmAAAAAgUAAAAMdW5sb2NrSGVpZ2h0BQAAAAZoZWlnaHQJAAACAAAAAQkAASwAAAACCQABLAAAAAICAAAAEXBsZWFzZSB3YWl0IGZvcjogCQABpAAAAAEFAAAADHVubG9ja0hlaWdodAIAAAAfIGJsb2NrIGhlaWdodCB0byB3aXRoZHJhdyBmdW5kcwMDAwkAAGYAAAACBQAAAAVpbmRleAUAAAAKcHJpY2VJbmRleAYJAABmAAAAAgUAAAAMdW5sb2NrSGVpZ2h0BQAAAAtpbmRleEhlaWdodAYDCQEAAAACIT0AAAACBQAAAA9wcmV2SW5kZXhI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AWkBAAAACHdpdGhkcmF3AAAAAwAAAAdhY2NvdW50AAAABWluZGV4AAAACHN3YXBUeElkCQEAAAAOY29tbW9uV2l0aGRyYXcAAAAFBQAAAAdhY2NvdW50BQAAAAVpbmRleAUAAAAIc3dhcFR4SWQFAAAABHVuaXQFAAAAAWkAAAABaQEAAAAMd2l0aGRyYXdSYW5kAAAABAAAAAdhY2NvdW50AAAABWluZGV4AAAACHN3YXBUeElkAAAABnJzYVNpZwkBAAAADmNvbW1vbldpdGhkcmF3AAAABQUAAAAHYWNjb3VudAUAAAAFaW5kZXgFAAAACHN3YXBUeElkBQAAAAZyc2FTaWcFAAAAAWkAAAABaQEAAAARdHJhbnNmZXJUb0F1Y3Rpb24AAAAABAAAAA9hdWN0aW9uTkJBbW91bnQJAABlAAAAAgUAAAAObmV1dHJpbm9TdXBwbHkJAAPwAAAAAgkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQUAAAAPYXVjdGlvbkNvbnRyYWN0BQAAAAtib25kQXNzZXRJZAQAAAAWc3VycGx1c1dpdGhMaXF1aWRhdGlvbgkAAGUAAAACBQAAAAdzdXJwbHVzCQAD8AAAAAIJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEFAAAAE2xpcXVpZGF0aW9uQ29udHJhY3QFAAAAD25ldXRyaW5vQXNzZXRJZAMFAAAACWlzQmxvY2tlZAkAAAIAAAABAgAAAFpjb250cmFjdCBpcyBibG9ja2VkIGJ5IEVNRVJHRU5DWSBTSFVURE9XTiBhY3Rpb25zIHVudGlsbCByZWFjdGl2YXRpb24gYnkgZW1lcmdlbmN5IG9yYWNsZXMDCQAAZgAAAAIFAAAAD2F1Y3Rpb25OQkFtb3VudAkAAGgAAAACAAAAAAAAAAABBQAAAAVQQVVMSQkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABBQAAAA9hdWN0aW9uQ29udHJhY3QFAAAAD2F1Y3Rpb25OQkFtb3VudAUAAAALYm9uZEFzc2V0SWQFAAAAA25pbAMJAABnAAAAAgUAAAAWc3VycGx1c1dpdGhMaXF1aWRhdGlvbgkAAGgAAAACAAAAAAAAAAABBQAAAAVQ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", "chainId": 87, "height": 2700951, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: DXH36JkLXLUENabfWVwz39Tui5aChR58xuyueYXJWWkP Next: AsY92vFx2MsaRDFqNt14pT2Cn7rcmARse8fJNrJqSYjB Diff:
OldNewDifferences
1-{-# STDLIB_VERSION 4 #-}
1+{-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 func getNumberByKey (key) = valueOrElse(getInteger(this, key), 0)
7979 func getHeightPriceByIndexKey (index) = ((PriceIndexKey + "_") + toString(index))
8080
8181
82+func getStakingNodeByIndex (idx) = addressFromStringValue(getStringByKey(makeString(["%s%d%s", "lease", toString(idx), "nodeAddress"], SEP)))
83+
84+
85+func getReservedAmountForSponsorship () = valueOrElse(getInteger(this, makeString(["%s%s", "lease", "sponsorshipWavesReserve"], SEP)), (1000 * WAVELET))
86+
87+
8288 func getBalanceUnlockBlockKey (owner) = ("balance_unlock_block_" + owner)
89+
90+
91+func getLeaseIdKey (nodeIndex) = makeString(["%s%d%s", "lease", toString(nodeIndex), "id"], SEP)
92+
93+
94+func getLeaseAmountKey (nodeIndex) = makeString(["%s%d%s", "lease", toString(nodeIndex), "amount"], SEP)
8395
8496
8597 func minSwapAmountKEY (swapType) = (("min_" + swapType) + "_swap_amount")
222234
223235 let sIdxRandUnlockHeight = 12
224236
237+let sIdxIndex = 13
238+
239+let sIdxWithdrawTxId = 14
240+
225241 func swapKEY (userAddress,txId) = makeString(["%s%s", userAddress, txId], SEP)
226242
227243
228-func strSwapDATA (swapType,status,inAmount,price,outNetAmount,outFeeAmount,startHeight,startTimestamp,endHeight,endTimestamp,selfUnlockHeight,randUnlockHeight) = makeString(["%s%s%d%d%d%d%d%d%d%d%d%d", swapType, status, inAmount, price, outNetAmount, outFeeAmount, startHeight, startTimestamp, endHeight, endTimestamp, selfUnlockHeight, randUnlockHeight], SEP)
244+func strSwapDATA (swapType,status,inAmount,price,outNetAmount,outFeeAmount,startHeight,startTimestamp,endHeight,endTimestamp,selfUnlockHeight,randUnlockHeight,index,withdrawTxId) = makeString(["%s%s%d%d%d%d%d%d%d%d%d%d%d%s", swapType, status, inAmount, price, outNetAmount, outFeeAmount, startHeight, startTimestamp, endHeight, endTimestamp, selfUnlockHeight, randUnlockHeight, index, withdrawTxId], SEP)
229245
230246
231-func pendingSwapDATA (swapType,inAssetAmount,selfUnlockHeight) = strSwapDATA(swapType, "PENDING", toString(inAssetAmount), "0", "0", "0", toString(height), toString(lastBlock.timestamp), "0", "0", toString(selfUnlockHeight), "0")
247+func pendingSwapDATA (swapType,inAssetAmount,selfUnlockHeight) = strSwapDATA(swapType, "PENDING", toString(inAssetAmount), "0", "0", "0", toString(height), toString(lastBlock.timestamp), "0", "0", toString(selfUnlockHeight), "0", "0", "NULL")
232248
233249
234-func finishSwapDATA (dataArray,price,outNetAmount,outFeeAmount,randUnlockHeight) = strSwapDATA(dataArray[sIdxSwapType], "FINISHED", dataArray[sIdxInAmount], toString(price), toString(outNetAmount), toString(outFeeAmount), dataArray[sIdxStartHeight], dataArray[sIdxStartTimestamp], toString(height), toString(lastBlock.timestamp), dataArray[sIdxSelfUnlockHeight], toString(randUnlockHeight))
250+func finishSwapDATA (dataArray,price,outNetAmount,outFeeAmount,randUnlockHeight,index,withdrawTxId) = strSwapDATA(dataArray[sIdxSwapType], "FINISHED", dataArray[sIdxInAmount], toString(price), toString(outNetAmount), toString(outFeeAmount), dataArray[sIdxStartHeight], dataArray[sIdxStartTimestamp], toString(height), toString(lastBlock.timestamp), dataArray[sIdxSelfUnlockHeight], toString(randUnlockHeight), toString(index), withdrawTxId)
235251
236252
237253 func swapDataFailOrREAD (userAddress,swapTxId) = {
262278 }
263279
264280
281+func abs (x) = if ((0 > x))
282+ then -(x)
283+ else x
284+
285+
286+func selectNode (unleaseAmount) = {
287+ let amountToLease = ((wavesBalance(neutrinoContract).available - unleaseAmount) - getReservedAmountForSponsorship())
288+ let oldLeased0 = getNumberByKey(getLeaseAmountKey(0))
289+ let oldLeased1 = getNumberByKey(getLeaseAmountKey(1))
290+ let newLeased0 = (amountToLease + oldLeased0)
291+ let newLeased1 = (amountToLease + oldLeased1)
292+ if (if ((newLeased0 > 0))
293+ then true
294+ else (newLeased1 > 0))
295+ then {
296+ let delta0 = abs((newLeased0 - oldLeased1))
297+ let delta1 = abs((newLeased1 - oldLeased0))
298+ if ((delta1 >= delta0))
299+ then $Tuple2(0, newLeased0)
300+ else $Tuple2(1, newLeased1)
301+ }
302+ else $Tuple2(-1, 0)
303+ }
304+
305+
306+func prepareUnleaseAndLease (unleaseAmount) = {
307+ let nodeTuple = selectNode(unleaseAmount)
308+ let nodeIndex = nodeTuple._1
309+ let newLeaseAmount = nodeTuple._2
310+ if ((newLeaseAmount > 0))
311+ then {
312+ let leaseIdKey = getLeaseIdKey(nodeIndex)
313+ let oldLease = getBinary(this, leaseIdKey)
314+ let unleaseOrEmpty = if (isDefined(oldLease))
315+ then [LeaseCancel(value(oldLease))]
316+ else nil
317+ let leaseAmountKey = getLeaseAmountKey(nodeIndex)
318+ let lease = Lease(getStakingNodeByIndex(nodeIndex), newLeaseAmount)
319+ (unleaseOrEmpty ++ [lease, BinaryEntry(leaseIdKey, calculateLeaseId(lease)), IntegerEntry(getLeaseAmountKey(nodeIndex), newLeaseAmount)])
320+ }
321+ else nil
322+ }
323+
324+
265325 func commonSwap (swapType,i) = {
266326 let pmt = value(i.payments[0])
267327 let account = toString(i.caller)
275335 then minSwapAmountFAIL(swapType, minSwapAmount)
276336 else if (isBlocked)
277337 then emergencyShutdownFAIL()
278- else [IntegerEntry(totalLockedByUserKEY(swapType, account), (totalLockedByUser + pmt.amount)), IntegerEntry(getBalanceUnlockBlockKey(account), (height + balanceLockMaxInterval)), IntegerEntry(totalLockedKEY(swapType), (totalLocked + pmt.amount)), StringEntry(swapKEY(account, txId58), pendingSwapDATA(swapType, pmt.amount, selfUnlockHeight))]
338+ else {
339+ let leasePart = if ((swapType == "waves"))
340+ then prepareUnleaseAndLease(0)
341+ else nil
342+ $Tuple2(([IntegerEntry(totalLockedByUserKEY(swapType, account), (totalLockedByUser + pmt.amount)), IntegerEntry(getBalanceUnlockBlockKey(account), (height + balanceLockMaxInterval)), IntegerEntry(totalLockedKEY(swapType), (totalLocked + pmt.amount)), StringEntry(swapKEY(account, txId58), pendingSwapDATA(swapType, pmt.amount, selfUnlockHeight))] ++ leasePart), unit)
343+ }
279344 }
280345
281346
330395 then true
331396 else (outFeePart >= PAULI))
332397 then throw(((("invalid outFeePart config for " + swapType) + " swap: outFeePart=") + toString(outFeePart)))
333- else [IntegerEntry(totalLockedByUserKEY(swapType, account), (totalLockedByUser - inAmount)), IntegerEntry(totalLockedKEY(swapType), (totalLocked - inAmount)), ScriptTransfer(userAddress, outNetAmount, outAmountGrossTuple._2), ScriptTransfer(feeManagerAddress, outFeeAmount, outAmountGrossTuple._2), StringEntry(swapKEY(account, swapTxId), finishSwapDATA(dataArray, priceByIndex, outNetAmount, outFeeAmount, unlockHeight))]
398+ else {
399+ let leasePart = if (if ((swapType == "neutrino"))
400+ then (outAmountGrossTuple._1 > 0)
401+ else false)
402+ then prepareUnleaseAndLease(outAmountGrossTuple._1)
403+ else nil
404+ $Tuple2((leasePart ++ [IntegerEntry(totalLockedByUserKEY(swapType, account), (totalLockedByUser - inAmount)), IntegerEntry(totalLockedKEY(swapType), (totalLocked - inAmount)), ScriptTransfer(userAddress, outNetAmount, outAmountGrossTuple._2), ScriptTransfer(feeManagerAddress, outFeeAmount, outAmountGrossTuple._2), StringEntry(swapKEY(account, swapTxId), finishSwapDATA(dataArray, priceByIndex, outNetAmount, outFeeAmount, unlockHeight, index, toBase58String(i.transactionId)))]), unit)
405+ }
334406 }
335407
336408
378450 }
379451
380452
453+
454+@Callable(i)
455+func acceptWaves () = if ((i.caller != addressFromStringValue(auctionContract)))
456+ then throw("Currently only auction contract is allowed to call")
457+ else $Tuple2(prepareUnleaseAndLease(0), "success")
458+
459+
460+
461+@Callable(i)
462+func migrateActiveLeasings (leaseChunkTxId,chunkAmount,nodeIndex) = if ((i.callerPublicKey != nodeOracleProviderPubKey))
463+ then throw("not authorized")
464+ else {
465+ let leaseAmountKEY = getLeaseAmountKey(nodeIndex)
466+ let amountToAdd = ((wavesBalance(neutrinoContract).available + chunkAmount) - getReservedAmountForSponsorship())
467+ let oldLeasedAmount = getNumberByKey(leaseAmountKEY)
468+ let newLeaseAmount = (oldLeasedAmount + amountToAdd)
469+ let leaseIdKEY = getLeaseIdKey(nodeIndex)
470+ let oldLeaseId = getBinary(this, leaseIdKEY)
471+ let oldUnleaseOrEmpty = if (isDefined(oldLeaseId))
472+ then [LeaseCancel(value(oldLeaseId))]
473+ else nil
474+ let lease = Lease(getStakingNodeByIndex(nodeIndex), newLeaseAmount)
475+ (oldUnleaseOrEmpty ++ [LeaseCancel(fromBase58String(leaseChunkTxId)), lease, BinaryEntry(leaseIdKEY, calculateLeaseId(lease)), IntegerEntry(leaseAmountKEY, newLeaseAmount)])
476+ }
477+
478+
381479 @Verifier(tx)
382480 func verify () = {
383481 let id = toBase58String(tx.id)
391489 then 2
392490 else 0))
393491 match tx {
394- case leasingTx: LeaseCancelTransaction|LeaseTransaction =>
395- sigVerify(leasingTx.bodyBytes, leasingTx.proofs[0], nodeOracleProviderPubKey)
396492 case sponsorTx: SponsorFeeTransaction =>
397493 if (checkIsValidMinSponsoredFee(sponsorTx))
398494 then (count >= 3)
Full:
OldNewDifferences
1-{-# STDLIB_VERSION 4 #-}
1+{-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 func getNumberByKey (key) = valueOrElse(getInteger(this, key), 0)
55
66
77 func getStringByKey (key) = valueOrElse(getString(this, key), "")
88
99
1010 func getBoolByKey (key) = valueOrElse(getBoolean(this, key), false)
1111
1212
1313 func getNumberByAddressAndKey (address,key) = valueOrElse(getInteger(addressFromStringValue(address), key), 0)
1414
1515
1616 func getStringByAddressAndKey (address,key) = valueOrElse(getString(addressFromStringValue(address), key), "")
1717
1818
1919 func getBoolByAddressAndKey (address,key) = valueOrElse(getBoolean(addressFromStringValue(address), key), false)
2020
2121
2222 let pubKeyAdminsList = ["GJdLSaLiv5K7xuejac8mcRcHoyo3dPrESrvktG3a6MAR", "FWVffYr2ALmHMejZm3WqeLz6Sdym3gLFGtJn4KTwyU5x", "3Wh2LaWcb5gg7K2pPcW3Ep6EAuRBzYkAgrdpt43jTDFa", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"]
2323
2424 let SEP = "__"
2525
2626 let WAVELET = 100000000
2727
2828 let PAULI = 1000000
2929
3030 let PRICELET = 1000000
3131
3232 let DEFAULTSWAPFEE = 20000
3333
3434 let IdxNetAmount = 0
3535
3636 let IdxFeeAmount = 1
3737
3838 let IdxGrossAmount = 2
3939
4040 let NeutrinoAssetIdKey = "neutrino_asset_id"
4141
4242 let BondAssetIdKey = "bond_asset_id"
4343
4444 let AuctionContractKey = "auction_contract"
4545
4646 let LiquidationContractKey = "liquidation_contract"
4747
4848 let RPDContractKey = "rpd_contract"
4949
5050 let ContolContractKey = "control_contract"
5151
5252 let BalanceWavesLockIntervalKey = "balance_waves_lock_interval"
5353
5454 let BalanceNeutrinoLockIntervalKey = "balance_neutrino_lock_interval"
5555
5656 let MinWavesSwapAmountKey = "min_waves_swap_amount"
5757
5858 let MinNeutrinoSwapAmountKey = "min_neutrino_swap_amount"
5959
6060 let NodeOracleProviderPubKeyKey = "node_oracle_provider"
6161
6262 let NeutrinoOutFeePartKey = "neutrinoOut_swap_feePart"
6363
6464 let WavesOutFeePartKey = "wavesOut_swap_feePart"
6565
6666 let FeesManagerAddressKey = "fees_manager_address"
6767
6868 let RsaRandPublic58Key = "rand_rsa_public"
6969
7070 let PriceKey = "price"
7171
7272 let PriceIndexKey = "price_index"
7373
7474 let IsBlockedKey = "is_blocked"
7575
7676 func getPriceHistoryKey (block) = ((PriceKey + "_") + toString(block))
7777
7878
7979 func getHeightPriceByIndexKey (index) = ((PriceIndexKey + "_") + toString(index))
8080
8181
82+func getStakingNodeByIndex (idx) = addressFromStringValue(getStringByKey(makeString(["%s%d%s", "lease", toString(idx), "nodeAddress"], SEP)))
83+
84+
85+func getReservedAmountForSponsorship () = valueOrElse(getInteger(this, makeString(["%s%s", "lease", "sponsorshipWavesReserve"], SEP)), (1000 * WAVELET))
86+
87+
8288 func getBalanceUnlockBlockKey (owner) = ("balance_unlock_block_" + owner)
89+
90+
91+func getLeaseIdKey (nodeIndex) = makeString(["%s%d%s", "lease", toString(nodeIndex), "id"], SEP)
92+
93+
94+func getLeaseAmountKey (nodeIndex) = makeString(["%s%d%s", "lease", toString(nodeIndex), "amount"], SEP)
8395
8496
8597 func minSwapAmountKEY (swapType) = (("min_" + swapType) + "_swap_amount")
8698
8799
88100 func totalLockedKEY (swapType) = ("balance_lock_" + swapType)
89101
90102
91103 func totalLockedByUserKEY (swapType,owner) = makeString(["balance_lock", swapType, owner], "_")
92104
93105
94106 func balanceLockIntervalKEY (swapType) = (("balance_" + swapType) + "_lock_interval")
95107
96108
97109 func minBalanceLockIntervalKEY (swapType) = (("balance_" + swapType) + "_lock_interval_minimum")
98110
99111
100112 func outFeePartKEY (swapType) = (swapType + "Out_swap_feePart")
101113
102114
103115 func minSwapAmountREAD (swapType) = valueOrElse(getInteger(this, minSwapAmountKEY(swapType)), 0)
104116
105117
106118 func totalLockedREAD (swapType) = valueOrElse(getInteger(this, totalLockedKEY(swapType)), 0)
107119
108120
109121 func totalLockedByUserREAD (swapType,owner) = valueOrElse(getInteger(this, totalLockedByUserKEY(swapType, owner)), 0)
110122
111123
112124 func balanceLockIntervalREAD (swapType) = valueOrElse(getInteger(this, balanceLockIntervalKEY(swapType)), 1440)
113125
114126
115127 func minBalanceLockIntervalREAD (swapType) = valueOrElse(getInteger(this, minBalanceLockIntervalKEY(swapType)), 60)
116128
117129
118130 func feeManagerAddressREAD () = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(this, FeesManagerAddressKey), (FeesManagerAddressKey + " is not specified"))), (FeesManagerAddressKey + " invalid address format"))
119131
120132
121133 func convertNeutrinoToWaves (amount,price) = fraction(fraction(amount, PRICELET, price), WAVELET, PAULI)
122134
123135
124136 func convertWavesToNeutrino (amount,price) = fraction(fraction(amount, price, PRICELET), PAULI, WAVELET)
125137
126138
127139 func convertWavesToBond (amount,price) = convertWavesToNeutrino(amount, price)
128140
129141
130142 func convertJsonArrayToList (jsonArray) = split(jsonArray, ",")
131143
132144
133145 func minSwapAmountFAIL (swapType,minSwapAmount) = throw(((("The specified amount in " + swapType) + " swap is less than the required minimum of ") + toString(minSwapAmount)))
134146
135147
136148 func emergencyShutdownFAIL () = throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles")
137149
138150
139151 func priceIndexFAIL (index,priceIndex,indexHeight,unlockHeight,prevIndexHeight) = throw(((((((((("invalid price history index: index=" + toString(index)) + " priceIndex=") + toString(priceIndex)) + " indexHeight=") + toString(indexHeight)) + " unlockHeight=") + toString(unlockHeight)) + " prevIndexHeight=") + toString(prevIndexHeight)))
140152
141153
142154 let liquidationContract = getStringByKey(LiquidationContractKey)
143155
144156 let neutrinoAssetId = fromBase58String(getStringByKey(NeutrinoAssetIdKey))
145157
146158 let auctionContract = getStringByKey(AuctionContractKey)
147159
148160 let rpdContract = getStringByKey(RPDContractKey)
149161
150162 let controlContract = getStringByKey(ContolContractKey)
151163
152164 let priceIndex = getNumberByAddressAndKey(controlContract, PriceIndexKey)
153165
154166 let isBlocked = getBoolByAddressAndKey(controlContract, IsBlockedKey)
155167
156168 let nodeOracleProviderPubKey = fromBase58String(getStringByKey(NodeOracleProviderPubKeyKey))
157169
158170 let bondAssetId = fromBase58String("6nSpVyNH7yM69eg446wrQR94ipbbcmZMU1ENPwanC97g")
159171
160172 let deprecatedBondAssetId = fromBase58String("975akZBfnMj513U7MZaHKzQrmsEx5aE3wdWKTrHBhbjF")
161173
162174 let rsaPub = fromBase64String(valueOrErrorMessage(getString(this, RsaRandPublic58Key), "RSA public key has not been specified"))
163175
164176 let neutrinoContract = this
165177
166178 let currentPrice = getNumberByAddressAndKey(controlContract, PriceKey)
167179
168180 let neutrinoLockedBalance = totalLockedREAD("neutrino")
169181
170182 let wavesLockedBalance = totalLockedREAD("waves")
171183
172184 let reserve = (wavesBalance(neutrinoContract).regular - wavesLockedBalance)
173185
174186 let neutrinoSupply = (((neutrinoLockedBalance + value(assetInfo(neutrinoAssetId)).quantity) - assetBalance(neutrinoContract, neutrinoAssetId)) - assetBalance(addressFromStringValue(liquidationContract), neutrinoAssetId))
175187
176188 let surplus = (convertWavesToNeutrino(reserve, currentPrice) - neutrinoSupply)
177189
178190 let deficit = (neutrinoSupply - convertWavesToNeutrino(reserve, currentPrice))
179191
180192 func checkIsValidMinSponsoredFee (tx) = {
181193 let MINTRANSFERFEE = 100000
182194 let SponsoredFeeUpperBound = 1000
183195 let realNeutrinoFee = convertWavesToNeutrino(MINTRANSFERFEE, currentPrice)
184196 let minNeutrinoFee = (realNeutrinoFee * 2)
185197 let maxNeutrinoFee = fraction(realNeutrinoFee, SponsoredFeeUpperBound, 100)
186198 let inputFee = value(tx.minSponsoredAssetFee)
187199 if (if ((inputFee >= minNeutrinoFee))
188200 then (maxNeutrinoFee >= inputFee)
189201 else false)
190202 then (tx.assetId == neutrinoAssetId)
191203 else false
192204 }
193205
194206
195207 func getPriceHistory (block) = getNumberByAddressAndKey(controlContract, getPriceHistoryKey(block))
196208
197209
198210 func getHeightPriceByIndex (index) = getNumberByAddressAndKey(controlContract, getHeightPriceByIndexKey(index))
199211
200212
201213 let sIdxSwapType = 1
202214
203215 let sIdxStatus = 2
204216
205217 let sIdxInAmount = 3
206218
207219 let sIdxPrice = 4
208220
209221 let sIdxOutNetAmount = 5
210222
211223 let sIdxOutFeeAmount = 6
212224
213225 let sIdxStartHeight = 7
214226
215227 let sIdxStartTimestamp = 8
216228
217229 let sIdxEndHeight = 9
218230
219231 let sIdxEndTimestamp = 10
220232
221233 let sIdxSelfUnlockHeight = 11
222234
223235 let sIdxRandUnlockHeight = 12
224236
237+let sIdxIndex = 13
238+
239+let sIdxWithdrawTxId = 14
240+
225241 func swapKEY (userAddress,txId) = makeString(["%s%s", userAddress, txId], SEP)
226242
227243
228-func strSwapDATA (swapType,status,inAmount,price,outNetAmount,outFeeAmount,startHeight,startTimestamp,endHeight,endTimestamp,selfUnlockHeight,randUnlockHeight) = makeString(["%s%s%d%d%d%d%d%d%d%d%d%d", swapType, status, inAmount, price, outNetAmount, outFeeAmount, startHeight, startTimestamp, endHeight, endTimestamp, selfUnlockHeight, randUnlockHeight], SEP)
244+func strSwapDATA (swapType,status,inAmount,price,outNetAmount,outFeeAmount,startHeight,startTimestamp,endHeight,endTimestamp,selfUnlockHeight,randUnlockHeight,index,withdrawTxId) = makeString(["%s%s%d%d%d%d%d%d%d%d%d%d%d%s", swapType, status, inAmount, price, outNetAmount, outFeeAmount, startHeight, startTimestamp, endHeight, endTimestamp, selfUnlockHeight, randUnlockHeight, index, withdrawTxId], SEP)
229245
230246
231-func pendingSwapDATA (swapType,inAssetAmount,selfUnlockHeight) = strSwapDATA(swapType, "PENDING", toString(inAssetAmount), "0", "0", "0", toString(height), toString(lastBlock.timestamp), "0", "0", toString(selfUnlockHeight), "0")
247+func pendingSwapDATA (swapType,inAssetAmount,selfUnlockHeight) = strSwapDATA(swapType, "PENDING", toString(inAssetAmount), "0", "0", "0", toString(height), toString(lastBlock.timestamp), "0", "0", toString(selfUnlockHeight), "0", "0", "NULL")
232248
233249
234-func finishSwapDATA (dataArray,price,outNetAmount,outFeeAmount,randUnlockHeight) = strSwapDATA(dataArray[sIdxSwapType], "FINISHED", dataArray[sIdxInAmount], toString(price), toString(outNetAmount), toString(outFeeAmount), dataArray[sIdxStartHeight], dataArray[sIdxStartTimestamp], toString(height), toString(lastBlock.timestamp), dataArray[sIdxSelfUnlockHeight], toString(randUnlockHeight))
250+func finishSwapDATA (dataArray,price,outNetAmount,outFeeAmount,randUnlockHeight,index,withdrawTxId) = strSwapDATA(dataArray[sIdxSwapType], "FINISHED", dataArray[sIdxInAmount], toString(price), toString(outNetAmount), toString(outFeeAmount), dataArray[sIdxStartHeight], dataArray[sIdxStartTimestamp], toString(height), toString(lastBlock.timestamp), dataArray[sIdxSelfUnlockHeight], toString(randUnlockHeight), toString(index), withdrawTxId)
235251
236252
237253 func swapDataFailOrREAD (userAddress,swapTxId) = {
238254 let swapKey = swapKEY(userAddress, swapTxId)
239255 split(valueOrErrorMessage(getString(this, swapKey), ("no swap data for " + swapKey)), SEP)
240256 }
241257
242258
243259 func applyFees (amountGross,feePart) = {
244260 let feeAmount = fraction(amountGross, feePart, PAULI)
245261 [(amountGross - feeAmount), feeAmount, amountGross]
246262 }
247263
248264
249265 func randUnlockHeightOrFail (txId,rsaSig,swapType,startHeight) = {
250266 let isRsaValid = rsaVerify_16Kb(SHA256, toBytes(txId), rsaSig, rsaPub)
251267 if (!(isRsaValid))
252268 then throw("invalid RSA signature")
253269 else {
254270 let maxBalanceLockInterval = balanceLockIntervalREAD(swapType)
255271 let minBalanceLockInterval = minBalanceLockIntervalREAD(swapType)
256272 let rand = (toInt(sha256_16Kb(rsaSig)) % (maxBalanceLockInterval - minBalanceLockInterval))
257273 let randLockInterval = (minBalanceLockInterval + (if ((0 > rand))
258274 then -(rand)
259275 else rand))
260276 (startHeight + randLockInterval)
261277 }
262278 }
263279
264280
281+func abs (x) = if ((0 > x))
282+ then -(x)
283+ else x
284+
285+
286+func selectNode (unleaseAmount) = {
287+ let amountToLease = ((wavesBalance(neutrinoContract).available - unleaseAmount) - getReservedAmountForSponsorship())
288+ let oldLeased0 = getNumberByKey(getLeaseAmountKey(0))
289+ let oldLeased1 = getNumberByKey(getLeaseAmountKey(1))
290+ let newLeased0 = (amountToLease + oldLeased0)
291+ let newLeased1 = (amountToLease + oldLeased1)
292+ if (if ((newLeased0 > 0))
293+ then true
294+ else (newLeased1 > 0))
295+ then {
296+ let delta0 = abs((newLeased0 - oldLeased1))
297+ let delta1 = abs((newLeased1 - oldLeased0))
298+ if ((delta1 >= delta0))
299+ then $Tuple2(0, newLeased0)
300+ else $Tuple2(1, newLeased1)
301+ }
302+ else $Tuple2(-1, 0)
303+ }
304+
305+
306+func prepareUnleaseAndLease (unleaseAmount) = {
307+ let nodeTuple = selectNode(unleaseAmount)
308+ let nodeIndex = nodeTuple._1
309+ let newLeaseAmount = nodeTuple._2
310+ if ((newLeaseAmount > 0))
311+ then {
312+ let leaseIdKey = getLeaseIdKey(nodeIndex)
313+ let oldLease = getBinary(this, leaseIdKey)
314+ let unleaseOrEmpty = if (isDefined(oldLease))
315+ then [LeaseCancel(value(oldLease))]
316+ else nil
317+ let leaseAmountKey = getLeaseAmountKey(nodeIndex)
318+ let lease = Lease(getStakingNodeByIndex(nodeIndex), newLeaseAmount)
319+ (unleaseOrEmpty ++ [lease, BinaryEntry(leaseIdKey, calculateLeaseId(lease)), IntegerEntry(getLeaseAmountKey(nodeIndex), newLeaseAmount)])
320+ }
321+ else nil
322+ }
323+
324+
265325 func commonSwap (swapType,i) = {
266326 let pmt = value(i.payments[0])
267327 let account = toString(i.caller)
268328 let txId58 = toBase58String(i.transactionId)
269329 let minSwapAmount = minSwapAmountREAD(swapType)
270330 let totalLocked = totalLockedREAD(swapType)
271331 let totalLockedByUser = totalLockedByUserREAD(swapType, account)
272332 let balanceLockMaxInterval = balanceLockIntervalREAD(swapType)
273333 let selfUnlockHeight = (height + balanceLockMaxInterval)
274334 if ((minSwapAmount > pmt.amount))
275335 then minSwapAmountFAIL(swapType, minSwapAmount)
276336 else if (isBlocked)
277337 then emergencyShutdownFAIL()
278- else [IntegerEntry(totalLockedByUserKEY(swapType, account), (totalLockedByUser + pmt.amount)), IntegerEntry(getBalanceUnlockBlockKey(account), (height + balanceLockMaxInterval)), IntegerEntry(totalLockedKEY(swapType), (totalLocked + pmt.amount)), StringEntry(swapKEY(account, txId58), pendingSwapDATA(swapType, pmt.amount, selfUnlockHeight))]
338+ else {
339+ let leasePart = if ((swapType == "waves"))
340+ then prepareUnleaseAndLease(0)
341+ else nil
342+ $Tuple2(([IntegerEntry(totalLockedByUserKEY(swapType, account), (totalLockedByUser + pmt.amount)), IntegerEntry(getBalanceUnlockBlockKey(account), (height + balanceLockMaxInterval)), IntegerEntry(totalLockedKEY(swapType), (totalLocked + pmt.amount)), StringEntry(swapKEY(account, txId58), pendingSwapDATA(swapType, pmt.amount, selfUnlockHeight))] ++ leasePart), unit)
343+ }
279344 }
280345
281346
282347 func commonWithdraw (account,index,swapTxId,rsaSigOrUnit,i) = {
283348 let userAddress = addressFromStringValue(account)
284349 let feeManagerAddress = feeManagerAddressREAD()
285350 let dataArray = swapDataFailOrREAD(account, swapTxId)
286351 let selfUnlockHeight = parseIntValue(dataArray[sIdxSelfUnlockHeight])
287352 let swapType = dataArray[sIdxSwapType]
288353 let inAmount = parseIntValue(dataArray[sIdxInAmount])
289354 let swapStatus = dataArray[sIdxStatus]
290355 let startHeight = parseIntValue(dataArray[sIdxStartHeight])
291356 let outFeePart = valueOrElse(getInteger(this, outFeePartKEY(swapType)), DEFAULTSWAPFEE)
292357 let totalLocked = totalLockedREAD(swapType)
293358 let totalLockedByUser = totalLockedByUserREAD(swapType, account)
294359 let unlockHeight = match rsaSigOrUnit {
295360 case rsaSig: ByteVector =>
296361 randUnlockHeightOrFail(swapTxId, rsaSig, swapType, startHeight)
297362 case _: Unit =>
298363 selfUnlockHeight
299364 case _ =>
300365 throw("Match error")
301366 }
302367 let indexHeight = getHeightPriceByIndex(index)
303368 let prevIndexHeight = getHeightPriceByIndex((index - 1))
304369 let priceByIndex = getPriceHistory(indexHeight)
305370 let outAmountGrossTuple = if ((swapType == "waves"))
306371 then $Tuple2(convertWavesToNeutrino(inAmount, priceByIndex), neutrinoAssetId)
307372 else if ((swapType == "neutrino"))
308373 then $Tuple2(convertNeutrinoToWaves(inAmount, priceByIndex), unit)
309374 else throw(("Unsupported swap type " + swapType))
310375 let payoutsArray = applyFees(outAmountGrossTuple._1, outFeePart)
311376 let outNetAmount = payoutsArray[IdxNetAmount]
312377 let outFeeAmount = payoutsArray[IdxFeeAmount]
313378 if (isBlocked)
314379 then emergencyShutdownFAIL()
315380 else if ((swapStatus != "PENDING"))
316381 then throw("swap has been already processed")
317382 else if ((unlockHeight > height))
318383 then throw((("please wait for: " + toString(unlockHeight)) + " block height to withdraw funds"))
319384 else if (if (if ((index > priceIndex))
320385 then true
321386 else (unlockHeight > indexHeight))
322387 then true
323388 else if ((prevIndexHeight != 0))
324389 then (prevIndexHeight >= unlockHeight)
325390 else false)
326391 then priceIndexFAIL(index, priceIndex, indexHeight, unlockHeight, prevIndexHeight)
327392 else if ((0 >= payoutsArray[IdxGrossAmount]))
328393 then throw("balance equals zero")
329394 else if (if ((0 > outFeePart))
330395 then true
331396 else (outFeePart >= PAULI))
332397 then throw(((("invalid outFeePart config for " + swapType) + " swap: outFeePart=") + toString(outFeePart)))
333- else [IntegerEntry(totalLockedByUserKEY(swapType, account), (totalLockedByUser - inAmount)), IntegerEntry(totalLockedKEY(swapType), (totalLocked - inAmount)), ScriptTransfer(userAddress, outNetAmount, outAmountGrossTuple._2), ScriptTransfer(feeManagerAddress, outFeeAmount, outAmountGrossTuple._2), StringEntry(swapKEY(account, swapTxId), finishSwapDATA(dataArray, priceByIndex, outNetAmount, outFeeAmount, unlockHeight))]
398+ else {
399+ let leasePart = if (if ((swapType == "neutrino"))
400+ then (outAmountGrossTuple._1 > 0)
401+ else false)
402+ then prepareUnleaseAndLease(outAmountGrossTuple._1)
403+ else nil
404+ $Tuple2((leasePart ++ [IntegerEntry(totalLockedByUserKEY(swapType, account), (totalLockedByUser - inAmount)), IntegerEntry(totalLockedKEY(swapType), (totalLocked - inAmount)), ScriptTransfer(userAddress, outNetAmount, outAmountGrossTuple._2), ScriptTransfer(feeManagerAddress, outFeeAmount, outAmountGrossTuple._2), StringEntry(swapKEY(account, swapTxId), finishSwapDATA(dataArray, priceByIndex, outNetAmount, outFeeAmount, unlockHeight, index, toBase58String(i.transactionId)))]), unit)
405+ }
334406 }
335407
336408
337409 @Callable(i)
338410 func swapWavesToNeutrino () = {
339411 let pmt = value(i.payments[0])
340412 if (isDefined(pmt.assetId))
341413 then throw("Only Waves token is allowed for swapping.")
342414 else commonSwap("waves", i)
343415 }
344416
345417
346418
347419 @Callable(i)
348420 func swapNeutrinoToWaves () = {
349421 let pmt = value(i.payments[0])
350422 if ((pmt.assetId != neutrinoAssetId))
351423 then throw("Only appropriate Neutrino tokens are allowed for swapping.")
352424 else commonSwap("neutrino", i)
353425 }
354426
355427
356428
357429 @Callable(i)
358430 func withdraw (account,index,swapTxId) = commonWithdraw(account, index, swapTxId, unit, i)
359431
360432
361433
362434 @Callable(i)
363435 func withdrawRand (account,index,swapTxId,rsaSig) = commonWithdraw(account, index, swapTxId, rsaSig, i)
364436
365437
366438
367439 @Callable(i)
368440 func transferToAuction () = {
369441 let auctionNBAmount = (neutrinoSupply - assetBalance(addressFromStringValue(auctionContract), bondAssetId))
370442 let surplusWithLiquidation = (surplus - assetBalance(addressFromStringValue(liquidationContract), neutrinoAssetId))
371443 if (isBlocked)
372444 then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles")
373445 else if ((auctionNBAmount > (1 * PAULI)))
374446 then [ScriptTransfer(addressFromStringValue(auctionContract), auctionNBAmount, bondAssetId)]
375447 else if ((surplusWithLiquidation >= (1 * PAULI)))
376448 then [ScriptTransfer(addressFromStringValue(liquidationContract), surplusWithLiquidation, neutrinoAssetId)]
377449 else throw(((((((("bond were generated or do not need it. Deficit:" + toString(auctionNBAmount)) + "|") + toString(0)) + ". Surplus:") + toString(surplusWithLiquidation)) + "|") + toString(surplus)))
378450 }
379451
380452
453+
454+@Callable(i)
455+func acceptWaves () = if ((i.caller != addressFromStringValue(auctionContract)))
456+ then throw("Currently only auction contract is allowed to call")
457+ else $Tuple2(prepareUnleaseAndLease(0), "success")
458+
459+
460+
461+@Callable(i)
462+func migrateActiveLeasings (leaseChunkTxId,chunkAmount,nodeIndex) = if ((i.callerPublicKey != nodeOracleProviderPubKey))
463+ then throw("not authorized")
464+ else {
465+ let leaseAmountKEY = getLeaseAmountKey(nodeIndex)
466+ let amountToAdd = ((wavesBalance(neutrinoContract).available + chunkAmount) - getReservedAmountForSponsorship())
467+ let oldLeasedAmount = getNumberByKey(leaseAmountKEY)
468+ let newLeaseAmount = (oldLeasedAmount + amountToAdd)
469+ let leaseIdKEY = getLeaseIdKey(nodeIndex)
470+ let oldLeaseId = getBinary(this, leaseIdKEY)
471+ let oldUnleaseOrEmpty = if (isDefined(oldLeaseId))
472+ then [LeaseCancel(value(oldLeaseId))]
473+ else nil
474+ let lease = Lease(getStakingNodeByIndex(nodeIndex), newLeaseAmount)
475+ (oldUnleaseOrEmpty ++ [LeaseCancel(fromBase58String(leaseChunkTxId)), lease, BinaryEntry(leaseIdKEY, calculateLeaseId(lease)), IntegerEntry(leaseAmountKEY, newLeaseAmount)])
476+ }
477+
478+
381479 @Verifier(tx)
382480 func verify () = {
383481 let id = toBase58String(tx.id)
384482 let count = ((((if (sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(pubKeyAdminsList[0])))
385483 then 1
386484 else 0) + (if (sigVerify(tx.bodyBytes, tx.proofs[1], fromBase58String(pubKeyAdminsList[1])))
387485 then 1
388486 else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[2], fromBase58String(pubKeyAdminsList[2])))
389487 then 1
390488 else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[3], fromBase58String(pubKeyAdminsList[3])))
391489 then 2
392490 else 0))
393491 match tx {
394- case leasingTx: LeaseCancelTransaction|LeaseTransaction =>
395- sigVerify(leasingTx.bodyBytes, leasingTx.proofs[0], nodeOracleProviderPubKey)
396492 case sponsorTx: SponsorFeeTransaction =>
397493 if (checkIsValidMinSponsoredFee(sponsorTx))
398494 then (count >= 3)
399495 else false
400496 case _ =>
401497 (count >= 3)
402498 }
403499 }
404500

github/deemru/w8io/786bc32 
223.17 ms