2022.10.13 12:24 [3335838] smart account 3P5VC7EqCZ3BsTuz3QrZFpxZ9VEm5N6WHTb > SELF 0.00000000 Waves

{ "type": 13, "id": "ACwGVJnLKt4ND9CCZSDJizvVhNzb9uMGt5G7wzuSSksu", "fee": 3400000, "feeAssetId": null, "timestamp": 1665653084823, "version": 1, "sender": "3P5VC7EqCZ3BsTuz3QrZFpxZ9VEm5N6WHTb", "senderPublicKey": "ADu1XuzisH2u8YwfLFVkHDbzwtKpT376inMjiSxYeq83", "proofs": [ "TWNVqRoYDeQDDtW1CWP9RExA98H12rNkAesM6wGfgYfLkCm1eSgpx2fyfCR43DDfPcNSagoLA4yUJgpwTrtwPHC" ], "script": "base64:BgKUAQgCEgMKAQgSAwoBCBIAEgQKAgEEEgQKAgEEEgMKAQESABIECgIIARIECgIIARIECgIIARIECgIBARIDCgEBEgUKAwEIARIECgIBCBIECgIICBIECgIICBIECgIIARIAEgMKAQgSBQoDAQEBEgQKAggBEgQKAgEBEgQKAggIEgsKCQgBAQIBAggEBBIGCgQICAEIEgBcAAZzY2FsZTgAgMLXLwAMc2NhbGU4QmlnSW50CQC2AgEAgMLXLwAHc2NhbGUxOAkAtgIBAICAkLu61q3wDQAKemVyb0JpZ0ludAkAtgIBAAAABGJpZzAJALYCAQAAAARiaWcxCQC2AgEAAQAEYmlnMgkAtgIBAAIACnNsaXBwYWdlNEQJALYCAQkAZQIFBnNjYWxlOAkAaQIJAGgCBQZzY2FsZTgAAQUGc2NhbGU4AAVBbXVsdAIDMTAwAAVEY29udgIBMQADU0VQAgJfXwAFRU1QVFkCAAAKUG9vbEFjdGl2ZQABAApQb29sUHV0RGlzAAIADlBvb2xNYXRjaGVyRGlzAAMADFBvb2xTaHV0ZG93bgAEAA5pZHhQb29sQWRkcmVzcwABAAlpZHhQb29sU3QAAgAJaWR4TFBBc0lkAAMACWlkeEFtQXNJZAAEAAlpZHhQckFzSWQABQALaWR4QW10QXNEY20ABgANaWR4UHJpY2VBc0RjbQAHAAtpZHhJQW10QXNJZAAIAA1pZHhJUHJpY2VBc0lkAAkAD2lkeEZhY3RTdGFrQ250cgABABBpZHhGYWN0U2xpcHBDbnRyAAcAEWlkeEZhY3RHd3hSZXdDbnRyAAoACmZlZURlZmF1bHQJAGsDAAUFBnNjYWxlOACQTgECdDECB29yaWdWYWwNb3JpZ1NjYWxlTXVsdAkAvAIDCQC2AgEFB29yaWdWYWwFB3NjYWxlMTgJALYCAQUNb3JpZ1NjYWxlTXVsdAECZjECA3ZhbA9yZXN1bHRTY2FsZU11bHQJAKADAQkAvAIDBQN2YWwJALYCAQUPcmVzdWx0U2NhbGVNdWx0BQdzY2FsZTE4AQJ0cwMDYW10CHJlc1NjYWxlCGN1clNjYWxlCQBrAwUDYW10BQhyZXNTY2FsZQUIY3VyU2NhbGUBA2FicwEDdmFsAwkAvwICBQp6ZXJvQmlnSW50BQN2YWwJAL4CAQUDdmFsBQN2YWwBCWFic0JpZ0ludAEDdmFsAwkAvwICBQp6ZXJvQmlnSW50BQN2YWwJAL4CAQUDdmFsBQN2YWwBAmZjAAITJXNfX2ZhY3RvcnlDb250cmFjdAEDbXBrAAIUJXNfX21hbmFnZXJQdWJsaWNLZXkBBHBtcGsAAhslc19fcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkBAnBsAAIRJXMlc19fcHJpY2VfX2xhc3QBAnBoAgFoAXQJALkJAgkAzAgCAhglcyVzJWQlZF9fcHJpY2VfX2hpc3RvcnkJAMwIAgkApAMBBQFoCQDMCAIJAKQDAQUBdAUDbmlsBQNTRVABA3BhdQICdWEEdHhJZAkArAICCQCsAgIJAKwCAgILJXMlcyVzX19QX18FAnVhAgJfXwUEdHhJZAEDZ2F1AgJ1YQR0eElkCQCsAgIJAKwCAgkArAICAgslcyVzJXNfX0dfXwUCdWECAl9fBQR0eElkAQJhYQACDyVzX19hbW91bnRBc3NldAECcGEAAg4lc19fcHJpY2VBc3NldAEDYW1wAAIHJXNfX2FtcAEDYWRhAAINJXNfX2FkZG9uQWRkcgAGa2V5RmVlAgclc19fZmVlAANmZWUJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUGa2V5RmVlBQpmZWVEZWZhdWx0AQRmY2ZnAAIRJXNfX2ZhY3RvcnlDb25maWcBBG10cGsAAhglcyVzX19tYXRjaGVyX19wdWJsaWNLZXkBAnBjAgZpQW10QXMFaVByQXMJAKwCAgkArAICCQCsAgIJAKwCAgIIJWQlZCVzX18FBmlBbXRBcwICX18FBWlQckFzAghfX2NvbmZpZwEDbWJhAQViQVN0cgkArAICAiglcyVzJXNfX21hcHBpbmdzX19iYXNlQXNzZXQyaW50ZXJuYWxJZF9fBQViQVN0cgEDYXBzAAIMJXNfX3NodXRkb3duARxrZXlBbGxvd2VkTHBTdGFibGVTY3JpcHRIYXNoAAIdJXNfX2FsbG93ZWRMcFN0YWJsZVNjcmlwdEhhc2gBFmtleUZlZUNvbGxlY3RvckFkZHJlc3MAAhclc19fZmVlQ29sbGVjdG9yQWRkcmVzcwEDdG9lAwNvclYGc2VuZHJWBm1hdGNoVgkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAhFGYWlsZWQ6IG9yZFZhbGlkPQkApQMBBQNvclYCCyBzbmRyVmFsaWQ9CQClAwEFBnNlbmRyVgIMIG10Y2hyVmFsaWQ9CQClAwEFBm1hdGNoVgEDc3RyAQN2YWwEByRtYXRjaDAFA3ZhbAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEBnZhbFN0cgUHJG1hdGNoMAUGdmFsU3RyCQACAQITZmFpbCBjYXN0IHRvIFN0cmluZwEEc3RyZgIEYWRkcgNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQRhZGRyBQNrZXkJALkJAgkAzAgCAgptYW5kYXRvcnkgCQDMCAIJAKUIAQUEYWRkcgkAzAgCAgEuCQDMCAIFA2tleQkAzAgCAgwgbm90IGRlZmluZWQFA25pbAIAAQRpbnRmAgRhZGRyA2tleQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFBGFkZHIFA2tleQkAuQkCCQDMCAICCm1hbmRhdG9yeSAJAMwIAgkApQgBBQRhZGRyCQDMCAICAS4JAMwIAgUDa2V5CQDMCAICDCBub3QgZGVmaW5lZAUDbmlsAgAAA2ZjYQkBEUBleHRyTmF0aXZlKDEwNjIpAQkBBHN0cmYCBQR0aGlzCQECZmMAAAFBCQEEc3RyZgIFBHRoaXMJAQNhbXAAAQNpZ3MACQELdmFsdWVPckVsc2UCCQCbCAIFA2ZjYQkBA2FwcwAHAQJtcAAJANkEAQkBBHN0cmYCBQNmY2EJAQRtdHBrAAATZmVlQ29sbGVjdG9yQWRkcmVzcwkBEUBleHRyTmF0aXZlKDEwNjIpAQkBBHN0cmYCBQNmY2EJARZrZXlGZWVDb2xsZWN0b3JBZGRyZXNzAAEDZ3BjAAQFYW10QXMJAQRzdHJmAgUEdGhpcwkBAmFhAAQHcHJpY2VBcwkBBHN0cmYCBQR0aGlzCQECcGEABAhpUHJpY2VBcwkBBGludGYCBQNmY2EJAQNtYmEBBQdwcmljZUFzBAZpQW10QXMJAQRpbnRmAgUDZmNhCQEDbWJhAQUFYW10QXMJALUJAgkBBHN0cmYCBQNmY2EJAQJwYwIJAKQDAQUGaUFtdEFzCQCkAwEFCGlQcmljZUFzBQNTRVABA2dmYwAJALUJAgkBBHN0cmYCBQNmY2EJAQRmY2ZnAAUDU0VQAA1mYWN0b3J5Q29uZmlnCQEDZ2ZjAAAPc3Rha2luZ0NvbnRyYWN0CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQ1mYWN0b3J5Q29uZmlnBQ9pZHhGYWN0U3Rha0NudHICIEludmFsaWQgc3Rha2luZyBjb250cmFjdCBhZGRyZXNzAA9zbGlwYWdlQ29udHJhY3QJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIFDWZhY3RvcnlDb25maWcFEGlkeEZhY3RTbGlwcENudHICIEludmFsaWQgc2xpcGFnZSBjb250cmFjdCBhZGRyZXNzAAtnd3hDb250cmFjdAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgUNZmFjdG9yeUNvbmZpZwURaWR4RmFjdEd3eFJld0NudHICHEludmFsaWQgZ3d4IGNvbnRyYWN0IGFkZHJlc3MBEWRhdGFQdXRBY3Rpb25JbmZvCg1pbkFtdEFzc2V0QW10D2luUHJpY2VBc3NldEFtdAhvdXRMcEFtdAVwcmljZQpzbGlwQnlVc2VyDHNsaXBwYWdlUmVhbAh0eEhlaWdodAt0eFRpbWVzdGFtcAxzbGlwYWdlQW1BbXQMc2xpcGFnZVByQW10CQC5CQIJAMwIAgIUJWQlZCVkJWQlZCVkJWQlZCVkJWQJAMwIAgkApAMBBQ1pbkFtdEFzc2V0QW10CQDMCAIJAKQDAQUPaW5QcmljZUFzc2V0QW10CQDMCAIJAKQDAQUIb3V0THBBbXQJAMwIAgkApAMBBQVwcmljZQkAzAgCCQCkAwEFCnNsaXBCeVVzZXIJAMwIAgkApAMBBQxzbGlwcGFnZVJlYWwJAMwIAgkApAMBBQh0eEhlaWdodAkAzAgCCQCkAwEFC3R4VGltZXN0YW1wCQDMCAIJAKQDAQUMc2xpcGFnZUFtQW10CQDMCAIJAKQDAQUMc2xpcGFnZVByQW10BQNuaWwFA1NFUAERZGF0YUdldEFjdGlvbkluZm8GDm91dEFtdEFzc2V0QW10EG91dFByaWNlQXNzZXRBbXQHaW5McEFtdAVwcmljZQh0eEhlaWdodAt0eFRpbWVzdGFtcAkAuQkCCQDMCAICDCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEFDm91dEFtdEFzc2V0QW10CQDMCAIJAKQDAQUQb3V0UHJpY2VBc3NldEFtdAkAzAgCCQCkAwEFB2luTHBBbXQJAMwIAgkApAMBBQVwcmljZQkAzAgCCQCkAwEFCHR4SGVpZ2h0CQDMCAIJAKQDAQULdHhUaW1lc3RhbXAFA25pbAUDU0VQAQ1nZXRBY2NCYWxhbmNlAQdhc3NldElkAwkAAAIFB2Fzc2V0SWQCBVdBVkVTCAkA7wcBBQR0aGlzCWF2YWlsYWJsZQkA8AcCBQR0aGlzCQDZBAEFB2Fzc2V0SWQBBGNwYmkCCHByQW10WDE4CGFtQW10WDE4CQC8AgMFCHByQW10WDE4BQdzY2FsZTE4BQhhbUFtdFgxOAEDdmFkAwJBMQJBMghzbGlwcGFnZQQEZGlmZgkAvAIDCQC4AgIFAkExBQJBMgUMc2NhbGU4QmlnSW50BQJBMgQEcGFzcwkAvwICCQC4AgIFCHNsaXBwYWdlCQEDYWJzAQUEZGlmZgUKemVyb0JpZ0ludAMJAQEhAQUEcGFzcwkAAgEJAKwCAgIKQmlnIHNscGc6IAkApgMBBQRkaWZmCQCUCgIFBHBhc3MJAJkDAQkAzAgCBQJBMQkAzAgCBQJBMgUDbmlsAQJ2ZAMCRDECRDAEc2xwZwQEZGlmZgkAvAIDBQJEMAUMc2NhbGU4QmlnSW50BQJEMQQEZmFpbAkAvwICBQRzbHBnBQRkaWZmAwMFBGZhaWwGCQC/AgIFAkQwBQJEMQkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKYDAQUCRDACASAJAKYDAQUCRDECASAJAKYDAQUEZGlmZgIBIAkApgMBBQRzbHBnBQRmYWlsAQNwY3AECmFtQXNzZXREY20KcHJBc3NldERjbQVhbUFtdAVwckFtdAQLYW10QXNBbXRYMTgJAQJ0MQIFBWFtQW10BQphbUFzc2V0RGNtBApwckFzQW10WDE4CQECdDECBQVwckFtdAUKcHJBc3NldERjbQkBBGNwYmkCBQpwckFzQW10WDE4BQthbXRBc0FtdFgxOAEKY2FsY1ByaWNlcwMFYW1BbXQFcHJBbXQFbHBBbXQEA2NmZwkBA2dwYwAECGFtdEFzRGNtCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUDY2ZnBQtpZHhBbXRBc0RjbQQHcHJBc0RjbQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFA2NmZwUNaWR4UHJpY2VBc0RjbQQIcHJpY2VYMTgJAQNwY3AEBQhhbXRBc0RjbQUHcHJBc0RjbQUFYW1BbXQFBXByQW10BAhhbUFtdFgxOAkBAnQxAgUFYW1BbXQFCGFtdEFzRGNtBAhwckFtdFgxOAkBAnQxAgUFcHJBbXQFB3ByQXNEY20ECGxwQW10WDE4CQECdDECBQVscEFtdAUGc2NhbGU4BA1scFBySW5BbUFzWDE4CQEEY3BiaQIFCGFtQW10WDE4BQhscEFtdFgxOAQNbHBQckluUHJBc1gxOAkBBGNwYmkCBQhwckFtdFgxOAUIbHBBbXRYMTgJAMwIAgUIcHJpY2VYMTgJAMwIAgUNbHBQckluQW1Bc1gxOAkAzAgCBQ1scFBySW5QckFzWDE4BQNuaWwBD2NhbGN1bGF0ZVByaWNlcwMFYW1BbXQFcHJBbXQFbHBBbXQEAXAJAQpjYWxjUHJpY2VzAwUFYW1BbXQFBXByQW10BQVscEFtdAkAzAgCCQECZjECCQCRAwIFAXAAAAUGc2NhbGU4CQDMCAIJAQJmMQIJAJEDAgUBcAABBQZzY2FsZTgJAMwIAgkBAmYxAgkAkQMCBQFwAAIFBnNjYWxlOAUDbmlsAQd0YWtlRmVlAQZhbW91bnQECWZlZUFtb3VudAkAawMFBmFtb3VudAUDZmVlBQZzY2FsZTgJAJQKAgkAZQIFBmFtb3VudAUJZmVlQW1vdW50BQlmZWVBbW91bnQBA2VnbwQGdHhJZDU4CnBtdEFzc2V0SWQIcG10THBBbXQLdXNlckFkZHJlc3MEA2NmZwkBA2dwYwAEBGxwSWQJAJEDAgUDY2ZnBQlpZHhMUEFzSWQEBGFtSWQJAJEDAgUDY2ZnBQlpZHhBbUFzSWQEBHBySWQJAJEDAgUDY2ZnBQlpZHhQckFzSWQEBWFtRGNtCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUDY2ZnBQtpZHhBbXRBc0RjbQQFcHJEY20JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQNjZmcFDWlkeFByaWNlQXNEY20EA3N0cwkAkQMCBQNjZmcFCWlkeFBvb2xTdAQHbHBFbWlzcwgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBCQDZBAEFBGxwSWQCC1dyb25nIExQIGlkCHF1YW50aXR5AwkBAiE9AgUEbHBJZAUKcG10QXNzZXRJZAkAAgECD1dyb25nIHBtdCBhc3NldAQJYW1CYWxhbmNlCQENZ2V0QWNjQmFsYW5jZQEFBGFtSWQEDGFtQmFsYW5jZVgxOAkBAnQxAgUJYW1CYWxhbmNlBQVhbURjbQQJcHJCYWxhbmNlCQENZ2V0QWNjQmFsYW5jZQEFBHBySWQEDHByQmFsYW5jZVgxOAkBAnQxAgUJcHJCYWxhbmNlBQVwckRjbQQLY3VyUHJpY2VYMTgJAQRjcGJpAgUMcHJCYWxhbmNlWDE4BQxhbUJhbGFuY2VYMTgECGN1clByaWNlCQECZjECBQtjdXJQcmljZVgxOAUGc2NhbGU4BAtwbXRMcEFtdFgxOAkBAnQxAgUIcG10THBBbXQFBnNjYWxlOAQKbHBFbWlzc1gxOAkBAnQxAgUHbHBFbWlzcwUGc2NhbGU4BAtvdXRBbUFtdFgxOAkAvAIDBQxhbUJhbGFuY2VYMTgFC3BtdExwQW10WDE4BQpscEVtaXNzWDE4BAtvdXRQckFtdFgxOAkAvAIDBQxwckJhbGFuY2VYMTgFC3BtdExwQW10WDE4BQpscEVtaXNzWDE4BAhvdXRBbUFtdAkBAmYxAgULb3V0QW1BbXRYMTgFBWFtRGNtBAhvdXRQckFtdAkBAmYxAgULb3V0UHJBbXRYMTgFBXByRGNtBAVzdGF0ZQMJAAACBQZ0eElkNTgCAAUDbmlsCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFC3VzZXJBZGRyZXNzBQhvdXRBbUFtdAMJAAACBQRhbUlkAgVXQVZFUwUEdW5pdAkA2QQBBQRhbUlkCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFC3VzZXJBZGRyZXNzBQhvdXRQckFtdAMJAAACBQRwcklkAgVXQVZFUwUEdW5pdAkA2QQBBQRwcklkCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQNnYXUCCQClCAEFC3VzZXJBZGRyZXNzBQZ0eElkNTgJARFkYXRhR2V0QWN0aW9uSW5mbwYFCG91dEFtQW10BQhvdXRQckFtdAUIcG10THBBbXQFCGN1clByaWNlBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECcGwABQhjdXJQcmljZQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAnBoAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUIY3VyUHJpY2UFA25pbAkAnAoKBQhvdXRBbUFtdAUIb3V0UHJBbXQFBGFtSWQFBHBySWQFCWFtQmFsYW5jZQUJcHJCYWxhbmNlBQdscEVtaXNzBQtjdXJQcmljZVgxOAUDc3RzBQVzdGF0ZQEDZXBvDQZ0eElkNTgIc2xpcHBhZ2UHaW5BbUFtdAZpbkFtSWQHaW5QckFtdAZpblBySWQLdXNlckFkZHJlc3MGaXNFdmFsBmVtaXRMcAppc09uZUFzc2V0EHZhbGlkYXRlU2xpcHBhZ2UGcG10QW10BXBtdElkBANjZmcJAQNncGMABARscElkCQDZBAEJAJEDAgUDY2ZnBQlpZHhMUEFzSWQEB2FtSWRTdHIJAJEDAgUDY2ZnBQlpZHhBbUFzSWQEB3BySWRTdHIJAJEDAgUDY2ZnBQlpZHhQckFzSWQECWluQW1JZFN0cgkAkQMCBQNjZmcFC2lkeElBbXRBc0lkBAlpblBySWRTdHIJAJEDAgUDY2ZnBQ1pZHhJUHJpY2VBc0lkBAZhbXREY20JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQNjZmcFC2lkeEFtdEFzRGNtBAhwcmljZURjbQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFA2NmZwUNaWR4UHJpY2VBc0RjbQQDc3RzCQCRAwIFA2NmZwUJaWR4UG9vbFN0BARscEVtCAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFBGxwSWQCCFdyIGxwIGFzCHF1YW50aXR5BAlhbUJhbGFuY2UDBQZpc0V2YWwJAQ1nZXRBY2NCYWxhbmNlAQUHYW1JZFN0cgMDBQppc09uZUFzc2V0CQAAAgUFcG10SWQFB2FtSWRTdHIHCQBlAgkBDWdldEFjY0JhbGFuY2UBBQdhbUlkU3RyBQZwbXRBbXQDBQppc09uZUFzc2V0CQENZ2V0QWNjQmFsYW5jZQEFB2FtSWRTdHIJAGUCCQENZ2V0QWNjQmFsYW5jZQEFB2FtSWRTdHIFB2luQW1BbXQECXByQmFsYW5jZQMFBmlzRXZhbAkBDWdldEFjY0JhbGFuY2UBBQdwcklkU3RyAwMFCmlzT25lQXNzZXQJAAACBQVwbXRJZAUHcHJJZFN0cgcJAGUCCQENZ2V0QWNjQmFsYW5jZQEFB3BySWRTdHIFBnBtdEFtdAMFCmlzT25lQXNzZXQJAQ1nZXRBY2NCYWxhbmNlAQUHcHJJZFN0cgkAZQIJAQ1nZXRBY2NCYWxhbmNlAQUHcHJJZFN0cgUHaW5QckFtdAQPaW5BbUFzc2V0QW10WDE4CQECdDECBQdpbkFtQW10BQZhbXREY20ED2luUHJBc3NldEFtdFgxOAkBAnQxAgUHaW5QckFtdAUIcHJpY2VEY20EDHVzZXJQcmljZVgxOAkBBGNwYmkCBQ9pblByQXNzZXRBbXRYMTgFD2luQW1Bc3NldEFtdFgxOAQMYW1CYWxhbmNlWDE4CQECdDECBQlhbUJhbGFuY2UFBmFtdERjbQQMcHJCYWxhbmNlWDE4CQECdDECBQlwckJhbGFuY2UFCHByaWNlRGNtBAFyAwkAAAIFBGxwRW0AAAQLY3VyUHJpY2VYMTgFCnplcm9CaWdJbnQEC3NsaXBwYWdlWDE4BQp6ZXJvQmlnSW50BAhscEFtdFgxOAkAdgYJALkCAgUPaW5BbUFzc2V0QW10WDE4BQ9pblByQXNzZXRBbXRYMTgAAAkAtgIBAAUAAQAABQRET1dOCQCXCgUJAQJmMQIFCGxwQW10WDE4BQZzY2FsZTgJAQJmMQIFD2luQW1Bc3NldEFtdFgxOAUGYW10RGNtCQECZjECBQ9pblByQXNzZXRBbXRYMTgFCHByaWNlRGNtCQEEY3BiaQIJALcCAgUMcHJCYWxhbmNlWDE4BQ9pblByQXNzZXRBbXRYMTgJALcCAgUMYW1CYWxhbmNlWDE4BQ9pbkFtQXNzZXRBbXRYMTgFC3NsaXBwYWdlWDE4BAtjdXJQcmljZVgxOAkBBGNwYmkCBQxwckJhbGFuY2VYMTgFDGFtQmFsYW5jZVgxOAQPc2xpcHBhZ2VSZWFsWDE4CQC8AgMJAQNhYnMBCQC4AgIFC2N1clByaWNlWDE4BQx1c2VyUHJpY2VYMTgFB3NjYWxlMTgFC2N1clByaWNlWDE4BAtzbGlwcGFnZVgxOAkBAnQxAgUIc2xpcHBhZ2UFBnNjYWxlOAMDAwUQdmFsaWRhdGVTbGlwcGFnZQkBAiE9AgULY3VyUHJpY2VYMTgFCnplcm9CaWdJbnQHCQC/AgIFD3NsaXBwYWdlUmVhbFgxOAULc2xpcHBhZ2VYMTgHCQACAQkArAICCQCsAgIJAKwCAgIPUHJpY2Ugc2xpcHBhZ2UgCQCmAwEFD3NsaXBwYWdlUmVhbFgxOAIDID4gCQCmAwEFC3NsaXBwYWdlWDE4BA1scEVtaXNzaW9uWDE4CQECdDECBQRscEVtBQZzY2FsZTgECnByVmlhQW1YMTgJALwCAwUPaW5BbUFzc2V0QW10WDE4BQtjdXJQcmljZVgxOAUHc2NhbGUxOAQKYW1WaWFQclgxOAkAvAIDBQ9pblByQXNzZXRBbXRYMTgFB3NjYWxlMTgFC2N1clByaWNlWDE4BAxleHBlY3RlZEFtdHMDCQC/AgIFCnByVmlhQW1YMTgFD2luUHJBc3NldEFtdFgxOAkAlAoCBQphbVZpYVByWDE4BQ9pblByQXNzZXRBbXRYMTgJAJQKAgUPaW5BbUFzc2V0QW10WDE4BQpwclZpYUFtWDE4BBFleHBBbXRBc3NldEFtdFgxOAgFDGV4cGVjdGVkQW10cwJfMQQTZXhwUHJpY2VBc3NldEFtdFgxOAgFDGV4cGVjdGVkQW10cwJfMgQIbHBBbXRYMTgJALwCAwUNbHBFbWlzc2lvblgxOAUTZXhwUHJpY2VBc3NldEFtdFgxOAUMcHJCYWxhbmNlWDE4CQCXCgUJAQJmMQIFCGxwQW10WDE4BQZzY2FsZTgJAQJmMQIFEWV4cEFtdEFzc2V0QW10WDE4BQZhbXREY20JAQJmMQIFE2V4cFByaWNlQXNzZXRBbXRYMTgFCHByaWNlRGNtBQtjdXJQcmljZVgxOAULc2xpcHBhZ2VYMTgECWNhbGNMcEFtdAgFAXICXzEEDmNhbGNBbUFzc2V0UG10CAUBcgJfMgQOY2FsY1ByQXNzZXRQbXQIBQFyAl8zBAhjdXJQcmljZQkBAmYxAggFAXICXzQFBnNjYWxlOAQMc2xpcHBhZ2VDYWxjCQECZjECCAUBcgJfNQUGc2NhbGU4AwkAZwIAAAUJY2FsY0xwQW10CQACAQIHTFAgPD0gMAQJZW1pdExwQW10AwkBASEBBQZlbWl0THAAAAUJY2FsY0xwQW10BAZhbURpZmYJAGUCBQdpbkFtQW10BQ5jYWxjQW1Bc3NldFBtdAQGcHJEaWZmCQBlAgUHaW5QckFtdAUOY2FsY1ByQXNzZXRQbXQEDSR0MDE2MzUxMTY2OTYDAwUKaXNPbmVBc3NldAkAAAIFBXBtdElkBQdhbUlkU3RyBwkAlAoCBQZwbXRBbXQAAAMDBQppc09uZUFzc2V0CQAAAgUFcG10SWQFB3BySWRTdHIHCQCUCgIAAAUGcG10QW10CQCUCgIFDmNhbGNBbUFzc2V0UG10BQ5jYWxjUHJBc3NldFBtdAQKd3JpdGVBbUFtdAgFDSR0MDE2MzUxMTY2OTYCXzEECndyaXRlUHJBbXQIBQ0kdDAxNjM1MTE2Njk2Al8yBAtjb21tb25TdGF0ZQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAnBsAAUIY3VyUHJpY2UJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJwaAIFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFCGN1clByaWNlCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQNwYXUCBQt1c2VyQWRkcmVzcwUGdHhJZDU4CQERZGF0YVB1dEFjdGlvbkluZm8KBQp3cml0ZUFtQW10BQp3cml0ZVByQW10BQllbWl0THBBbXQFCGN1clByaWNlBQhzbGlwcGFnZQUMc2xpcHBhZ2VDYWxjBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQZhbURpZmYFBnByRGlmZgUDbmlsCQCfCg0FCWNhbGNMcEFtdAUJZW1pdExwQW10BQhjdXJQcmljZQUJYW1CYWxhbmNlBQlwckJhbGFuY2UFBGxwRW0FBGxwSWQFA3N0cwULY29tbW9uU3RhdGUFBmFtRGlmZgUGcHJEaWZmBQZpbkFtSWQFBmluUHJJZAEDbW9hAQVvcmRlcgQDY2ZnCQEDZ3BjAAQHYW10QXNJZAkAkQMCBQNjZmcFCWlkeEFtQXNJZAQGcHJBc0lkCQCRAwIFA2NmZwUJaWR4UHJBc0lkBANzdHMJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQNjZmcFCWlkeFBvb2xTdAQIYW10QXNEY20JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQNjZmcFC2lkeEFtdEFzRGNtBAdwckFzRGNtCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUDY2ZnBQ1pZHhQcmljZUFzRGNtBA9hY2NBbXRBc0JhbGFuY2UJAQ1nZXRBY2NCYWxhbmNlAQUHYW10QXNJZAQOYWNjUHJBc0JhbGFuY2UJAQ1nZXRBY2NCYWxhbmNlAQUGcHJBc0lkBAtjdXJQcmljZVgxOAMJAAACCAUFb3JkZXIJb3JkZXJUeXBlBQNCdXkJAQNwY3AEBQhhbXRBc0RjbQUHcHJBc0RjbQkAZAIFD2FjY0FtdEFzQmFsYW5jZQgFBW9yZGVyBmFtb3VudAUOYWNjUHJBc0JhbGFuY2UJAQNwY3AEBQhhbXRBc0RjbQUHcHJBc0RjbQkAZQIFD2FjY0FtdEFzQmFsYW5jZQgFBW9yZGVyBmFtb3VudAUOYWNjUHJBc0JhbGFuY2UECGN1clByaWNlCQECZjECBQtjdXJQcmljZVgxOAUGc2NhbGU4AwMDCQEDaWdzAAYJAAACBQNzdHMFDlBvb2xNYXRjaGVyRGlzBgkAAAIFA3N0cwUMUG9vbFNodXRkb3duCQACAQINQWRtaW4gYmxvY2tlZAQKb3JBbXRBc3NldAgIBQVvcmRlcglhc3NldFBhaXILYW1vdW50QXNzZXQECm9yQW10QXNTdHIDCQAAAgUKb3JBbXRBc3NldAUEdW5pdAIFV0FWRVMJANgEAQkBBXZhbHVlAQUKb3JBbXRBc3NldAQJb3JQckFzc2V0CAgFBW9yZGVyCWFzc2V0UGFpcgpwcmljZUFzc2V0BAlvclByQXNTdHIDCQAAAgUJb3JQckFzc2V0BQR1bml0AgVXQVZFUwkA2AQBCQEFdmFsdWUBBQlvclByQXNzZXQDAwkBAiE9AgUKb3JBbXRBc1N0cgUHYW10QXNJZAYJAQIhPQIFCW9yUHJBc1N0cgUGcHJBc0lkCQACAQIJV3IgYXNzZXRzBApvcmRlclByaWNlCAUFb3JkZXIFcHJpY2UECHByaWNlRGNtCQBrAwUGc2NhbGU4BQdwckFzRGNtBQhhbXRBc0RjbQQOY2FzdE9yZGVyUHJpY2UJAQJ0cwMFCm9yZGVyUHJpY2UFBnNjYWxlOAUIcHJpY2VEY20EEWlzT3JkZXJQcmljZVZhbGlkAwkAAAIIBQVvcmRlcglvcmRlclR5cGUFA0J1eQkAZwIFCGN1clByaWNlBQ5jYXN0T3JkZXJQcmljZQkAZwIFDmNhc3RPcmRlclByaWNlBQhjdXJQcmljZQYBAmNnAQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIKMSBwbW50IGV4cAQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAAECnBtdEFzc2V0SWQJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAQGcG10QW10CAUDcG10BmFtb3VudAQBcgkBA2VnbwQJANgEAQgFAWkNdHJhbnNhY3Rpb25JZAkA2AQBBQpwbXRBc3NldElkBQZwbXRBbXQIBQFpBmNhbGxlcgQIb3V0QW1BbXQIBQFyAl8xBAhvdXRQckFtdAgFAXICXzIEA3N0cwkBDXBhcnNlSW50VmFsdWUBCAUBcgJfOQQFc3RhdGUIBQFyA18xMAMDCQEDaWdzAAYJAAACBQNzdHMFDFBvb2xTaHV0ZG93bgkAAgEJAKwCAgIPQWRtaW4gYmxvY2tlZDogCQCkAwEFA3N0cwkAlwoFBQhvdXRBbUFtdAUIb3V0UHJBbXQFBnBtdEFtdAUKcG10QXNzZXRJZAUFc3RhdGUBAmNwCgZjYWxsZXIEdHhJZAdhbUFzUG10B3ByQXNQbXQIc2xpcHBhZ2UGZW1pdExwCmlzT25lQXNzZXQQdmFsaWRhdGVTbGlwcGFnZQZwbXRBbXQFcG10SWQEAXIJAQNlcG8NBQR0eElkBQhzbGlwcGFnZQgJAQV2YWx1ZQEFB2FtQXNQbXQGYW1vdW50CAkBBXZhbHVlAQUHYW1Bc1BtdAdhc3NldElkCAkBBXZhbHVlAQUHcHJBc1BtdAZhbW91bnQICQEFdmFsdWUBBQdwckFzUG10B2Fzc2V0SWQFBmNhbGxlcgkAAAIFBHR4SWQCAAUGZW1pdExwBQppc09uZUFzc2V0BRB2YWxpZGF0ZVNsaXBwYWdlBQZwbXRBbXQFBXBtdElkBANzdHMJAQ1wYXJzZUludFZhbHVlAQgFAXICXzgDAwMJAQNpZ3MABgkAAAIFA3N0cwUKUG9vbFB1dERpcwYJAAACBQNzdHMFDFBvb2xTaHV0ZG93bgkAAgEJAKwCAgIIQmxvY2tlZDoJAKQDAQUDc3RzBQFyAQRnZXREAQJ4cAQBbgUEYmlnMgQDeHAwCQCRAwIFAnhwAAAEA3hwMQkAkQMCBQJ4cAABBAphUHJlY2lzaW9uCQCnAwEFBUFtdWx0BAFhCQC5AgIJAKcDAQUBQQUKYVByZWNpc2lvbgQBcwkAtwICBQN4cDAFA3hwMQMJAAACBQFzBQRiaWcwBQRiaWcwBANhbm4JALkCAgUBYQUBbgQLeHAwX3hwMV9uX24JALkCAgkAuQICCQC5AgIFA3hwMAUDeHAxBQFuBQFuBBBhbm5fc19hUHJlY2lzaW9uCQC6AgIJALkCAgUDYW5uBQFzBQphUHJlY2lzaW9uBA5hbm5fYVByZWNpc2lvbgkAuAICBQNhbm4FCmFQcmVjaXNpb24EAm4xCQC3AgIFAW4FBGJpZzEKAQRjYWxjAgNhY2MDY3VyBA0kdDAyMTI0ODIxMjY4BQNhY2MEAWQIBQ0kdDAyMTI0ODIxMjY4Al8xBAVmb3VuZAgFDSR0MDIxMjQ4MjEyNjgCXzIDCQECIT0CBQVmb3VuZAUEdW5pdAUDYWNjBAJkcAkAugICCQC5AgIJALkCAgUBZAUBZAUBZAULeHAwX3hwMV9uX24EBWROZXh0CQC6AgIJALkCAgkAtwICBRBhbm5fc19hUHJlY2lzaW9uCQC5AgIFAmRwBQFuBQFkCQC3AgIJALoCAgkAuQICBQ5hbm5fYVByZWNpc2lvbgUBZAUKYVByZWNpc2lvbgkAuQICBQJuMQUCZHAEBWREaWZmCQEJYWJzQmlnSW50AQkAuAICBQVkTmV4dAkBBXZhbHVlAQUBZAMJAMACAgUEYmlnMQUFZERpZmYJAJQKAgUFZE5leHQFA2N1cgkAlAoCBQVkTmV4dAUEdW5pdAQDYXJyCQDMCAIAAAkAzAgCAAEJAMwIAgACCQDMCAIAAwkAzAgCAAQJAMwIAgAFCQDMCAIABgkAzAgCAAcJAMwIAgAICQDMCAIACQkAzAgCAAoJAMwIAgALCQDMCAIADAkAzAgCAA0JAMwIAgAOBQNuaWwEDSR0MDIxNjg5MjE3MzYKAAIkbAUDYXJyCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlAoCBQFzBQR1bml0CgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQRjYWxjAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxNQkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwQBZAgFDSR0MDIxNjg5MjE3MzYCXzEEBWZvdW5kCAUNJHQwMjE2ODkyMTczNgJfMgMJAQIhPQIFBWZvdW5kBQR1bml0BQFkCQACAQkArAICAhlEIGNhbGN1bGF0aW9uIGVycm9yLCBEID0gCQCmAwEFAWQBBWdldFlEAwJ4cAFpAUQEAW4FBGJpZzIEAXgJAJEDAgUCeHADCQAAAgUBaQAAAAEAAAQKYVByZWNpc2lvbgkApwMBBQVBbXVsdAQBYQkAuQICCQCnAwEFAUEFCmFQcmVjaXNpb24EAXMFAXgEA2FubgkAuQICBQFhBQFuBAFjCQC6AgIJALkCAgkAuQICCQC6AgIJALkCAgUBRAUBRAkAuQICBQF4BQFuBQFEBQphUHJlY2lzaW9uCQC5AgIFA2FubgUBbgQBYgkAuAICCQC3AgIFAXMJALoCAgkAuQICBQFEBQphUHJlY2lzaW9uBQNhbm4FAUQKAQRjYWxjAgNhY2MDY3VyBA0kdDAyMjIzNjIyMjU2BQNhY2MEAXkIBQ0kdDAyMjIzNjIyMjU2Al8xBAVmb3VuZAgFDSR0MDIyMjM2MjIyNTYCXzIDCQECIT0CBQVmb3VuZAUEdW5pdAUDYWNjBAV5TmV4dAkAugICCQC3AgIJALkCAgUBeQUBeQUBYwkAtwICCQC5AgIFBGJpZzIFAXkFAWIEBXlEaWZmCQEJYWJzQmlnSW50AQkAuAICBQV5TmV4dAkBBXZhbHVlAQUBeQMJAMACAgUEYmlnMQUFeURpZmYJAJQKAgUFeU5leHQFA2N1cgkAlAoCBQV5TmV4dAUEdW5pdAQDYXJyCQDMCAIAAAkAzAgCAAEJAMwIAgACCQDMCAIAAwkAzAgCAAQJAMwIAgAFCQDMCAIABgkAzAgCAAcJAMwIAgAICQDMCAIACQkAzAgCAAoJAMwIAgALCQDMCAIADAkAzAgCAA0JAMwIAgAOBQNuaWwEDSR0MDIyNTYzMjI2MTAKAAIkbAUDYXJyCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlAoCBQFEBQR1bml0CgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQRjYWxjAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxNQkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwQBeQgFDSR0MDIyNTYzMjI2MTACXzEEBWZvdW5kCAUNJHQwMjI1NjMyMjYxMAJfMgMJAQIhPQIFBWZvdW5kBQR1bml0BQF5CQACAQkArAICAhlZIGNhbGN1bGF0aW9uIGVycm9yLCBZID0gCQCmAwEFAXkBDWNhbGNQdXRPbmVUa24ECXBtdEFtdFJhdwpwbXRBc3NldElkC3VzZXJBZGRyZXNzBHR4SWQECnBvb2xDb25maWcJAQNncGMABARhbUlkCQCRAwIFCnBvb2xDb25maWcFCWlkeEFtQXNJZAQEcHJJZAkAkQMCBQpwb29sQ29uZmlnBQlpZHhQckFzSWQEBGxwSWQJAJEDAgUKcG9vbENvbmZpZwUJaWR4TFBBc0lkBAZhbXREY20JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQpwb29sQ29uZmlnBQtpZHhBbXRBc0RjbQQIcHJpY2VEY20JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQpwb29sQ29uZmlnBQ1pZHhQcmljZUFzRGNtBA9scEFzc2V0RW1pc3Npb24JALYCAQgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBCQDZBAEFBGxwSWQCEGludmFsaWQgbHAgYXNzZXQIcXVhbnRpdHkEDWNoZWNoRW1pc3Npb24DCQC/AgIFD2xwQXNzZXRFbWlzc2lvbgUEYmlnMAYJAAIBAiJpbml0aWFsIGRlcG9zaXQgcmVxdWlyZXMgYWxsIGNvaW5zAwkAAAIFDWNoZWNoRW1pc3Npb24FDWNoZWNoRW1pc3Npb24ECWFtQmFsYW5jZQkBDWdldEFjY0JhbGFuY2UBBQRhbUlkBAlwckJhbGFuY2UJAQ1nZXRBY2NCYWxhbmNlAQUEcHJJZAQNJHQwMjMzNjkyMzgzMQMJAAACBQR0eElkAgAJAJQKAgUJYW1CYWxhbmNlBQlwckJhbGFuY2UDCQAAAgUKcG10QXNzZXRJZAUEYW1JZAMJAGYCBQlwbXRBbXRSYXcFCWFtQmFsYW5jZQkAAgECFmludmFsaWQgcGF5bWVudCBhbW91bnQJAJQKAgkAZQIFCWFtQmFsYW5jZQUJcG10QW10UmF3BQlwckJhbGFuY2UDCQAAAgUKcG10QXNzZXRJZAUEcHJJZAMJAGYCBQlwbXRBbXRSYXcFCXByQmFsYW5jZQkAAgECFmludmFsaWQgcGF5bWVudCBhbW91bnQJAJQKAgUJYW1CYWxhbmNlCQBlAgUJcHJCYWxhbmNlBQlwbXRBbXRSYXcJAAIBAhB3cm9uZyBwbXRBc3NldElkBAxhbUJhbGFuY2VPbGQIBQ0kdDAyMzM2OTIzODMxAl8xBAxwckJhbGFuY2VPbGQIBQ0kdDAyMzM2OTIzODMxAl8yBA0kdDAyMzgzNzI0MDEzAwkAAAIFCnBtdEFzc2V0SWQFBGFtSWQJAJQKAgUJcG10QW10UmF3AAADCQAAAgUKcG10QXNzZXRJZAUEcHJJZAkAlAoCAAAFCXBtdEFtdFJhdwkAAgECD2ludmFsaWQgcGF5bWVudAQLYW1BbW91bnRSYXcIBQ0kdDAyMzgzNzI0MDEzAl8xBAtwckFtb3VudFJhdwgFDSR0MDIzODM3MjQwMTMCXzIECGFtQW1vdW50CAkBB3Rha2VGZWUBBQthbUFtb3VudFJhdwJfMQQIcHJBbW91bnQICQEHdGFrZUZlZQEFC3ByQW1vdW50UmF3Al8xBAlmZWVBbW91bnQICQEHdGFrZUZlZQEFCXBtdEFtdFJhdwJfMgQMYW1CYWxhbmNlTmV3CQBkAgUMYW1CYWxhbmNlT2xkBQhhbUFtb3VudAQMcHJCYWxhbmNlTmV3CQBkAgUMcHJCYWxhbmNlT2xkBQhwckFtb3VudAQCRDAJAQRnZXREAQkAzAgCCQC2AgEFDGFtQmFsYW5jZU9sZAkAzAgCCQC2AgEFDHByQmFsYW5jZU9sZAUDbmlsBAJEMQkBBGdldEQBCQDMCAIJALYCAQUMYW1CYWxhbmNlTmV3CQDMCAIJALYCAQUMcHJCYWxhbmNlTmV3BQNuaWwEBmNoZWNrRAMJAL8CAgUCRDEFAkQwBgkBBXRocm93AAMJAAACBQZjaGVja0QFBmNoZWNrRAQIbHBBbW91bnQJALwCAwUPbHBBc3NldEVtaXNzaW9uCQC4AgIFAkQxBQJEMAUCRDAECGN1clByaWNlCQECZjECCQEEY3BiaQIJAQJ0MQIFDHByQmFsYW5jZU5ldwUIcHJpY2VEY20JAQJ0MQIFDGFtQmFsYW5jZU5ldwUGYW10RGNtBQZzY2FsZTgEC2NvbW1vblN0YXRlCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECcGwABQhjdXJQcmljZQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAnBoAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUIY3VyUHJpY2UJAMwIAgkBC1N0cmluZ0VudHJ5AgkBA3BhdQIFC3VzZXJBZGRyZXNzBQR0eElkCQERZGF0YVB1dEFjdGlvbkluZm8KBQthbUFtb3VudFJhdwULcHJBbW91bnRSYXcJAKADAQUIbHBBbW91bnQFCGN1clByaWNlAAAAAAUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAAAAAAFA25pbAQOcG9vbFByb3BvcnRpb24JAGsDBQxwckJhbGFuY2VPbGQFBnNjYWxlOAUMYW1CYWxhbmNlT2xkBA9hbW91bnRBc3NldFBhcnQJAGsDBQlwbXRBbXRSYXcFBnNjYWxlOAkAZAIFDnBvb2xQcm9wb3J0aW9uBQZzY2FsZTgEDnByaWNlQXNzZXRQYXJ0CQBlAgUJcG10QW10UmF3BQ9hbW91bnRBc3NldFBhcnQECWxwQW10Qm90aAkAvAIDBQ9scEFzc2V0RW1pc3Npb24JALYCAQUOcHJpY2VBc3NldFBhcnQJALYCAQUMcHJCYWxhbmNlT2xkBAVib251cwkAoAMBCQC8AgMJALgCAgUIbHBBbW91bnQFCWxwQW10Qm90aAUMc2NhbGU4QmlnSW50BQlscEFtdEJvdGgJAJYKBAkAoAMBBQhscEFtb3VudAULY29tbW9uU3RhdGUFCWZlZUFtb3VudAUFYm9udXMJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BE2dldE9uZVRrblYySW50ZXJuYWwGCm91dEFzc2V0SWQMbWluT3V0QW1vdW50CHBheW1lbnRzBmNhbGxlcgxvcmlnaW5DYWxsZXINdHJhbnNhY3Rpb25JZAMJAQIhPQIJAJADAQUIcGF5bWVudHMAAQkAAgECCzEgcG1udCBleHBkBApwb29sQ29uZmlnCQEDZ3BjAAQEbHBJZAkAkQMCBQpwb29sQ29uZmlnBQlpZHhMUEFzSWQEBGFtSWQJAJEDAgUKcG9vbENvbmZpZwUJaWR4QW1Bc0lkBARwcklkCQCRAwIFCnBvb2xDb25maWcFCWlkeFByQXNJZAQKYW1EZWNpbWFscwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCnBvb2xDb25maWcFC2lkeEFtdEFzRGNtBApwckRlY2ltYWxzCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUKcG9vbENvbmZpZwUNaWR4UHJpY2VBc0RjbQQKcG9vbFN0YXR1cwkAkQMCBQpwb29sQ29uZmlnBQlpZHhQb29sU3QEC3VzZXJBZGRyZXNzAwkAAAIFBmNhbGxlcgUEdGhpcwUMb3JpZ2luQ2FsbGVyBQZjYWxsZXIEA3BtdAkBBXZhbHVlAQkAkQMCBQhwYXltZW50cwAABApwbXRBc3NldElkCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQEBnBtdEFtdAgFA3BtdAZhbW91bnQDCQBmAgCAlOvcAwUGcG10QW10CQACAQINTWluIHBtdCAxMCBMUAQGdHhJZDU4CQDYBAEFDXRyYW5zYWN0aW9uSWQDCQECIT0CBQRscElkCQDYBAEFCnBtdEFzc2V0SWQJAAIBAghXcm9uZyBMUAQJYW1CYWxhbmNlCQENZ2V0QWNjQmFsYW5jZQEFBGFtSWQECXByQmFsYW5jZQkBDWdldEFjY0JhbGFuY2UBBQRwcklkBA0kdDAyNjI1NjI2MzY0CgABQAkA/AcEBQR0aGlzAhNnZXRPbmVUa25WMlJFQURPTkxZCQDMCAIFCm91dEFzc2V0SWQJAMwIAgUGcG10QW10BQNuaWwFA25pbAMJAAECBQFAAgooSW50LCBJbnQpBQFACQACAQkArAICCQADAQUBQAIfIGNvdWxkbid0IGJlIGNhc3QgdG8gKEludCwgSW50KQQIdG90YWxHZXQIBQ0kdDAyNjI1NjI2MzY0Al8xBAlmZWVBbW91bnQIBQ0kdDAyNjI1NjI2MzY0Al8yBAt0b3RhbEFtb3VudAMDCQBmAgUMbWluT3V0QW1vdW50AAAJAGYCBQxtaW5PdXRBbW91bnQFCHRvdGFsR2V0BwkAAgEJALkJAgkAzAgCAh9hbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUMbWluT3V0QW1vdW50BQNuaWwCAAUIdG90YWxHZXQEDSR0MDI2NTUxMjY4NTgDCQAAAgUKb3V0QXNzZXRJZAUEYW1JZAkAlgoEBQt0b3RhbEFtb3VudAAACQBlAgkAZQIFCWFtQmFsYW5jZQULdG90YWxBbW91bnQFCWZlZUFtb3VudAUJcHJCYWxhbmNlAwkAAAIFCm91dEFzc2V0SWQFBHBySWQJAJYKBAAABQt0b3RhbEFtb3VudAUJYW1CYWxhbmNlCQBlAgkAZQIFCXByQmFsYW5jZQULdG90YWxBbW91bnQFCWZlZUFtb3VudAkAAgECFGludmFsaWQgb3V0IGFzc2V0IGlkBAVvdXRBbQgFDSR0MDI2NTUxMjY4NTgCXzEEBW91dFByCAUNJHQwMjY1NTEyNjg1OAJfMgQMYW1CYWxhbmNlTmV3CAUNJHQwMjY1NTEyNjg1OAJfMwQMcHJCYWxhbmNlTmV3CAUNJHQwMjY1NTEyNjg1OAJfNAQIY3VyUHJYMTgJAQRjcGJpAgkBAnQxAgUMcHJCYWxhbmNlTmV3BQpwckRlY2ltYWxzCQECdDECBQxhbUJhbGFuY2VOZXcFCmFtRGVjaW1hbHMEBWN1clByCQECZjECBQhjdXJQclgxOAUGc2NhbGU4BBFvdXRBc3NldElkT3JXYXZlcwMJAAACBQpvdXRBc3NldElkAgVXQVZFUwUEdW5pdAkA2QQBBQpvdXRBc3NldElkBBBzZW5kRmVlVG9NYXRjaGVyAwkAZgIFCWZlZUFtb3VudAAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFE2ZlZUNvbGxlY3RvckFkZHJlc3MFCWZlZUFtb3VudAURb3V0QXNzZXRJZE9yV2F2ZXMFA25pbAUDbmlsBAVzdGF0ZQkAzggCCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFC3VzZXJBZGRyZXNzBQt0b3RhbEFtb3VudAURb3V0QXNzZXRJZE9yV2F2ZXMJAMwIAgkBC1N0cmluZ0VudHJ5AgkBA2dhdQIJAKUIAQULdXNlckFkZHJlc3MFBnR4SWQ1OAkBEWRhdGFHZXRBY3Rpb25JbmZvBgUFb3V0QW0FBW91dFByBQZwbXRBbXQFBWN1clByBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECcGwABQVjdXJQcgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAnBoAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUFY3VyUHIFA25pbAUQc2VuZEZlZVRvTWF0Y2hlcgMJAAACBQVzdGF0ZQUFc3RhdGUEBGJ1cm4JAPwHBAUDZmNhAgRidXJuCQDMCAIFBnBtdEFtdAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQpwbXRBc3NldElkBQZwbXRBbXQFA25pbAMJAAACBQRidXJuBQRidXJuCQCUCgIFBXN0YXRlBQt0b3RhbEFtb3VudAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgEBbQAEByRtYXRjaDAJAKIIAQkBA21wawADCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwCQDZBAEFAXMDCQABAgUHJG1hdGNoMAIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yAQJwbQAEByRtYXRjaDAJAKIIAQkBBHBtcGsAAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkA2QQBBQFzAwkAAQIFByRtYXRjaDACBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgACcGQJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAECbW0BAWkEByRtYXRjaDAJAQFtAAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAJwawUHJG1hdGNoMAMJAAACCAUBaQ9jYWxsZXJQdWJsaWNLZXkFAnBrBgUCcGQDCQABAgUHJG1hdGNoMAIEVW5pdAMJAAACCAUBaQZjYWxsZXIFBHRoaXMGBQJwZAkAAgECC01hdGNoIGVycm9yGgFpAQtjb25zdHJ1Y3RvcgECZmMEAWMJAQJtbQEFAWkDCQAAAgUBYwUBYwkAzAgCCQELU3RyaW5nRW50cnkCCQECZmMABQJmYwUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCnNldE1hbmFnZXIBF3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5BAFjCQECbW0BBQFpAwkAAAIFAWMFAWMEAmNtCQDZBAEFF3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5AwkAAAIFAmNtBQJjbQkAzAgCCQELU3RyaW5nRW50cnkCCQEEcG1wawAFF3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEOY29uZmlybU1hbmFnZXIABAFwCQECcG0ABANocG0DCQEJaXNEZWZpbmVkAQUBcAYJAAIBAhJObyBwZW5kaW5nIG1hbmFnZXIDCQAAAgUDaHBtBQNocG0EA2NwbQMJAAACCAUBaQ9jYWxsZXJQdWJsaWNLZXkJAQV2YWx1ZQEFAXAGCQACAQIbWW91IGFyZSBub3QgcGVuZGluZyBtYW5hZ2VyAwkAAAIFA2NwbQUDY3BtCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQNtcGsACQDYBAEJAQV2YWx1ZQEFAXAJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBBHBtcGsABQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEDcHV0AgRzbGlwCWF1dG9TdGFrZQQHZmFjdENmZwkBA2dmYwAEC3N0YWtpbmdDbnRyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQdmYWN0Q2ZnBQ9pZHhGYWN0U3Rha0NudHICCldyIHN0IGFkZHIECHNsaXBDbnRyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQdmYWN0Q2ZnBRBpZHhGYWN0U2xpcHBDbnRyAgpXciBzbCBhZGRyAwkAZgIAAAUEc2xpcAkAAgECDldyb25nIHNsaXBwYWdlAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwACCQACAQIMMiBwbW50cyBleHBkBAFlCQECY3AKCQClCAEIBQFpBmNhbGxlcgkA2AQBCAUBaQ10cmFuc2FjdGlvbklkCQEPQXR0YWNoZWRQYXltZW50AggJAQV2YWx1ZQEJAJEDAggFAWkIcGF5bWVudHMAAAdhc3NldElkCAkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAkAkQMCCAUBaQhwYXltZW50cwABBQRzbGlwBgcGAAACAAQJZW1pdExwQW10CAUBZQJfMgQJbHBBc3NldElkCAUBZQJfNwQFc3RhdGUIBQFlAl85BAZhbURpZmYIBQFlA18xMAQGcHJEaWZmCAUBZQNfMTEEBGFtSWQIBQFlA18xMgQEcHJJZAgFAWUDXzEzBAFyCQD8BwQFA2ZjYQIEZW1pdAkAzAgCBQllbWl0THBBbXQFA25pbAUDbmlsAwkAAAIFAXIFAXIEAmVsBAckbWF0Y2gwBQFyAwkAAQIFByRtYXRjaDACB0FkZHJlc3MEBmxlZ2FjeQUHJG1hdGNoMAkA/AcEBQZsZWdhY3kCBGVtaXQJAMwIAgUJZW1pdExwQW10BQNuaWwFA25pbAUEdW5pdAMJAAACBQJlbAUCZWwEAnNhAwkAZgIFBmFtRGlmZgAACQD8BwQFCHNsaXBDbnRyAgNwdXQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUEYW1JZAUGYW1EaWZmBQNuaWwFA25pbAMJAAACBQJzYQUCc2EEAnNwAwkAZgIFBnByRGlmZgAACQD8BwQFCHNsaXBDbnRyAgNwdXQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUEcHJJZAUGcHJEaWZmBQNuaWwFA25pbAMJAAACBQJzcAUCc3AECGxwVHJuc2ZyAwUJYXV0b1N0YWtlBAJzcwkA/AcEBQtzdGFraW5nQ250cgIFc3Rha2UFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUJbHBBc3NldElkBQllbWl0THBBbXQFA25pbAMJAAACBQJzcwUCc3MFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFCWVtaXRMcEFtdAUJbHBBc3NldElkBQNuaWwJAM4IAgUFc3RhdGUFCGxwVHJuc2ZyCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBC3B1dE9uZVRrblYyAgxtaW5PdXRBbW91bnQJYXV0b1N0YWtlAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQILMSBwbW50IGV4cGQECnBvb2xDb25maWcJAQNncGMABARhbUlkCQCRAwIFCnBvb2xDb25maWcFCWlkeEFtQXNJZAQEcHJJZAkAkQMCBQpwb29sQ29uZmlnBQlpZHhQckFzSWQEBGxwSWQJANkEAQkAkQMCBQpwb29sQ29uZmlnBQlpZHhMUEFzSWQECmFtRGVjaW1hbHMJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQpwb29sQ29uZmlnBQtpZHhBbXRBc0RjbQQKcHJEZWNpbWFscwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCnBvb2xDb25maWcFDWlkeFByaWNlQXNEY20EC3VzZXJBZGRyZXNzAwkAAAIIBQFpBmNhbGxlcgUEdGhpcwgFAWkMb3JpZ2luQ2FsbGVyCAUBaQZjYWxsZXIEA3BtdAkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAABApwbXRBc3NldElkCQDYBAEJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAQGcG10QW10CAUDcG10BmFtb3VudAMJAGYCAICt4gQFBnBtdEFtdAkAAgECDVdyb25nIHBtdCBhbXQEDSR0MDMxNzM1MzE4NjAJAQ1jYWxjUHV0T25lVGtuBAUGcG10QW10BQpwbXRBc3NldElkCQClCAEFC3VzZXJBZGRyZXNzCQDYBAEIBQFpDXRyYW5zYWN0aW9uSWQEB2VzdGltTFAIBQ0kdDAzMTczNTMxODYwAl8xBAVzdGF0ZQgFDSR0MDMxNzM1MzE4NjACXzIECWZlZUFtb3VudAgFDSR0MDMxNzM1MzE4NjACXzMECWVtaXRMcEFtdAMDCQBmAgUMbWluT3V0QW1vdW50AAAJAGYCBQxtaW5PdXRBbW91bnQFB2VzdGltTFAHCQACAQkAuQkCCQDMCAICH2Ftb3VudCB0byByZWNlaXZlIGlzIGxlc3MgdGhhbiAJAMwIAgkApAMBBQxtaW5PdXRBbW91bnQFA25pbAIABQdlc3RpbUxQBAFlCQD8BwQFA2ZjYQIEZW1pdAkAzAgCBQllbWl0THBBbXQFA25pbAUDbmlsAwkAAAIFAWUFAWUEAmVsBAckbWF0Y2gwBQFlAwkAAQIFByRtYXRjaDACB0FkZHJlc3MEBmxlZ2FjeQUHJG1hdGNoMAkA/AcEBQZsZWdhY3kCBGVtaXQJAMwIAgUJZW1pdExwQW10BQNuaWwFA25pbAUEdW5pdAMJAAACBQJlbAUCZWwECGxwVHJuc2ZyAwUJYXV0b1N0YWtlBAJzcwkA/AcEBQ9zdGFraW5nQ29udHJhY3QCBXN0YWtlBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFBGxwSWQFCWVtaXRMcEFtdAUDbmlsAwkAAAIFAnNzBQJzcwUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgUJZW1pdExwQW10BQRscElkBQNuaWwEEHNlbmRGZWVUb01hdGNoZXIDCQBmAgUJZmVlQW1vdW50AAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUTZmVlQ29sbGVjdG9yQWRkcmVzcwUJZmVlQW1vdW50CQDZBAEFCnBtdEFzc2V0SWQFA25pbAUDbmlsCQCUCgIJAM4IAgkAzggCBQVzdGF0ZQUIbHBUcm5zZnIFEHNlbmRGZWVUb01hdGNoZXIFCWVtaXRMcEFtdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQpwdXRGb3JGcmVlAQdtYXhTbHBnAwkAZgIAAAUHbWF4U2xwZwkAAgECCldyb25nIHNscGcDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAIJAAIBAgwyIHBtbnRzIGV4cGQEBmVzdFB1dAkBAmNwCgkApQgBCAUBaQZjYWxsZXIJANgEAQgFAWkNdHJhbnNhY3Rpb25JZAkBD0F0dGFjaGVkUGF5bWVudAIICQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAgJAQV2YWx1ZQEJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQJAJEDAggFAWkIcGF5bWVudHMAAQUHbWF4U2xwZwcHBgAAAgAIBQZlc3RQdXQCXzkBaQEDZ2V0AAQBcgkBAmNnAQUBaQQJb3V0QW10QW10CAUBcgJfMQQIb3V0UHJBbXQIBQFyAl8yBAZwbXRBbXQIBQFyAl8zBApwbXRBc3NldElkCAUBcgJfNAQFc3RhdGUIBQFyAl81BAFiCQD8BwQFA2ZjYQIEYnVybgkAzAgCBQZwbXRBbXQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUKcG10QXNzZXRJZAUGcG10QW10BQNuaWwDCQAAAgUBYgUBYgUFc3RhdGUJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQELZ2V0T25lVGtuVjICCm91dEFzc2V0SWQMbWluT3V0QW1vdW50BA0kdDAzNDA0MzM0MTk4CQETZ2V0T25lVGtuVjJJbnRlcm5hbAYFCm91dEFzc2V0SWQFDG1pbk91dEFtb3VudAgFAWkIcGF5bWVudHMIBQFpBmNhbGxlcggFAWkMb3JpZ2luQ2FsbGVyCAUBaQ10cmFuc2FjdGlvbklkBAVzdGF0ZQgFDSR0MDM0MDQzMzQxOTgCXzEEC3RvdGFsQW1vdW50CAUNJHQwMzQwNDMzNDE5OAJfMgkAlAoCBQVzdGF0ZQULdG90YWxBbW91bnQBaQETZ2V0T25lVGtuVjJSRUFET05MWQIKb3V0QXNzZXRJZA1scEFzc2V0QW1vdW50BApwb29sQ29uZmlnCQEDZ3BjAAQEYW1JZAkAkQMCBQpwb29sQ29uZmlnBQlpZHhBbUFzSWQEBHBySWQJAJEDAgUKcG9vbENvbmZpZwUJaWR4UHJBc0lkBARscElkCQCRAwIFCnBvb2xDb25maWcFCWlkeExQQXNJZAQCeHAJAMwIAgkAtgIBCQENZ2V0QWNjQmFsYW5jZQEFBGFtSWQJAMwIAgkAtgIBCQENZ2V0QWNjQmFsYW5jZQEFBHBySWQFA25pbAQKbHBFbWlzc2lvbgkAtgIBCAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEJANkEAQUEbHBJZAIQaW52YWxpZCBscCBhc3NldAhxdWFudGl0eQQCRDAJAQRnZXREAQUCeHAEAkQxCQC4AgIFAkQwCQC8AgMJALYCAQUNbHBBc3NldEFtb3VudAUCRDAFCmxwRW1pc3Npb24EBWluZGV4AwkAAAIFCm91dEFzc2V0SWQFBGFtSWQAAAMJAAACBQpvdXRBc3NldElkBQRwcklkAAEJAAIBAhRpbnZhbGlkIG91dCBhc3NldCBpZAQEbmV3WQkBBWdldFlEAwUCeHAFBWluZGV4BQJEMQQCZHkJALgCAgkAkQMCBQJ4cAUFaW5kZXgFBG5ld1kEC3RvdGFsR2V0UmF3CQCgAwEJALgCAgUCZHkFBGJpZzEEDSR0MDM0OTc3MzUwMjYJAQd0YWtlRmVlAQULdG90YWxHZXRSYXcECHRvdGFsR2V0CAUNJHQwMzQ5NzczNTAyNgJfMQQJZmVlQW1vdW50CAUNJHQwMzQ5NzczNTAyNgJfMgkAlAoCBQNuaWwJAJQKAgUIdG90YWxHZXQFCWZlZUFtb3VudAFpARxnZXRPbmVUa25WMldpdGhCb251c1JFQURPTkxZAgpvdXRBc3NldElkDWxwQXNzZXRBbW91bnQECnBvb2xDb25maWcJAQNncGMABARhbUlkCQCRAwIFCnBvb2xDb25maWcFCWlkeEFtQXNJZAQEcHJJZAkAkQMCBQpwb29sQ29uZmlnBQlpZHhQckFzSWQEBGxwSWQJAJEDAgUKcG9vbENvbmZpZwUJaWR4TFBBc0lkBAlhbUJhbGFuY2UJAQ1nZXRBY2NCYWxhbmNlAQUEYW1JZAQJcHJCYWxhbmNlCQENZ2V0QWNjQmFsYW5jZQEFBHBySWQEDSR0MDM1MzcxMzU0ODYKAAFACQD8BwQFBHRoaXMCE2dldE9uZVRrblYyUkVBRE9OTFkJAMwIAgUKb3V0QXNzZXRJZAkAzAgCBQ1scEFzc2V0QW1vdW50BQNuaWwFA25pbAMJAAECBQFAAgooSW50LCBJbnQpBQFACQACAQkArAICCQADAQUBQAIfIGNvdWxkbid0IGJlIGNhc3QgdG8gKEludCwgSW50KQQIdG90YWxHZXQIBQ0kdDAzNTM3MTM1NDg2Al8xBAlmZWVBbW91bnQIBQ0kdDAzNTM3MTM1NDg2Al8yBAFyCQEDZWdvBAIABQRscElkBQ1scEFzc2V0QW1vdW50BQR0aGlzBAhvdXRBbUFtdAgFAXICXzEECG91dFByQW10CAUBcgJfMgQOc3VtT2ZHZXRBc3NldHMJAGQCBQhvdXRBbUFtdAUIb3V0UHJBbXQEBWJvbnVzCQBrAwkAZQIFCHRvdGFsR2V0BQ5zdW1PZkdldEFzc2V0cwUGc2NhbGU4BQ5zdW1PZkdldEFzc2V0cwkAlAoCBQNuaWwJAJUKAwUIdG90YWxHZXQFCWZlZUFtb3VudAUFYm9udXMBaQEJZ2V0Tm9MZXNzAhJub0xlc3NUaGVuQW10QXNzZXQUbm9MZXNzVGhlblByaWNlQXNzZXQEAXIJAQJjZwEFAWkECG91dEFtQW10CAUBcgJfMQQIb3V0UHJBbXQIBQFyAl8yBAZwbXRBbXQIBQFyAl8zBApwbXRBc3NldElkCAUBcgJfNAQFc3RhdGUIBQFyAl81AwkAZgIFEm5vTGVzc1RoZW5BbXRBc3NldAUIb3V0QW1BbXQJAAIBCQCsAgIJAKwCAgkArAICAglGYWlsZWQ6ICAJAKQDAQUIb3V0QW1BbXQCAyA8IAkApAMBBRJub0xlc3NUaGVuQW10QXNzZXQDCQBmAgUUbm9MZXNzVGhlblByaWNlQXNzZXQFCG91dFByQW10CQACAQkArAICCQCsAgIJAKwCAgIIRmFpbGVkOiAJAKQDAQUIb3V0UHJBbXQCAyA8IAkApAMBBRRub0xlc3NUaGVuUHJpY2VBc3NldAQUYnVybkxQQXNzZXRPbkZhY3RvcnkJAPwHBAUDZmNhAgRidXJuCQDMCAIFBnBtdEFtdAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQpwbXRBc3NldElkBQZwbXRBbXQFA25pbAMJAAACBRRidXJuTFBBc3NldE9uRmFjdG9yeQUUYnVybkxQQXNzZXRPbkZhY3RvcnkFBXN0YXRlCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDXVuc3Rha2VBbmRHZXQBBmFtb3VudAQNY2hlY2tQYXltZW50cwMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECDU5vIHBtbnRzIGV4cGQGAwkAAAIFDWNoZWNrUGF5bWVudHMFDWNoZWNrUGF5bWVudHMEA2NmZwkBA2dwYwAECmZhY3RvcnlDZmcJAQNnZmMABAlscEFzc2V0SWQJANkEAQkAkQMCBQNjZmcFCWlkeExQQXNJZAQHc3Rha2luZwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgUKZmFjdG9yeUNmZwUPaWR4RmFjdFN0YWtDbnRyAgpXciBzdCBhZGRyBAp1bnN0YWtlSW52CQD8BwQFB3N0YWtpbmcCB3Vuc3Rha2UJAMwIAgkA2AQBBQlscEFzc2V0SWQJAMwIAgUGYW1vdW50BQNuaWwFA25pbAMJAAACBQp1bnN0YWtlSW52BQp1bnN0YWtlSW52BAFyCQEDZWdvBAkA2AQBCAUBaQ10cmFuc2FjdGlvbklkCQDYBAEFCWxwQXNzZXRJZAUGYW1vdW50CAUBaQZjYWxsZXIEA3N0cwkBDXBhcnNlSW50VmFsdWUBCAUBcgJfOQQFc3RhdGUIBQFyA18xMAQBdgMDCQEDaWdzAAYJAAACBQNzdHMFDFBvb2xTaHV0ZG93bgkAAgEJAKwCAgIJQmxvY2tlZDogCQCkAwEFA3N0cwYDCQAAAgUBdgUBdgQFYnVybkEJAPwHBAUDZmNhAgRidXJuCQDMCAIFBmFtb3VudAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQlscEFzc2V0SWQFBmFtb3VudAUDbmlsAwkAAAIFBWJ1cm5BBQVidXJuQQUFc3RhdGUJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEVdW5zdGFrZUFuZEdldE9uZVRrblYyAw11bnN0YWtlQW1vdW50Cm91dEFzc2V0SWQMbWluT3V0QW1vdW50BA1jaGVja1BheW1lbnRzAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQINTm8gcG1udHMgZXhwZAYDCQAAAgUNY2hlY2tQYXltZW50cwUNY2hlY2tQYXltZW50cwQDY2ZnCQEDZ3BjAAQKZmFjdG9yeUNmZwkBA2dmYwAECWxwQXNzZXRJZAkA2QQBCQCRAwIFA2NmZwUJaWR4TFBBc0lkBAdzdGFraW5nCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQpmYWN0b3J5Q2ZnBQ9pZHhGYWN0U3Rha0NudHICCldyIHN0IGFkZHIECnVuc3Rha2VJbnYJAPwHBAUHc3Rha2luZwIHdW5zdGFrZQkAzAgCCQDYBAEFCWxwQXNzZXRJZAkAzAgCBQ11bnN0YWtlQW1vdW50BQNuaWwFA25pbAMJAAACBQp1bnN0YWtlSW52BQp1bnN0YWtlSW52BA0kdDAzNzc5MzM3OTgxCQETZ2V0T25lVGtuVjJJbnRlcm5hbAYFCm91dEFzc2V0SWQFDG1pbk91dEFtb3VudAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUJbHBBc3NldElkBQ11bnN0YWtlQW1vdW50BQNuaWwIBQFpBmNhbGxlcggFAWkMb3JpZ2luQ2FsbGVyCAUBaQ10cmFuc2FjdGlvbklkBAVzdGF0ZQgFDSR0MDM3NzkzMzc5ODECXzEEC3RvdGFsQW1vdW50CAUNJHQwMzc3OTMzNzk4MQJfMgkAlAoCBQVzdGF0ZQULdG90YWxBbW91bnQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEccHV0T25lVGtuVjJXaXRoQm9udXNSRUFET05MWQIQcGF5bWVudEFtb3VudFJhdw5wYXltZW50QXNzZXRJZAQKcG9vbENvbmZpZwkBA2dwYwAEBGFtSWQJAJEDAgUKcG9vbENvbmZpZwUJaWR4QW1Bc0lkBARwcklkCQCRAwIFCnBvb2xDb25maWcFCWlkeFByQXNJZAQEbHBJZAkAkQMCBQpwb29sQ29uZmlnBQlpZHhMUEFzSWQEDSR0MDM4MjQwMzgzMzcJAQ1jYWxjUHV0T25lVGtuBAUQcGF5bWVudEFtb3VudFJhdwUOcGF5bWVudEFzc2V0SWQCAAIABAhscEFtb3VudAgFDSR0MDM4MjQwMzgzMzcCXzEEBXN0YXRlCAUNJHQwMzgyNDAzODMzNwJfMgQJZmVlQW1vdW50CAUNJHQwMzgyNDAzODMzNwJfMwQFYm9udXMIBQ0kdDAzODI0MDM4MzM3Al80CQCUCgIFA25pbAkAlQoDBQhscEFtb3VudAUJZmVlQW1vdW50BQVib251cwFpAQhhY3RpdmF0ZQIIYW10QXNTdHIHcHJBc1N0cgMJAQIhPQIJAKUIAQgFAWkGY2FsbGVyCQClCAEFA2ZjYQkAAgECBmRlbmllZAkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhYQAFCGFtdEFzU3RyCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJwYQAFB3ByQXNTdHIFA25pbAIHc3VjY2VzcwFpAQRzZXRTAgFrAXYDCQECIT0CCQClCAEIBQFpBmNhbGxlcgkBBHN0cmYCBQR0aGlzCQEDYWRhAAUCcGQJAMwIAgkBC1N0cmluZ0VudHJ5AgUBawUBdgUDbmlsAWkBBHNldEkCAWsBdgMJAQIhPQIJAKUIAQgFAWkGY2FsbGVyCQEEc3RyZgIFBHRoaXMJAQNhZGEABQJwZAkAzAgCCQEMSW50ZWdlckVudHJ5AgUBawUBdgUDbmlsAWkBHGdldFBvb2xDb25maWdXcmFwcGVyUkVBRE9OTFkACQCUCgIFA25pbAkBA2dwYwABaQEcZ2V0QWNjQmFsYW5jZVdyYXBwZXJSRUFET05MWQEHYXNzZXRJZAkAlAoCBQNuaWwJAQ1nZXRBY2NCYWxhbmNlAQUHYXNzZXRJZAFpARljYWxjUHJpY2VzV3JhcHBlclJFQURPTkxZAwVhbUFtdAVwckFtdAVscEFtdAQCcHIJAQpjYWxjUHJpY2VzAwUFYW1BbXQFBXByQW10BQVscEFtdAkAlAoCBQNuaWwJAMwIAgkApgMBCQCRAwIFAnByAAAJAMwIAgkApgMBCQCRAwIFAnByAAEJAMwIAgkApgMBCQCRAwIFAnByAAIFA25pbAFpARZmcm9tWDE4V3JhcHBlclJFQURPTkxZAgN2YWwMcmVzU2NhbGVNdWx0CQCUCgIFA25pbAkBAmYxAgkApwMBBQN2YWwFDHJlc1NjYWxlTXVsdAFpARR0b1gxOFdyYXBwZXJSRUFET05MWQIHb3JpZ1ZhbA1vcmlnU2NhbGVNdWx0CQCUCgIFA25pbAkApgMBCQECdDECBQdvcmlnVmFsBQ1vcmlnU2NhbGVNdWx0AWkBHmNhbGNQcmljZUJpZ0ludFdyYXBwZXJSRUFET05MWQIIcHJBbXRYMTgIYW1BbXRYMTgJAJQKAgUDbmlsCQCmAwEJAQRjcGJpAgkApwMBBQhwckFtdFgxOAkApwMBBQhhbUFtdFgxOAFpASNlc3RpbWF0ZVB1dE9wZXJhdGlvbldyYXBwZXJSRUFET05MWQkGdHhJZDU4CHNsaXBwYWdlB2luQW1BbXQGaW5BbUlkB2luUHJBbXQGaW5QcklkB3VzckFkZHIGaXNFdmFsBmVtaXRMcAkAlAoCBQNuaWwJAQNlcG8NBQZ0eElkNTgFCHNsaXBwYWdlBQdpbkFtQW10BQZpbkFtSWQFB2luUHJBbXQFBmluUHJJZAUHdXNyQWRkcgUGaXNFdmFsBQZlbWl0THAGBwAAAgABaQEjZXN0aW1hdGVHZXRPcGVyYXRpb25XcmFwcGVyUkVBRE9OTFkEBnR4SWQ1OAdwbXRBc0lkCHBtdExwQW10B3VzckFkZHIEAXIJAQNlZ28EBQZ0eElkNTgFB3BtdEFzSWQFCHBtdExwQW10CQERQGV4dHJOYXRpdmUoMTA2MikBBQd1c3JBZGRyCQCUCgIFA25pbAkAnAoKCAUBcgJfMQgFAXICXzIIBQFyAl8zCAUBcgJfNAgFAXICXzUIBQFyAl82CAUBcgJfNwkApgMBCAUBcgJfOAgFAXICXzkIBQFyA18xMAFpAQ5nZXRGZWVSRUFET05MWQAJAJQKAgUDbmlsBQNmZWUBAnR4AQZ2ZXJpZnkABA90YXJnZXRQdWJsaWNLZXkEByRtYXRjaDAJAQFtAAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAJwawUHJG1hdGNoMAUCcGsDCQABAgUHJG1hdGNoMAIEVW5pdAgFAnR4D3NlbmRlclB1YmxpY0tleQkAAgECC01hdGNoIGVycm9yBAckbWF0Y2gwBQJ0eAMJAAECBQckbWF0Y2gwAgVPcmRlcgQFb3JkZXIFByRtYXRjaDAECm1hdGNoZXJQdWIJAQJtcAAECm9yZGVyVmFsaWQJAQNtb2EBBQVvcmRlcgQLc2VuZGVyVmFsaWQJAPQDAwgFBW9yZGVyCWJvZHlCeXRlcwkAkQMCCAUFb3JkZXIGcHJvb2ZzAAAIBQVvcmRlcg9zZW5kZXJQdWJsaWNLZXkEDG1hdGNoZXJWYWxpZAkA9AMDCAUFb3JkZXIJYm9keUJ5dGVzCQCRAwIIBQVvcmRlcgZwcm9vZnMAAQUKbWF0Y2hlclB1YgMDAwUKb3JkZXJWYWxpZAULc2VuZGVyVmFsaWQHBQxtYXRjaGVyVmFsaWQHBgkBA3RvZQMFCm9yZGVyVmFsaWQFC3NlbmRlclZhbGlkBQxtYXRjaGVyVmFsaWQDCQABAgUHJG1hdGNoMAIUU2V0U2NyaXB0VHJhbnNhY3Rpb24EAXMFByRtYXRjaDAEB25ld0hhc2gJAPYDAQkBBXZhbHVlAQgFAXMGc2NyaXB0BAthbGxvd2VkSGFzaAkA2wQBCQEFdmFsdWUBCQCdCAIFA2ZjYQkBHGtleUFsbG93ZWRMcFN0YWJsZVNjcmlwdEhhc2gABAtjdXJyZW50SGFzaAkA8QcBBQR0aGlzAwMJAAACBQthbGxvd2VkSGFzaAUHbmV3SGFzaAkBAiE9AgULY3VycmVudEhhc2gFB25ld0hhc2gHBgkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAUPdGFyZ2V0UHVibGljS2V5CQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwAABQ90YXJnZXRQdWJsaWNLZXmzZy+g", "chainId": 87, "height": 3335838, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: dpyg3p368f9UHSbi2TTS7iAnoaETQxkJpc6PUZ9LMTC Next: 7pfqFLbwNivRYGXHZmKrMNSZfWGwHMvH9XjMAcRB66C5 Diff:
OldNewDifferences
99
1010 let zeroBigInt = toBigInt(0)
1111
12-let oneBigInt = toBigInt(1)
12+let big0 = toBigInt(0)
13+
14+let big1 = toBigInt(1)
15+
16+let big2 = toBigInt(2)
1317
1418 let slippage4D = toBigInt((scale8 - ((scale8 * 1) / scale8)))
1519
5357
5458 let idxFactGwxRewCntr = 10
5559
56-let delay = "%s__delay"
60+let feeDefault = fraction(5, scale8, 10000)
5761
5862 func t1 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
5963
6569
6670
6771 func abs (val) = if ((zeroBigInt > val))
72+ then -(val)
73+ else val
74+
75+
76+func absBigInt (val) = if ((zeroBigInt > val))
6877 then -(val)
6978 else val
7079
102111 func ada () = "%s__addonAddr"
103112
104113
105-func lgotc (caller) = makeString(["%s%s__lastGetOneTknCall", caller], SEP)
114+let keyFee = "%s__fee"
106115
107-
108-func lsotc (caller) = makeString(["%s%s__lastPutOneTknCall", caller], SEP)
109-
116+let fee = valueOrElse(getInteger(this, keyFee), feeDefault)
110117
111118 func fcfg () = "%s__factoryConfig"
112119
124131
125132
126133 func keyAllowedLpStableScriptHash () = "%s__allowedLpStableScriptHash"
134+
135+
136+func keyFeeCollectorAddress () = "%s__feeCollectorAddress"
127137
128138
129139 func toe (orV,sendrV,matchV) = throw(((((("Failed: ordValid=" + toString(orV)) + " sndrValid=") + toString(sendrV)) + " mtchrValid=") + toString(matchV)))
153163 func mp () = fromBase58String(strf(fca, mtpk()))
154164
155165
166+let feeCollectorAddress = addressFromStringValue(strf(fca, keyFeeCollectorAddress()))
167+
156168 func gpc () = {
157169 let amtAs = strf(this, aa())
158170 let priceAs = strf(this, pa())
164176
165177 func gfc () = split(strf(fca, fcfg()), SEP)
166178
179+
180+let factoryConfig = gfc()
181+
182+let stakingContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactStakCntr]), "Invalid staking contract address")
183+
184+let slipageContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactSlippCntr]), "Invalid slipage contract address")
185+
186+let gwxContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactGwxRewCntr]), "Invalid gwx contract address")
167187
168188 func dataPutActionInfo (inAmtAssetAmt,inPriceAssetAmt,outLpAmt,price,slipByUser,slippageReal,txHeight,txTimestamp,slipageAmAmt,slipagePrAmt) = makeString(["%d%d%d%d%d%d%d%d%d%d", toString(inAmtAssetAmt), toString(inPriceAssetAmt), toString(outLpAmt), toString(price), toString(slipByUser), toString(slippageReal), toString(txHeight), toString(txTimestamp), toString(slipageAmAmt), toString(slipagePrAmt)], SEP)
169189
226246 }
227247
228248
249+func takeFee (amount) = {
250+ let feeAmount = fraction(amount, fee, scale8)
251+ $Tuple2((amount - feeAmount), feeAmount)
252+ }
253+
254+
229255 func ego (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
230256 let cfg = gpc()
231257 let lpId = cfg[idxLPAsId]
262288 }
263289
264290
265-func epo (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,userAddress,isEval,emitLp,isOneAsset,pmtAmt,pmtId) = {
291+func epo (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,userAddress,isEval,emitLp,isOneAsset,validateSlippage,pmtAmt,pmtId) = {
266292 let cfg = gpc()
267293 let lpId = fromBase58String(cfg[idxLPAsId])
268294 let amIdStr = cfg[idxAmAsId]
307333 let curPriceX18 = cpbi(prBalanceX18, amBalanceX18)
308334 let slippageRealX18 = fraction(abs((curPriceX18 - userPriceX18)), scale18, curPriceX18)
309335 let slippageX18 = t1(slippage, scale8)
310- if (if ((curPriceX18 != zeroBigInt))
336+ if (if (if (validateSlippage)
337+ then (curPriceX18 != zeroBigInt)
338+ else false)
311339 then (slippageRealX18 > slippageX18)
312340 else false)
313341 then throw(((("Price slippage " + toString(slippageRealX18)) + " > ") + toString(slippageX18)))
337365 else calcLpAmt
338366 let amDiff = (inAmAmt - calcAmAssetPmt)
339367 let prDiff = (inPrAmt - calcPrAssetPmt)
340- let $t01560115946 = if (if (isOneAsset)
368+ let $t01635116696 = if (if (isOneAsset)
341369 then (pmtId == amIdStr)
342370 else false)
343371 then $Tuple2(pmtAmt, 0)
346374 else false)
347375 then $Tuple2(0, pmtAmt)
348376 else $Tuple2(calcAmAssetPmt, calcPrAssetPmt)
349- let writeAmAmt = $t01560115946._1
350- let writePrAmt = $t01560115946._2
377+ let writeAmAmt = $t01635116696._1
378+ let writePrAmt = $t01635116696._2
351379 let commonState = [IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice), StringEntry(pau(userAddress, txId58), dataPutActionInfo(writeAmAmt, writePrAmt, emitLpAmt, curPrice, slippage, slippageCalc, height, lastBlock.timestamp, amDiff, prDiff))]
352380 $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEm, lpId, sts, commonState, amDiff, prDiff, inAmId, inPrId)
353381 }
418446 }
419447
420448
421-func cp (caller,txId,amAsPmt,prAsPmt,slippage,emitLp,isOneAsset,pmtAmt,pmtId) = {
422- let r = epo(txId, slippage, value(amAsPmt).amount, value(amAsPmt).assetId, value(prAsPmt).amount, value(prAsPmt).assetId, caller, false, emitLp, isOneAsset, pmtAmt, pmtId)
449+func cp (caller,txId,amAsPmt,prAsPmt,slippage,emitLp,isOneAsset,validateSlippage,pmtAmt,pmtId) = {
450+ let r = epo(txId, slippage, value(amAsPmt).amount, value(amAsPmt).assetId, value(prAsPmt).amount, value(prAsPmt).assetId, caller, (txId == ""), emitLp, isOneAsset, validateSlippage, pmtAmt, pmtId)
423451 let sts = parseIntValue(r._8)
424452 if (if (if (igs())
425453 then true
429457 then throw(("Blocked:" + toString(sts)))
430458 else r
431459 }
460+
461+
462+func getD (xp) = {
463+ let n = big2
464+ let xp0 = xp[0]
465+ let xp1 = xp[1]
466+ let aPrecision = parseBigIntValue(Amult)
467+ let a = (parseBigIntValue(A) * aPrecision)
468+ let s = (xp0 + xp1)
469+ if ((s == big0))
470+ then big0
471+ else {
472+ let ann = (a * n)
473+ let xp0_xp1_n_n = (((xp0 * xp1) * n) * n)
474+ let ann_s_aPrecision = ((ann * s) / aPrecision)
475+ let ann_aPrecision = (ann - aPrecision)
476+ let n1 = (n + big1)
477+ func calc (acc,cur) = {
478+ let $t02124821268 = acc
479+ let d = $t02124821268._1
480+ let found = $t02124821268._2
481+ if ((found != unit))
482+ then acc
483+ else {
484+ let dp = (((d * d) * d) / xp0_xp1_n_n)
485+ let dNext = (((ann_s_aPrecision + (dp * n)) * d) / (((ann_aPrecision * d) / aPrecision) + (n1 * dp)))
486+ let dDiff = absBigInt((dNext - value(d)))
487+ if ((big1 >= dDiff))
488+ then $Tuple2(dNext, cur)
489+ else $Tuple2(dNext, unit)
490+ }
491+ }
492+
493+ let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
494+ let $t02168921736 = {
495+ let $l = arr
496+ let $s = size($l)
497+ let $acc0 = $Tuple2(s, unit)
498+ func $f0_1 ($a,$i) = if (($i >= $s))
499+ then $a
500+ else calc($a, $l[$i])
501+
502+ func $f0_2 ($a,$i) = if (($i >= $s))
503+ then $a
504+ else throw("List size exceeds 15")
505+
506+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15)
507+ }
508+ let d = $t02168921736._1
509+ let found = $t02168921736._2
510+ if ((found != unit))
511+ then d
512+ else throw(("D calculation error, D = " + toString(d)))
513+ }
514+ }
515+
516+
517+func getYD (xp,i,D) = {
518+ let n = big2
519+ let x = xp[if ((i == 0))
520+ then 1
521+ else 0]
522+ let aPrecision = parseBigIntValue(Amult)
523+ let a = (parseBigIntValue(A) * aPrecision)
524+ let s = x
525+ let ann = (a * n)
526+ let c = (((((D * D) / (x * n)) * D) * aPrecision) / (ann * n))
527+ let b = ((s + ((D * aPrecision) / ann)) - D)
528+ func calc (acc,cur) = {
529+ let $t02223622256 = acc
530+ let y = $t02223622256._1
531+ let found = $t02223622256._2
532+ if ((found != unit))
533+ then acc
534+ else {
535+ let yNext = (((y * y) + c) / ((big2 * y) + b))
536+ let yDiff = absBigInt((yNext - value(y)))
537+ if ((big1 >= yDiff))
538+ then $Tuple2(yNext, cur)
539+ else $Tuple2(yNext, unit)
540+ }
541+ }
542+
543+ let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
544+ let $t02256322610 = {
545+ let $l = arr
546+ let $s = size($l)
547+ let $acc0 = $Tuple2(D, unit)
548+ func $f0_1 ($a,$i) = if (($i >= $s))
549+ then $a
550+ else calc($a, $l[$i])
551+
552+ func $f0_2 ($a,$i) = if (($i >= $s))
553+ then $a
554+ else throw("List size exceeds 15")
555+
556+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15)
557+ }
558+ let y = $t02256322610._1
559+ let found = $t02256322610._2
560+ if ((found != unit))
561+ then y
562+ else throw(("Y calculation error, Y = " + toString(y)))
563+ }
564+
565+
566+func calcPutOneTkn (pmtAmtRaw,pmtAssetId,userAddress,txId) = {
567+ let poolConfig = gpc()
568+ let amId = poolConfig[idxAmAsId]
569+ let prId = poolConfig[idxPrAsId]
570+ let lpId = poolConfig[idxLPAsId]
571+ let amtDcm = parseIntValue(poolConfig[idxAmtAsDcm])
572+ let priceDcm = parseIntValue(poolConfig[idxPriceAsDcm])
573+ let lpAssetEmission = toBigInt(valueOrErrorMessage(assetInfo(fromBase58String(lpId)), "invalid lp asset").quantity)
574+ let chechEmission = if ((lpAssetEmission > big0))
575+ then true
576+ else throw("initial deposit requires all coins")
577+ if ((chechEmission == chechEmission))
578+ then {
579+ let amBalance = getAccBalance(amId)
580+ let prBalance = getAccBalance(prId)
581+ let $t02336923831 = if ((txId == ""))
582+ then $Tuple2(amBalance, prBalance)
583+ else if ((pmtAssetId == amId))
584+ then if ((pmtAmtRaw > amBalance))
585+ then throw("invalid payment amount")
586+ else $Tuple2((amBalance - pmtAmtRaw), prBalance)
587+ else if ((pmtAssetId == prId))
588+ then if ((pmtAmtRaw > prBalance))
589+ then throw("invalid payment amount")
590+ else $Tuple2(amBalance, (prBalance - pmtAmtRaw))
591+ else throw("wrong pmtAssetId")
592+ let amBalanceOld = $t02336923831._1
593+ let prBalanceOld = $t02336923831._2
594+ let $t02383724013 = if ((pmtAssetId == amId))
595+ then $Tuple2(pmtAmtRaw, 0)
596+ else if ((pmtAssetId == prId))
597+ then $Tuple2(0, pmtAmtRaw)
598+ else throw("invalid payment")
599+ let amAmountRaw = $t02383724013._1
600+ let prAmountRaw = $t02383724013._2
601+ let amAmount = takeFee(amAmountRaw)._1
602+ let prAmount = takeFee(prAmountRaw)._1
603+ let feeAmount = takeFee(pmtAmtRaw)._2
604+ let amBalanceNew = (amBalanceOld + amAmount)
605+ let prBalanceNew = (prBalanceOld + prAmount)
606+ let D0 = getD([toBigInt(amBalanceOld), toBigInt(prBalanceOld)])
607+ let D1 = getD([toBigInt(amBalanceNew), toBigInt(prBalanceNew)])
608+ let checkD = if ((D1 > D0))
609+ then true
610+ else throw()
611+ if ((checkD == checkD))
612+ then {
613+ let lpAmount = fraction(lpAssetEmission, (D1 - D0), D0)
614+ let curPrice = f1(cpbi(t1(prBalanceNew, priceDcm), t1(amBalanceNew, amtDcm)), scale8)
615+ let commonState = [IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice), StringEntry(pau(userAddress, txId), dataPutActionInfo(amAmountRaw, prAmountRaw, toInt(lpAmount), curPrice, 0, 0, height, lastBlock.timestamp, 0, 0))]
616+ let poolProportion = fraction(prBalanceOld, scale8, amBalanceOld)
617+ let amountAssetPart = fraction(pmtAmtRaw, scale8, (poolProportion + scale8))
618+ let priceAssetPart = (pmtAmtRaw - amountAssetPart)
619+ let lpAmtBoth = fraction(lpAssetEmission, toBigInt(priceAssetPart), toBigInt(prBalanceOld))
620+ let bonus = toInt(fraction((lpAmount - lpAmtBoth), scale8BigInt, lpAmtBoth))
621+ $Tuple4(toInt(lpAmount), commonState, feeAmount, bonus)
622+ }
623+ else throw("Strict value is not equal to itself.")
624+ }
625+ else throw("Strict value is not equal to itself.")
626+ }
627+
628+
629+func getOneTknV2Internal (outAssetId,minOutAmount,payments,caller,originCaller,transactionId) = if ((size(payments) != 1))
630+ then throw("1 pmnt expd")
631+ else {
632+ let poolConfig = gpc()
633+ let lpId = poolConfig[idxLPAsId]
634+ let amId = poolConfig[idxAmAsId]
635+ let prId = poolConfig[idxPrAsId]
636+ let amDecimals = parseIntValue(poolConfig[idxAmtAsDcm])
637+ let prDecimals = parseIntValue(poolConfig[idxPriceAsDcm])
638+ let poolStatus = poolConfig[idxPoolSt]
639+ let userAddress = if ((caller == this))
640+ then originCaller
641+ else caller
642+ let pmt = value(payments[0])
643+ let pmtAssetId = value(pmt.assetId)
644+ let pmtAmt = pmt.amount
645+ if ((1000000000 > pmtAmt))
646+ then throw("Min pmt 10 LP")
647+ else {
648+ let txId58 = toBase58String(transactionId)
649+ if ((lpId != toBase58String(pmtAssetId)))
650+ then throw("Wrong LP")
651+ else {
652+ let amBalance = getAccBalance(amId)
653+ let prBalance = getAccBalance(prId)
654+ let $t02625626364 = {
655+ let @ = invoke(this, "getOneTknV2READONLY", [outAssetId, pmtAmt], nil)
656+ if ($isInstanceOf(@, "(Int, Int)"))
657+ then @
658+ else throw(($getType(@) + " couldn't be cast to (Int, Int)"))
659+ }
660+ let totalGet = $t02625626364._1
661+ let feeAmount = $t02625626364._2
662+ let totalAmount = if (if ((minOutAmount > 0))
663+ then (minOutAmount > totalGet)
664+ else false)
665+ then throw(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
666+ else totalGet
667+ let $t02655126858 = if ((outAssetId == amId))
668+ then $Tuple4(totalAmount, 0, ((amBalance - totalAmount) - feeAmount), prBalance)
669+ else if ((outAssetId == prId))
670+ then $Tuple4(0, totalAmount, amBalance, ((prBalance - totalAmount) - feeAmount))
671+ else throw("invalid out asset id")
672+ let outAm = $t02655126858._1
673+ let outPr = $t02655126858._2
674+ let amBalanceNew = $t02655126858._3
675+ let prBalanceNew = $t02655126858._4
676+ let curPrX18 = cpbi(t1(prBalanceNew, prDecimals), t1(amBalanceNew, amDecimals))
677+ let curPr = f1(curPrX18, scale8)
678+ let outAssetIdOrWaves = if ((outAssetId == "WAVES"))
679+ then unit
680+ else fromBase58String(outAssetId)
681+ let sendFeeToMatcher = if ((feeAmount > 0))
682+ then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetIdOrWaves)]
683+ else nil
684+ let state = ([ScriptTransfer(userAddress, totalAmount, outAssetIdOrWaves), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAm, outPr, pmtAmt, curPr, height, lastBlock.timestamp)), IntegerEntry(pl(), curPr), IntegerEntry(ph(height, lastBlock.timestamp), curPr)] ++ sendFeeToMatcher)
685+ if ((state == state))
686+ then {
687+ let burn = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
688+ if ((burn == burn))
689+ then $Tuple2(state, totalAmount)
690+ else throw("Strict value is not equal to itself.")
691+ }
692+ else throw("Strict value is not equal to itself.")
693+ }
694+ }
695+ }
432696
433697
434698 func m () = match getString(mpk()) {
522786 else if ((size(i.payments) != 2))
523787 then throw("2 pmnts expd")
524788 else {
525- let e = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(value(i.payments[0]).assetId, value(i.payments[0]).amount), i.payments[1], slip, true, false, 0, "")
789+ let e = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(value(i.payments[0]).assetId, value(i.payments[0]).amount), i.payments[1], slip, true, false, true, 0, "")
526790 let emitLpAmt = e._2
527791 let lpAssetId = e._7
528792 let state = e._9
574838
575839
576840 @Callable(i)
577-func putOneTkn (amAssetPart,prAssetPart,outLp,slippage,autoStake) = {
578- let cfg = gfc()
579- let stakingCntr = valueOrErrorMessage(addressFromString(cfg[idxFactStakCntr]), "Wr st addr")
580- let slipCntr = valueOrErrorMessage(addressFromString(cfg[idxFactSlippCntr]), "Wr sl addr")
581- let gwxCntr = valueOrErrorMessage(addressFromString(cfg[idxFactGwxRewCntr]), "Wr gwx addr")
582- let poolCfg = gpc()
583- let amId = poolCfg[idxAmAsId]
584- let prId = poolCfg[idxPrAsId]
585- let amDcm = parseIntValue(poolCfg[idxAmtAsDcm])
586- let prDcm = parseIntValue(poolCfg[idxPriceAsDcm])
587- let addon = valueOrElse(getString(this, ada()), "")
588- let userAddress = if ((addon == toString(i.caller)))
589- then i.originCaller
590- else i.caller
591- let addonContract = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(ada()), "no addons")), "addon address in not valid")
592- let check = reentrantInvoke(addonContract, "ensureCanPutOneTkn", [toString(userAddress)], nil)
593- if ((check == check))
594- then if (if (if (if ((0 >= slippage))
595- then true
596- else (0 >= amAssetPart))
597- then true
598- else (0 >= prAssetPart))
599- then true
600- else (0 >= outLp))
601- then throw("Wrong params")
602- else if ((size(i.payments) != 1))
603- then throw("1 pmnt expd")
604- else {
605- let pmt = value(i.payments[0])
606- let pmtAssetId = toBase58String(value(pmt.assetId))
607- let pmtAmt = pmt.amount
608- if ((10000000 > pmtAmt))
609- then throw("Wrong pmt amt")
610- else {
611- let amBalance = getAccBalance(amId)
612- let prBalance = getAccBalance(prId)
613- let $t02485925435 = if ((pmtAssetId == amId))
614- then if (if ((pmtAmt > amBalance))
615- then true
616- else (amAssetPart > pmtAmt))
617- then throw("invalid payment amount")
618- else $Tuple6((amBalance - pmtAmt), prBalance, (pmtAmt - amAssetPart), prAssetPart, 0, 0)
619- else if ((pmtAssetId == prId))
620- then if (if ((pmtAmt > prBalance))
621- then true
622- else (prAssetPart > pmtAmt))
623- then throw("invalid payment amount")
624- else $Tuple6(amBalance, (prBalance - pmtAmt), 0, 0, (pmtAmt - prAssetPart), amAssetPart)
625- else throw("wrong pmtAssetId")
626- let amBalanceNow = $t02485925435._1
627- let prBalanceNow = $t02485925435._2
628- let virtSwapInAm = $t02485925435._3
629- let virtSwapOutPr = $t02485925435._4
630- let virtSwapInPr = $t02485925435._5
631- let virtSwapOutAm = $t02485925435._6
632- let D0 = invoke(gwxCntr, "calcD", [toString(amBalanceNow), toString(prBalanceNow), A, Amult, Dconv], nil)
633- let D1 = invoke(gwxCntr, "calcD", [toString(toBigInt(((amBalanceNow + virtSwapInAm) - virtSwapOutAm))), toString(toBigInt(((prBalanceNow + virtSwapInPr) - virtSwapOutPr))), A, Amult, Dconv], nil)
634- let D0vsD1 = vd(parseBigIntValue(str(D1)), parseBigIntValue(str(D0)), slippage4D)
635- if ((D0vsD1 == D0vsD1))
636- then {
637- let estPut = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(fromBase58String(amId), amAssetPart), AttachedPayment(fromBase58String(prId), prAssetPart), slippage, true, true, pmtAmt, pmtAssetId)
638- let estimLP = estPut._2
639- let lpAssetId = estPut._7
640- let state = estPut._9
641- let amDiff = estPut._10
642- let prDiff = estPut._11
643- let lpCalcRes = vad(toBigInt(estimLP), toBigInt(outLp), toBigInt(slippage))
644- let emitLpAmt = toInt(lpCalcRes._2)
645- let e = invoke(fca, "emit", [emitLpAmt], nil)
646- if ((e == e))
647- then {
648- let el = match e {
649- case legacy: Address =>
650- invoke(legacy, "emit", [emitLpAmt], nil)
651- case _ =>
652- unit
653- }
654- if ((el == el))
655- then {
656- let sa = if ((amDiff > 0))
657- then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(amId), amDiff)])
658- else nil
659- if ((sa == sa))
660- then {
661- let sp = if ((prDiff > 0))
662- then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(prId), prDiff)])
663- else nil
664- if ((sp == sp))
665- then {
666- let lpTrnsfr = if (autoStake)
667- then {
668- let ss = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
669- if ((ss == ss))
670- then nil
671- else throw("Strict value is not equal to itself.")
672- }
673- else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
674- (state ++ lpTrnsfr)
675- }
676- else throw("Strict value is not equal to itself.")
677- }
678- else throw("Strict value is not equal to itself.")
679- }
680- else throw("Strict value is not equal to itself.")
681- }
682- else throw("Strict value is not equal to itself.")
683- }
684- else throw("Strict value is not equal to itself.")
685- }
686- }
687- else throw("Strict value is not equal to itself.")
688- }
841+func putOneTknV2 (minOutAmount,autoStake) = if ((size(i.payments) != 1))
842+ then throw("1 pmnt expd")
843+ else {
844+ let poolConfig = gpc()
845+ let amId = poolConfig[idxAmAsId]
846+ let prId = poolConfig[idxPrAsId]
847+ let lpId = fromBase58String(poolConfig[idxLPAsId])
848+ let amDecimals = parseIntValue(poolConfig[idxAmtAsDcm])
849+ let prDecimals = parseIntValue(poolConfig[idxPriceAsDcm])
850+ let userAddress = if ((i.caller == this))
851+ then i.originCaller
852+ else i.caller
853+ let pmt = value(i.payments[0])
854+ let pmtAssetId = toBase58String(value(pmt.assetId))
855+ let pmtAmt = pmt.amount
856+ if ((10000000 > pmtAmt))
857+ then throw("Wrong pmt amt")
858+ else {
859+ let $t03173531860 = calcPutOneTkn(pmtAmt, pmtAssetId, toString(userAddress), toBase58String(i.transactionId))
860+ let estimLP = $t03173531860._1
861+ let state = $t03173531860._2
862+ let feeAmount = $t03173531860._3
863+ let emitLpAmt = if (if ((minOutAmount > 0))
864+ then (minOutAmount > estimLP)
865+ else false)
866+ then throw(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
867+ else estimLP
868+ let e = invoke(fca, "emit", [emitLpAmt], nil)
869+ if ((e == e))
870+ then {
871+ let el = match e {
872+ case legacy: Address =>
873+ invoke(legacy, "emit", [emitLpAmt], nil)
874+ case _ =>
875+ unit
876+ }
877+ if ((el == el))
878+ then {
879+ let lpTrnsfr = if (autoStake)
880+ then {
881+ let ss = invoke(stakingContract, "stake", nil, [AttachedPayment(lpId, emitLpAmt)])
882+ if ((ss == ss))
883+ then nil
884+ else throw("Strict value is not equal to itself.")
885+ }
886+ else [ScriptTransfer(i.caller, emitLpAmt, lpId)]
887+ let sendFeeToMatcher = if ((feeAmount > 0))
888+ then [ScriptTransfer(feeCollectorAddress, feeAmount, fromBase58String(pmtAssetId))]
889+ else nil
890+ $Tuple2(((state ++ lpTrnsfr) ++ sendFeeToMatcher), emitLpAmt)
891+ }
892+ else throw("Strict value is not equal to itself.")
893+ }
894+ else throw("Strict value is not equal to itself.")
895+ }
896+ }
689897
690898
691899
695903 else if ((size(i.payments) != 2))
696904 then throw("2 pmnts expd")
697905 else {
698- let estPut = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(value(i.payments[0]).assetId, value(i.payments[0]).amount), i.payments[1], maxSlpg, false, false, 0, "")
906+ let estPut = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(value(i.payments[0]).assetId, value(i.payments[0]).amount), i.payments[1], maxSlpg, false, false, true, 0, "")
699907 estPut._9
700908 }
701909
718926
719927
720928 @Callable(i)
721-func getOneTkn (exchResult,notUsed,outAmount,outAssetId,slippage) = if ((size(i.payments) != 1))
722- then throw("1 pmnt expd")
723- else {
724- let cfg = gpc()
725- let lpId = cfg[idxLPAsId]
726- let amId = cfg[idxAmAsId]
727- let prId = cfg[idxPrAsId]
728- let amDcm = parseIntValue(cfg[idxAmtAsDcm])
729- let prDcm = parseIntValue(cfg[idxPriceAsDcm])
730- let sts = cfg[idxPoolSt]
731- let factCfg = gfc()
732- let gwxCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactGwxRewCntr]), "Wr sl addr")
733- let pmt = value(i.payments[0])
734- let addon = valueOrElse(getString(this, ada()), "")
735- let userAddress = if ((addon == toString(i.caller)))
736- then i.originCaller
737- else i.caller
738- let txId58 = toBase58String(i.transactionId)
739- let pmtAssetId = value(pmt.assetId)
740- let pmtAmt = pmt.amount
741- let addonContract = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(ada()), "no addons")), "addon address in not valid")
742- let check = reentrantInvoke(addonContract, "ensureCanGetOneTkn", [toString(userAddress)], nil)
743- if ((check == check))
744- then if ((1000000000 > pmtAmt))
745- then throw("Min pmt 10 LP")
746- else if (if (if ((0 > slippage))
747- then true
748- else (0 > exchResult))
749- then true
750- else (0 > outAmount))
751- then throw("Wrong params")
752- else if ((lpId != toBase58String(pmtAssetId)))
753- then throw("Wrong LP")
754- else {
755- let r = ego(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
756- let estimAmAmt = r._1
757- let estimPrAmt = r._2
758- let amBalance = getAccBalance(amId)
759- let prBalance = getAccBalance(prId)
760- let $t03046630923 = if ((outAssetId == amId))
761- then $Tuple7((amBalance - estimAmAmt), (prBalance - estimPrAmt), exchResult, estimPrAmt, 0, 0, (estimAmAmt + exchResult))
762- else if ((outAssetId == prId))
763- then $Tuple7((amBalance - estimAmAmt), (prBalance - estimPrAmt), 0, 0, exchResult, estimAmAmt, (estimPrAmt + exchResult))
764- else throw("wrong outAssetId")
765- let amBalanceNow = $t03046630923._1
766- let prBalanceNow = $t03046630923._2
767- let virtSwapInAm = $t03046630923._3
768- let virtSwapOutPr = $t03046630923._4
769- let virtSwapInPr = $t03046630923._5
770- let virtSwapOutAm = $t03046630923._6
771- let totalGet = $t03046630923._7
772- if (if ((0 > virtSwapInAm))
773- then true
774- else (0 > virtSwapInPr))
775- then throw("Wrong calc")
776- else {
777- let D0 = invoke(gwxCntr, "calcD", [toString(amBalanceNow), toString(prBalanceNow), A, Amult, Dconv], nil)
778- let D1 = invoke(gwxCntr, "calcD", [toString(((amBalanceNow - virtSwapInAm) + virtSwapOutAm)), toString(((prBalanceNow + virtSwapOutPr) - virtSwapInPr)), A, Amult, Dconv], nil)
779- let D0vsD1 = vd(parseBigIntValue(str(D1)), parseBigIntValue(str(D0)), slippage4D)
780- if ((D0vsD1 == D0vsD1))
781- then {
782- let finalRes = vad(toBigInt(totalGet), toBigInt(outAmount), toBigInt(slippage))
783- if ((finalRes == finalRes))
784- then {
785- let $t03162831732 = if ((outAssetId == amId))
786- then $Tuple2(toInt(finalRes._2), 0)
787- else $Tuple2(0, toInt(finalRes._2))
788- let outAm = $t03162831732._1
789- let outPr = $t03162831732._2
790- let curPrX18 = cpbi(t1(prBalance, prDcm), t1(amBalance, amDcm))
791- let curPr = f1(curPrX18, scale8)
792- let state = [ScriptTransfer(userAddress, (outAm + outPr), if ((outAssetId == "WAVES"))
793- then unit
794- else fromBase58String(outAssetId)), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAm, outPr, pmtAmt, curPr, height, lastBlock.timestamp)), IntegerEntry(pl(), curPr), IntegerEntry(ph(height, lastBlock.timestamp), curPr)]
795- if ((state == state))
796- then {
797- let burn = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
798- if ((burn == burn))
799- then state
800- else throw("Strict value is not equal to itself.")
801- }
802- else throw("Strict value is not equal to itself.")
803- }
804- else throw("Strict value is not equal to itself.")
805- }
806- else throw("Strict value is not equal to itself.")
807- }
808- }
809- else throw("Strict value is not equal to itself.")
929+func getOneTknV2 (outAssetId,minOutAmount) = {
930+ let $t03404334198 = getOneTknV2Internal(outAssetId, minOutAmount, i.payments, i.caller, i.originCaller, i.transactionId)
931+ let state = $t03404334198._1
932+ let totalAmount = $t03404334198._2
933+ $Tuple2(state, totalAmount)
934+ }
935+
936+
937+
938+@Callable(i)
939+func getOneTknV2READONLY (outAssetId,lpAssetAmount) = {
940+ let poolConfig = gpc()
941+ let amId = poolConfig[idxAmAsId]
942+ let prId = poolConfig[idxPrAsId]
943+ let lpId = poolConfig[idxLPAsId]
944+ let xp = [toBigInt(getAccBalance(amId)), toBigInt(getAccBalance(prId))]
945+ let lpEmission = toBigInt(valueOrErrorMessage(assetInfo(fromBase58String(lpId)), "invalid lp asset").quantity)
946+ let D0 = getD(xp)
947+ let D1 = (D0 - fraction(toBigInt(lpAssetAmount), D0, lpEmission))
948+ let index = if ((outAssetId == amId))
949+ then 0
950+ else if ((outAssetId == prId))
951+ then 1
952+ else throw("invalid out asset id")
953+ let newY = getYD(xp, index, D1)
954+ let dy = (xp[index] - newY)
955+ let totalGetRaw = toInt((dy - big1))
956+ let $t03497735026 = takeFee(totalGetRaw)
957+ let totalGet = $t03497735026._1
958+ let feeAmount = $t03497735026._2
959+ $Tuple2(nil, $Tuple2(totalGet, feeAmount))
960+ }
961+
962+
963+
964+@Callable(i)
965+func getOneTknV2WithBonusREADONLY (outAssetId,lpAssetAmount) = {
966+ let poolConfig = gpc()
967+ let amId = poolConfig[idxAmAsId]
968+ let prId = poolConfig[idxPrAsId]
969+ let lpId = poolConfig[idxLPAsId]
970+ let amBalance = getAccBalance(amId)
971+ let prBalance = getAccBalance(prId)
972+ let $t03537135486 = {
973+ let @ = invoke(this, "getOneTknV2READONLY", [outAssetId, lpAssetAmount], nil)
974+ if ($isInstanceOf(@, "(Int, Int)"))
975+ then @
976+ else throw(($getType(@) + " couldn't be cast to (Int, Int)"))
810977 }
978+ let totalGet = $t03537135486._1
979+ let feeAmount = $t03537135486._2
980+ let r = ego("", lpId, lpAssetAmount, this)
981+ let outAmAmt = r._1
982+ let outPrAmt = r._2
983+ let sumOfGetAssets = (outAmAmt + outPrAmt)
984+ let bonus = fraction((totalGet - sumOfGetAssets), scale8, sumOfGetAssets)
985+ $Tuple2(nil, $Tuple3(totalGet, feeAmount, bonus))
986+ }
811987
812988
813989
8721048
8731049
8741050 @Callable(i)
1051+func unstakeAndGetOneTknV2 (unstakeAmount,outAssetId,minOutAmount) = {
1052+ let checkPayments = if ((size(i.payments) != 0))
1053+ then throw("No pmnts expd")
1054+ else true
1055+ if ((checkPayments == checkPayments))
1056+ then {
1057+ let cfg = gpc()
1058+ let factoryCfg = gfc()
1059+ let lpAssetId = fromBase58String(cfg[idxLPAsId])
1060+ let staking = valueOrErrorMessage(addressFromString(factoryCfg[idxFactStakCntr]), "Wr st addr")
1061+ let unstakeInv = invoke(staking, "unstake", [toBase58String(lpAssetId), unstakeAmount], nil)
1062+ if ((unstakeInv == unstakeInv))
1063+ then {
1064+ let $t03779337981 = getOneTknV2Internal(outAssetId, minOutAmount, [AttachedPayment(lpAssetId, unstakeAmount)], i.caller, i.originCaller, i.transactionId)
1065+ let state = $t03779337981._1
1066+ let totalAmount = $t03779337981._2
1067+ $Tuple2(state, totalAmount)
1068+ }
1069+ else throw("Strict value is not equal to itself.")
1070+ }
1071+ else throw("Strict value is not equal to itself.")
1072+ }
1073+
1074+
1075+
1076+@Callable(i)
1077+func putOneTknV2WithBonusREADONLY (paymentAmountRaw,paymentAssetId) = {
1078+ let poolConfig = gpc()
1079+ let amId = poolConfig[idxAmAsId]
1080+ let prId = poolConfig[idxPrAsId]
1081+ let lpId = poolConfig[idxLPAsId]
1082+ let $t03824038337 = calcPutOneTkn(paymentAmountRaw, paymentAssetId, "", "")
1083+ let lpAmount = $t03824038337._1
1084+ let state = $t03824038337._2
1085+ let feeAmount = $t03824038337._3
1086+ let bonus = $t03824038337._4
1087+ $Tuple2(nil, $Tuple3(lpAmount, feeAmount, bonus))
1088+ }
1089+
1090+
1091+
1092+@Callable(i)
8751093 func activate (amtAsStr,prAsStr) = if ((toString(i.caller) != toString(fca)))
8761094 then throw("denied")
8771095 else $Tuple2([StringEntry(aa(), amtAsStr), StringEntry(pa(), prAsStr)], "success")
9261144
9271145
9281146 @Callable(i)
929-func estimatePutOperationWrapperREADONLY (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,usrAddr,isEval,emitLp) = $Tuple2(nil, epo(txId58, slippage, inAmAmt, inAmId, inPrAmt, inPrId, usrAddr, isEval, emitLp, false, 0, ""))
1147+func estimatePutOperationWrapperREADONLY (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,usrAddr,isEval,emitLp) = $Tuple2(nil, epo(txId58, slippage, inAmAmt, inAmId, inPrAmt, inPrId, usrAddr, isEval, emitLp, true, false, 0, ""))
9301148
9311149
9321150
9351153 let r = ego(txId58, pmtAsId, pmtLpAmt, addressFromStringValue(usrAddr))
9361154 $Tuple2(nil, $Tuple10(r._1, r._2, r._3, r._4, r._5, r._6, r._7, toString(r._8), r._9, r._10))
9371155 }
1156+
1157+
1158+
1159+@Callable(i)
1160+func getFeeREADONLY () = $Tuple2(nil, fee)
9381161
9391162
9401163 @Verifier(tx)
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let scale8 = 100000000
55
66 let scale8BigInt = toBigInt(100000000)
77
88 let scale18 = toBigInt(1000000000000000000)
99
1010 let zeroBigInt = toBigInt(0)
1111
12-let oneBigInt = toBigInt(1)
12+let big0 = toBigInt(0)
13+
14+let big1 = toBigInt(1)
15+
16+let big2 = toBigInt(2)
1317
1418 let slippage4D = toBigInt((scale8 - ((scale8 * 1) / scale8)))
1519
1620 let Amult = "100"
1721
1822 let Dconv = "1"
1923
2024 let SEP = "__"
2125
2226 let EMPTY = ""
2327
2428 let PoolActive = 1
2529
2630 let PoolPutDis = 2
2731
2832 let PoolMatcherDis = 3
2933
3034 let PoolShutdown = 4
3135
3236 let idxPoolAddress = 1
3337
3438 let idxPoolSt = 2
3539
3640 let idxLPAsId = 3
3741
3842 let idxAmAsId = 4
3943
4044 let idxPrAsId = 5
4145
4246 let idxAmtAsDcm = 6
4347
4448 let idxPriceAsDcm = 7
4549
4650 let idxIAmtAsId = 8
4751
4852 let idxIPriceAsId = 9
4953
5054 let idxFactStakCntr = 1
5155
5256 let idxFactSlippCntr = 7
5357
5458 let idxFactGwxRewCntr = 10
5559
56-let delay = "%s__delay"
60+let feeDefault = fraction(5, scale8, 10000)
5761
5862 func t1 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
5963
6064
6165 func f1 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18))
6266
6367
6468 func ts (amt,resScale,curScale) = fraction(amt, resScale, curScale)
6569
6670
6771 func abs (val) = if ((zeroBigInt > val))
72+ then -(val)
73+ else val
74+
75+
76+func absBigInt (val) = if ((zeroBigInt > val))
6877 then -(val)
6978 else val
7079
7180
7281 func fc () = "%s__factoryContract"
7382
7483
7584 func mpk () = "%s__managerPublicKey"
7685
7786
7887 func pmpk () = "%s__pendingManagerPublicKey"
7988
8089
8190 func pl () = "%s%s__price__last"
8291
8392
8493 func ph (h,t) = makeString(["%s%s%d%d__price__history", toString(h), toString(t)], SEP)
8594
8695
8796 func pau (ua,txId) = ((("%s%s%s__P__" + ua) + "__") + txId)
8897
8998
9099 func gau (ua,txId) = ((("%s%s%s__G__" + ua) + "__") + txId)
91100
92101
93102 func aa () = "%s__amountAsset"
94103
95104
96105 func pa () = "%s__priceAsset"
97106
98107
99108 func amp () = "%s__amp"
100109
101110
102111 func ada () = "%s__addonAddr"
103112
104113
105-func lgotc (caller) = makeString(["%s%s__lastGetOneTknCall", caller], SEP)
114+let keyFee = "%s__fee"
106115
107-
108-func lsotc (caller) = makeString(["%s%s__lastPutOneTknCall", caller], SEP)
109-
116+let fee = valueOrElse(getInteger(this, keyFee), feeDefault)
110117
111118 func fcfg () = "%s__factoryConfig"
112119
113120
114121 func mtpk () = "%s%s__matcher__publicKey"
115122
116123
117124 func pc (iAmtAs,iPrAs) = (((("%d%d%s__" + iAmtAs) + "__") + iPrAs) + "__config")
118125
119126
120127 func mba (bAStr) = ("%s%s%s__mappings__baseAsset2internalId__" + bAStr)
121128
122129
123130 func aps () = "%s__shutdown"
124131
125132
126133 func keyAllowedLpStableScriptHash () = "%s__allowedLpStableScriptHash"
134+
135+
136+func keyFeeCollectorAddress () = "%s__feeCollectorAddress"
127137
128138
129139 func toe (orV,sendrV,matchV) = throw(((((("Failed: ordValid=" + toString(orV)) + " sndrValid=") + toString(sendrV)) + " mtchrValid=") + toString(matchV)))
130140
131141
132142 func str (val) = match val {
133143 case valStr: String =>
134144 valStr
135145 case _ =>
136146 throw("fail cast to String")
137147 }
138148
139149
140150 func strf (addr,key) = valueOrErrorMessage(getString(addr, key), makeString(["mandatory ", toString(addr), ".", key, " not defined"], ""))
141151
142152
143153 func intf (addr,key) = valueOrErrorMessage(getInteger(addr, key), makeString(["mandatory ", toString(addr), ".", key, " not defined"], ""))
144154
145155
146156 let fca = addressFromStringValue(strf(this, fc()))
147157
148158 let A = strf(this, amp())
149159
150160 func igs () = valueOrElse(getBoolean(fca, aps()), false)
151161
152162
153163 func mp () = fromBase58String(strf(fca, mtpk()))
154164
155165
166+let feeCollectorAddress = addressFromStringValue(strf(fca, keyFeeCollectorAddress()))
167+
156168 func gpc () = {
157169 let amtAs = strf(this, aa())
158170 let priceAs = strf(this, pa())
159171 let iPriceAs = intf(fca, mba(priceAs))
160172 let iAmtAs = intf(fca, mba(amtAs))
161173 split(strf(fca, pc(toString(iAmtAs), toString(iPriceAs))), SEP)
162174 }
163175
164176
165177 func gfc () = split(strf(fca, fcfg()), SEP)
166178
179+
180+let factoryConfig = gfc()
181+
182+let stakingContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactStakCntr]), "Invalid staking contract address")
183+
184+let slipageContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactSlippCntr]), "Invalid slipage contract address")
185+
186+let gwxContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactGwxRewCntr]), "Invalid gwx contract address")
167187
168188 func dataPutActionInfo (inAmtAssetAmt,inPriceAssetAmt,outLpAmt,price,slipByUser,slippageReal,txHeight,txTimestamp,slipageAmAmt,slipagePrAmt) = makeString(["%d%d%d%d%d%d%d%d%d%d", toString(inAmtAssetAmt), toString(inPriceAssetAmt), toString(outLpAmt), toString(price), toString(slipByUser), toString(slippageReal), toString(txHeight), toString(txTimestamp), toString(slipageAmAmt), toString(slipagePrAmt)], SEP)
169189
170190
171191 func dataGetActionInfo (outAmtAssetAmt,outPriceAssetAmt,inLpAmt,price,txHeight,txTimestamp) = makeString(["%d%d%d%d%d%d", toString(outAmtAssetAmt), toString(outPriceAssetAmt), toString(inLpAmt), toString(price), toString(txHeight), toString(txTimestamp)], SEP)
172192
173193
174194 func getAccBalance (assetId) = if ((assetId == "WAVES"))
175195 then wavesBalance(this).available
176196 else assetBalance(this, fromBase58String(assetId))
177197
178198
179199 func cpbi (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
180200
181201
182202 func vad (A1,A2,slippage) = {
183203 let diff = fraction((A1 - A2), scale8BigInt, A2)
184204 let pass = ((slippage - abs(diff)) > zeroBigInt)
185205 if (!(pass))
186206 then throw(("Big slpg: " + toString(diff)))
187207 else $Tuple2(pass, min([A1, A2]))
188208 }
189209
190210
191211 func vd (D1,D0,slpg) = {
192212 let diff = fraction(D0, scale8BigInt, D1)
193213 let fail = (slpg > diff)
194214 if (if (fail)
195215 then true
196216 else (D0 > D1))
197217 then throw(((((((toString(D0) + " ") + toString(D1)) + " ") + toString(diff)) + " ") + toString(slpg)))
198218 else fail
199219 }
200220
201221
202222 func pcp (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
203223 let amtAsAmtX18 = t1(amAmt, amAssetDcm)
204224 let prAsAmtX18 = t1(prAmt, prAssetDcm)
205225 cpbi(prAsAmtX18, amtAsAmtX18)
206226 }
207227
208228
209229 func calcPrices (amAmt,prAmt,lpAmt) = {
210230 let cfg = gpc()
211231 let amtAsDcm = parseIntValue(cfg[idxAmtAsDcm])
212232 let prAsDcm = parseIntValue(cfg[idxPriceAsDcm])
213233 let priceX18 = pcp(amtAsDcm, prAsDcm, amAmt, prAmt)
214234 let amAmtX18 = t1(amAmt, amtAsDcm)
215235 let prAmtX18 = t1(prAmt, prAsDcm)
216236 let lpAmtX18 = t1(lpAmt, scale8)
217237 let lpPrInAmAsX18 = cpbi(amAmtX18, lpAmtX18)
218238 let lpPrInPrAsX18 = cpbi(prAmtX18, lpAmtX18)
219239 [priceX18, lpPrInAmAsX18, lpPrInPrAsX18]
220240 }
221241
222242
223243 func calculatePrices (amAmt,prAmt,lpAmt) = {
224244 let p = calcPrices(amAmt, prAmt, lpAmt)
225245 [f1(p[0], scale8), f1(p[1], scale8), f1(p[2], scale8)]
226246 }
227247
228248
249+func takeFee (amount) = {
250+ let feeAmount = fraction(amount, fee, scale8)
251+ $Tuple2((amount - feeAmount), feeAmount)
252+ }
253+
254+
229255 func ego (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
230256 let cfg = gpc()
231257 let lpId = cfg[idxLPAsId]
232258 let amId = cfg[idxAmAsId]
233259 let prId = cfg[idxPrAsId]
234260 let amDcm = parseIntValue(cfg[idxAmtAsDcm])
235261 let prDcm = parseIntValue(cfg[idxPriceAsDcm])
236262 let sts = cfg[idxPoolSt]
237263 let lpEmiss = valueOrErrorMessage(assetInfo(fromBase58String(lpId)), "Wrong LP id").quantity
238264 if ((lpId != pmtAssetId))
239265 then throw("Wrong pmt asset")
240266 else {
241267 let amBalance = getAccBalance(amId)
242268 let amBalanceX18 = t1(amBalance, amDcm)
243269 let prBalance = getAccBalance(prId)
244270 let prBalanceX18 = t1(prBalance, prDcm)
245271 let curPriceX18 = cpbi(prBalanceX18, amBalanceX18)
246272 let curPrice = f1(curPriceX18, scale8)
247273 let pmtLpAmtX18 = t1(pmtLpAmt, scale8)
248274 let lpEmissX18 = t1(lpEmiss, scale8)
249275 let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissX18)
250276 let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissX18)
251277 let outAmAmt = f1(outAmAmtX18, amDcm)
252278 let outPrAmt = f1(outPrAmtX18, prDcm)
253279 let state = if ((txId58 == ""))
254280 then nil
255281 else [ScriptTransfer(userAddress, outAmAmt, if ((amId == "WAVES"))
256282 then unit
257283 else fromBase58String(amId)), ScriptTransfer(userAddress, outPrAmt, if ((prId == "WAVES"))
258284 then unit
259285 else fromBase58String(prId)), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAmAmt, outPrAmt, pmtLpAmt, curPrice, height, lastBlock.timestamp)), IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice)]
260286 $Tuple10(outAmAmt, outPrAmt, amId, prId, amBalance, prBalance, lpEmiss, curPriceX18, sts, state)
261287 }
262288 }
263289
264290
265-func epo (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,userAddress,isEval,emitLp,isOneAsset,pmtAmt,pmtId) = {
291+func epo (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,userAddress,isEval,emitLp,isOneAsset,validateSlippage,pmtAmt,pmtId) = {
266292 let cfg = gpc()
267293 let lpId = fromBase58String(cfg[idxLPAsId])
268294 let amIdStr = cfg[idxAmAsId]
269295 let prIdStr = cfg[idxPrAsId]
270296 let inAmIdStr = cfg[idxIAmtAsId]
271297 let inPrIdStr = cfg[idxIPriceAsId]
272298 let amtDcm = parseIntValue(cfg[idxAmtAsDcm])
273299 let priceDcm = parseIntValue(cfg[idxPriceAsDcm])
274300 let sts = cfg[idxPoolSt]
275301 let lpEm = valueOrErrorMessage(assetInfo(lpId), "Wr lp as").quantity
276302 let amBalance = if (isEval)
277303 then getAccBalance(amIdStr)
278304 else if (if (isOneAsset)
279305 then (pmtId == amIdStr)
280306 else false)
281307 then (getAccBalance(amIdStr) - pmtAmt)
282308 else if (isOneAsset)
283309 then getAccBalance(amIdStr)
284310 else (getAccBalance(amIdStr) - inAmAmt)
285311 let prBalance = if (isEval)
286312 then getAccBalance(prIdStr)
287313 else if (if (isOneAsset)
288314 then (pmtId == prIdStr)
289315 else false)
290316 then (getAccBalance(prIdStr) - pmtAmt)
291317 else if (isOneAsset)
292318 then getAccBalance(prIdStr)
293319 else (getAccBalance(prIdStr) - inPrAmt)
294320 let inAmAssetAmtX18 = t1(inAmAmt, amtDcm)
295321 let inPrAssetAmtX18 = t1(inPrAmt, priceDcm)
296322 let userPriceX18 = cpbi(inPrAssetAmtX18, inAmAssetAmtX18)
297323 let amBalanceX18 = t1(amBalance, amtDcm)
298324 let prBalanceX18 = t1(prBalance, priceDcm)
299325 let r = if ((lpEm == 0))
300326 then {
301327 let curPriceX18 = zeroBigInt
302328 let slippageX18 = zeroBigInt
303329 let lpAmtX18 = pow((inAmAssetAmtX18 * inPrAssetAmtX18), 0, toBigInt(5), 1, 0, DOWN)
304330 $Tuple5(f1(lpAmtX18, scale8), f1(inAmAssetAmtX18, amtDcm), f1(inPrAssetAmtX18, priceDcm), cpbi((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
305331 }
306332 else {
307333 let curPriceX18 = cpbi(prBalanceX18, amBalanceX18)
308334 let slippageRealX18 = fraction(abs((curPriceX18 - userPriceX18)), scale18, curPriceX18)
309335 let slippageX18 = t1(slippage, scale8)
310- if (if ((curPriceX18 != zeroBigInt))
336+ if (if (if (validateSlippage)
337+ then (curPriceX18 != zeroBigInt)
338+ else false)
311339 then (slippageRealX18 > slippageX18)
312340 else false)
313341 then throw(((("Price slippage " + toString(slippageRealX18)) + " > ") + toString(slippageX18)))
314342 else {
315343 let lpEmissionX18 = t1(lpEm, scale8)
316344 let prViaAmX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
317345 let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
318346 let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
319347 then $Tuple2(amViaPrX18, inPrAssetAmtX18)
320348 else $Tuple2(inAmAssetAmtX18, prViaAmX18)
321349 let expAmtAssetAmtX18 = expectedAmts._1
322350 let expPriceAssetAmtX18 = expectedAmts._2
323351 let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18)
324352 $Tuple5(f1(lpAmtX18, scale8), f1(expAmtAssetAmtX18, amtDcm), f1(expPriceAssetAmtX18, priceDcm), curPriceX18, slippageX18)
325353 }
326354 }
327355 let calcLpAmt = r._1
328356 let calcAmAssetPmt = r._2
329357 let calcPrAssetPmt = r._3
330358 let curPrice = f1(r._4, scale8)
331359 let slippageCalc = f1(r._5, scale8)
332360 if ((0 >= calcLpAmt))
333361 then throw("LP <= 0")
334362 else {
335363 let emitLpAmt = if (!(emitLp))
336364 then 0
337365 else calcLpAmt
338366 let amDiff = (inAmAmt - calcAmAssetPmt)
339367 let prDiff = (inPrAmt - calcPrAssetPmt)
340- let $t01560115946 = if (if (isOneAsset)
368+ let $t01635116696 = if (if (isOneAsset)
341369 then (pmtId == amIdStr)
342370 else false)
343371 then $Tuple2(pmtAmt, 0)
344372 else if (if (isOneAsset)
345373 then (pmtId == prIdStr)
346374 else false)
347375 then $Tuple2(0, pmtAmt)
348376 else $Tuple2(calcAmAssetPmt, calcPrAssetPmt)
349- let writeAmAmt = $t01560115946._1
350- let writePrAmt = $t01560115946._2
377+ let writeAmAmt = $t01635116696._1
378+ let writePrAmt = $t01635116696._2
351379 let commonState = [IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice), StringEntry(pau(userAddress, txId58), dataPutActionInfo(writeAmAmt, writePrAmt, emitLpAmt, curPrice, slippage, slippageCalc, height, lastBlock.timestamp, amDiff, prDiff))]
352380 $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEm, lpId, sts, commonState, amDiff, prDiff, inAmId, inPrId)
353381 }
354382 }
355383
356384
357385 func moa (order) = {
358386 let cfg = gpc()
359387 let amtAsId = cfg[idxAmAsId]
360388 let prAsId = cfg[idxPrAsId]
361389 let sts = parseIntValue(cfg[idxPoolSt])
362390 let amtAsDcm = parseIntValue(cfg[idxAmtAsDcm])
363391 let prAsDcm = parseIntValue(cfg[idxPriceAsDcm])
364392 let accAmtAsBalance = getAccBalance(amtAsId)
365393 let accPrAsBalance = getAccBalance(prAsId)
366394 let curPriceX18 = if ((order.orderType == Buy))
367395 then pcp(amtAsDcm, prAsDcm, (accAmtAsBalance + order.amount), accPrAsBalance)
368396 else pcp(amtAsDcm, prAsDcm, (accAmtAsBalance - order.amount), accPrAsBalance)
369397 let curPrice = f1(curPriceX18, scale8)
370398 if (if (if (igs())
371399 then true
372400 else (sts == PoolMatcherDis))
373401 then true
374402 else (sts == PoolShutdown))
375403 then throw("Admin blocked")
376404 else {
377405 let orAmtAsset = order.assetPair.amountAsset
378406 let orAmtAsStr = if ((orAmtAsset == unit))
379407 then "WAVES"
380408 else toBase58String(value(orAmtAsset))
381409 let orPrAsset = order.assetPair.priceAsset
382410 let orPrAsStr = if ((orPrAsset == unit))
383411 then "WAVES"
384412 else toBase58String(value(orPrAsset))
385413 if (if ((orAmtAsStr != amtAsId))
386414 then true
387415 else (orPrAsStr != prAsId))
388416 then throw("Wr assets")
389417 else {
390418 let orderPrice = order.price
391419 let priceDcm = fraction(scale8, prAsDcm, amtAsDcm)
392420 let castOrderPrice = ts(orderPrice, scale8, priceDcm)
393421 let isOrderPriceValid = if ((order.orderType == Buy))
394422 then (curPrice >= castOrderPrice)
395423 else (castOrderPrice >= curPrice)
396424 true
397425 }
398426 }
399427 }
400428
401429
402430 func cg (i) = if ((size(i.payments) != 1))
403431 then throw("1 pmnt exp")
404432 else {
405433 let pmt = value(i.payments[0])
406434 let pmtAssetId = value(pmt.assetId)
407435 let pmtAmt = pmt.amount
408436 let r = ego(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
409437 let outAmAmt = r._1
410438 let outPrAmt = r._2
411439 let sts = parseIntValue(r._9)
412440 let state = r._10
413441 if (if (igs())
414442 then true
415443 else (sts == PoolShutdown))
416444 then throw(("Admin blocked: " + toString(sts)))
417445 else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
418446 }
419447
420448
421-func cp (caller,txId,amAsPmt,prAsPmt,slippage,emitLp,isOneAsset,pmtAmt,pmtId) = {
422- let r = epo(txId, slippage, value(amAsPmt).amount, value(amAsPmt).assetId, value(prAsPmt).amount, value(prAsPmt).assetId, caller, false, emitLp, isOneAsset, pmtAmt, pmtId)
449+func cp (caller,txId,amAsPmt,prAsPmt,slippage,emitLp,isOneAsset,validateSlippage,pmtAmt,pmtId) = {
450+ let r = epo(txId, slippage, value(amAsPmt).amount, value(amAsPmt).assetId, value(prAsPmt).amount, value(prAsPmt).assetId, caller, (txId == ""), emitLp, isOneAsset, validateSlippage, pmtAmt, pmtId)
423451 let sts = parseIntValue(r._8)
424452 if (if (if (igs())
425453 then true
426454 else (sts == PoolPutDis))
427455 then true
428456 else (sts == PoolShutdown))
429457 then throw(("Blocked:" + toString(sts)))
430458 else r
431459 }
460+
461+
462+func getD (xp) = {
463+ let n = big2
464+ let xp0 = xp[0]
465+ let xp1 = xp[1]
466+ let aPrecision = parseBigIntValue(Amult)
467+ let a = (parseBigIntValue(A) * aPrecision)
468+ let s = (xp0 + xp1)
469+ if ((s == big0))
470+ then big0
471+ else {
472+ let ann = (a * n)
473+ let xp0_xp1_n_n = (((xp0 * xp1) * n) * n)
474+ let ann_s_aPrecision = ((ann * s) / aPrecision)
475+ let ann_aPrecision = (ann - aPrecision)
476+ let n1 = (n + big1)
477+ func calc (acc,cur) = {
478+ let $t02124821268 = acc
479+ let d = $t02124821268._1
480+ let found = $t02124821268._2
481+ if ((found != unit))
482+ then acc
483+ else {
484+ let dp = (((d * d) * d) / xp0_xp1_n_n)
485+ let dNext = (((ann_s_aPrecision + (dp * n)) * d) / (((ann_aPrecision * d) / aPrecision) + (n1 * dp)))
486+ let dDiff = absBigInt((dNext - value(d)))
487+ if ((big1 >= dDiff))
488+ then $Tuple2(dNext, cur)
489+ else $Tuple2(dNext, unit)
490+ }
491+ }
492+
493+ let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
494+ let $t02168921736 = {
495+ let $l = arr
496+ let $s = size($l)
497+ let $acc0 = $Tuple2(s, unit)
498+ func $f0_1 ($a,$i) = if (($i >= $s))
499+ then $a
500+ else calc($a, $l[$i])
501+
502+ func $f0_2 ($a,$i) = if (($i >= $s))
503+ then $a
504+ else throw("List size exceeds 15")
505+
506+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15)
507+ }
508+ let d = $t02168921736._1
509+ let found = $t02168921736._2
510+ if ((found != unit))
511+ then d
512+ else throw(("D calculation error, D = " + toString(d)))
513+ }
514+ }
515+
516+
517+func getYD (xp,i,D) = {
518+ let n = big2
519+ let x = xp[if ((i == 0))
520+ then 1
521+ else 0]
522+ let aPrecision = parseBigIntValue(Amult)
523+ let a = (parseBigIntValue(A) * aPrecision)
524+ let s = x
525+ let ann = (a * n)
526+ let c = (((((D * D) / (x * n)) * D) * aPrecision) / (ann * n))
527+ let b = ((s + ((D * aPrecision) / ann)) - D)
528+ func calc (acc,cur) = {
529+ let $t02223622256 = acc
530+ let y = $t02223622256._1
531+ let found = $t02223622256._2
532+ if ((found != unit))
533+ then acc
534+ else {
535+ let yNext = (((y * y) + c) / ((big2 * y) + b))
536+ let yDiff = absBigInt((yNext - value(y)))
537+ if ((big1 >= yDiff))
538+ then $Tuple2(yNext, cur)
539+ else $Tuple2(yNext, unit)
540+ }
541+ }
542+
543+ let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
544+ let $t02256322610 = {
545+ let $l = arr
546+ let $s = size($l)
547+ let $acc0 = $Tuple2(D, unit)
548+ func $f0_1 ($a,$i) = if (($i >= $s))
549+ then $a
550+ else calc($a, $l[$i])
551+
552+ func $f0_2 ($a,$i) = if (($i >= $s))
553+ then $a
554+ else throw("List size exceeds 15")
555+
556+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15)
557+ }
558+ let y = $t02256322610._1
559+ let found = $t02256322610._2
560+ if ((found != unit))
561+ then y
562+ else throw(("Y calculation error, Y = " + toString(y)))
563+ }
564+
565+
566+func calcPutOneTkn (pmtAmtRaw,pmtAssetId,userAddress,txId) = {
567+ let poolConfig = gpc()
568+ let amId = poolConfig[idxAmAsId]
569+ let prId = poolConfig[idxPrAsId]
570+ let lpId = poolConfig[idxLPAsId]
571+ let amtDcm = parseIntValue(poolConfig[idxAmtAsDcm])
572+ let priceDcm = parseIntValue(poolConfig[idxPriceAsDcm])
573+ let lpAssetEmission = toBigInt(valueOrErrorMessage(assetInfo(fromBase58String(lpId)), "invalid lp asset").quantity)
574+ let chechEmission = if ((lpAssetEmission > big0))
575+ then true
576+ else throw("initial deposit requires all coins")
577+ if ((chechEmission == chechEmission))
578+ then {
579+ let amBalance = getAccBalance(amId)
580+ let prBalance = getAccBalance(prId)
581+ let $t02336923831 = if ((txId == ""))
582+ then $Tuple2(amBalance, prBalance)
583+ else if ((pmtAssetId == amId))
584+ then if ((pmtAmtRaw > amBalance))
585+ then throw("invalid payment amount")
586+ else $Tuple2((amBalance - pmtAmtRaw), prBalance)
587+ else if ((pmtAssetId == prId))
588+ then if ((pmtAmtRaw > prBalance))
589+ then throw("invalid payment amount")
590+ else $Tuple2(amBalance, (prBalance - pmtAmtRaw))
591+ else throw("wrong pmtAssetId")
592+ let amBalanceOld = $t02336923831._1
593+ let prBalanceOld = $t02336923831._2
594+ let $t02383724013 = if ((pmtAssetId == amId))
595+ then $Tuple2(pmtAmtRaw, 0)
596+ else if ((pmtAssetId == prId))
597+ then $Tuple2(0, pmtAmtRaw)
598+ else throw("invalid payment")
599+ let amAmountRaw = $t02383724013._1
600+ let prAmountRaw = $t02383724013._2
601+ let amAmount = takeFee(amAmountRaw)._1
602+ let prAmount = takeFee(prAmountRaw)._1
603+ let feeAmount = takeFee(pmtAmtRaw)._2
604+ let amBalanceNew = (amBalanceOld + amAmount)
605+ let prBalanceNew = (prBalanceOld + prAmount)
606+ let D0 = getD([toBigInt(amBalanceOld), toBigInt(prBalanceOld)])
607+ let D1 = getD([toBigInt(amBalanceNew), toBigInt(prBalanceNew)])
608+ let checkD = if ((D1 > D0))
609+ then true
610+ else throw()
611+ if ((checkD == checkD))
612+ then {
613+ let lpAmount = fraction(lpAssetEmission, (D1 - D0), D0)
614+ let curPrice = f1(cpbi(t1(prBalanceNew, priceDcm), t1(amBalanceNew, amtDcm)), scale8)
615+ let commonState = [IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice), StringEntry(pau(userAddress, txId), dataPutActionInfo(amAmountRaw, prAmountRaw, toInt(lpAmount), curPrice, 0, 0, height, lastBlock.timestamp, 0, 0))]
616+ let poolProportion = fraction(prBalanceOld, scale8, amBalanceOld)
617+ let amountAssetPart = fraction(pmtAmtRaw, scale8, (poolProportion + scale8))
618+ let priceAssetPart = (pmtAmtRaw - amountAssetPart)
619+ let lpAmtBoth = fraction(lpAssetEmission, toBigInt(priceAssetPart), toBigInt(prBalanceOld))
620+ let bonus = toInt(fraction((lpAmount - lpAmtBoth), scale8BigInt, lpAmtBoth))
621+ $Tuple4(toInt(lpAmount), commonState, feeAmount, bonus)
622+ }
623+ else throw("Strict value is not equal to itself.")
624+ }
625+ else throw("Strict value is not equal to itself.")
626+ }
627+
628+
629+func getOneTknV2Internal (outAssetId,minOutAmount,payments,caller,originCaller,transactionId) = if ((size(payments) != 1))
630+ then throw("1 pmnt expd")
631+ else {
632+ let poolConfig = gpc()
633+ let lpId = poolConfig[idxLPAsId]
634+ let amId = poolConfig[idxAmAsId]
635+ let prId = poolConfig[idxPrAsId]
636+ let amDecimals = parseIntValue(poolConfig[idxAmtAsDcm])
637+ let prDecimals = parseIntValue(poolConfig[idxPriceAsDcm])
638+ let poolStatus = poolConfig[idxPoolSt]
639+ let userAddress = if ((caller == this))
640+ then originCaller
641+ else caller
642+ let pmt = value(payments[0])
643+ let pmtAssetId = value(pmt.assetId)
644+ let pmtAmt = pmt.amount
645+ if ((1000000000 > pmtAmt))
646+ then throw("Min pmt 10 LP")
647+ else {
648+ let txId58 = toBase58String(transactionId)
649+ if ((lpId != toBase58String(pmtAssetId)))
650+ then throw("Wrong LP")
651+ else {
652+ let amBalance = getAccBalance(amId)
653+ let prBalance = getAccBalance(prId)
654+ let $t02625626364 = {
655+ let @ = invoke(this, "getOneTknV2READONLY", [outAssetId, pmtAmt], nil)
656+ if ($isInstanceOf(@, "(Int, Int)"))
657+ then @
658+ else throw(($getType(@) + " couldn't be cast to (Int, Int)"))
659+ }
660+ let totalGet = $t02625626364._1
661+ let feeAmount = $t02625626364._2
662+ let totalAmount = if (if ((minOutAmount > 0))
663+ then (minOutAmount > totalGet)
664+ else false)
665+ then throw(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
666+ else totalGet
667+ let $t02655126858 = if ((outAssetId == amId))
668+ then $Tuple4(totalAmount, 0, ((amBalance - totalAmount) - feeAmount), prBalance)
669+ else if ((outAssetId == prId))
670+ then $Tuple4(0, totalAmount, amBalance, ((prBalance - totalAmount) - feeAmount))
671+ else throw("invalid out asset id")
672+ let outAm = $t02655126858._1
673+ let outPr = $t02655126858._2
674+ let amBalanceNew = $t02655126858._3
675+ let prBalanceNew = $t02655126858._4
676+ let curPrX18 = cpbi(t1(prBalanceNew, prDecimals), t1(amBalanceNew, amDecimals))
677+ let curPr = f1(curPrX18, scale8)
678+ let outAssetIdOrWaves = if ((outAssetId == "WAVES"))
679+ then unit
680+ else fromBase58String(outAssetId)
681+ let sendFeeToMatcher = if ((feeAmount > 0))
682+ then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetIdOrWaves)]
683+ else nil
684+ let state = ([ScriptTransfer(userAddress, totalAmount, outAssetIdOrWaves), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAm, outPr, pmtAmt, curPr, height, lastBlock.timestamp)), IntegerEntry(pl(), curPr), IntegerEntry(ph(height, lastBlock.timestamp), curPr)] ++ sendFeeToMatcher)
685+ if ((state == state))
686+ then {
687+ let burn = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
688+ if ((burn == burn))
689+ then $Tuple2(state, totalAmount)
690+ else throw("Strict value is not equal to itself.")
691+ }
692+ else throw("Strict value is not equal to itself.")
693+ }
694+ }
695+ }
432696
433697
434698 func m () = match getString(mpk()) {
435699 case s: String =>
436700 fromBase58String(s)
437701 case _: Unit =>
438702 unit
439703 case _ =>
440704 throw("Match error")
441705 }
442706
443707
444708 func pm () = match getString(pmpk()) {
445709 case s: String =>
446710 fromBase58String(s)
447711 case _: Unit =>
448712 unit
449713 case _ =>
450714 throw("Match error")
451715 }
452716
453717
454718 let pd = throw("Permission denied")
455719
456720 func mm (i) = match m() {
457721 case pk: ByteVector =>
458722 if ((i.callerPublicKey == pk))
459723 then true
460724 else pd
461725 case _: Unit =>
462726 if ((i.caller == this))
463727 then true
464728 else pd
465729 case _ =>
466730 throw("Match error")
467731 }
468732
469733
470734 @Callable(i)
471735 func constructor (fc) = {
472736 let c = mm(i)
473737 if ((c == c))
474738 then [StringEntry(fc(), fc)]
475739 else throw("Strict value is not equal to itself.")
476740 }
477741
478742
479743
480744 @Callable(i)
481745 func setManager (pendingManagerPublicKey) = {
482746 let c = mm(i)
483747 if ((c == c))
484748 then {
485749 let cm = fromBase58String(pendingManagerPublicKey)
486750 if ((cm == cm))
487751 then [StringEntry(pmpk(), pendingManagerPublicKey)]
488752 else throw("Strict value is not equal to itself.")
489753 }
490754 else throw("Strict value is not equal to itself.")
491755 }
492756
493757
494758
495759 @Callable(i)
496760 func confirmManager () = {
497761 let p = pm()
498762 let hpm = if (isDefined(p))
499763 then true
500764 else throw("No pending manager")
501765 if ((hpm == hpm))
502766 then {
503767 let cpm = if ((i.callerPublicKey == value(p)))
504768 then true
505769 else throw("You are not pending manager")
506770 if ((cpm == cpm))
507771 then [StringEntry(mpk(), toBase58String(value(p))), DeleteEntry(pmpk())]
508772 else throw("Strict value is not equal to itself.")
509773 }
510774 else throw("Strict value is not equal to itself.")
511775 }
512776
513777
514778
515779 @Callable(i)
516780 func put (slip,autoStake) = {
517781 let factCfg = gfc()
518782 let stakingCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactStakCntr]), "Wr st addr")
519783 let slipCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactSlippCntr]), "Wr sl addr")
520784 if ((0 > slip))
521785 then throw("Wrong slippage")
522786 else if ((size(i.payments) != 2))
523787 then throw("2 pmnts expd")
524788 else {
525- let e = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(value(i.payments[0]).assetId, value(i.payments[0]).amount), i.payments[1], slip, true, false, 0, "")
789+ let e = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(value(i.payments[0]).assetId, value(i.payments[0]).amount), i.payments[1], slip, true, false, true, 0, "")
526790 let emitLpAmt = e._2
527791 let lpAssetId = e._7
528792 let state = e._9
529793 let amDiff = e._10
530794 let prDiff = e._11
531795 let amId = e._12
532796 let prId = e._13
533797 let r = invoke(fca, "emit", [emitLpAmt], nil)
534798 if ((r == r))
535799 then {
536800 let el = match r {
537801 case legacy: Address =>
538802 invoke(legacy, "emit", [emitLpAmt], nil)
539803 case _ =>
540804 unit
541805 }
542806 if ((el == el))
543807 then {
544808 let sa = if ((amDiff > 0))
545809 then invoke(slipCntr, "put", nil, [AttachedPayment(amId, amDiff)])
546810 else nil
547811 if ((sa == sa))
548812 then {
549813 let sp = if ((prDiff > 0))
550814 then invoke(slipCntr, "put", nil, [AttachedPayment(prId, prDiff)])
551815 else nil
552816 if ((sp == sp))
553817 then {
554818 let lpTrnsfr = if (autoStake)
555819 then {
556820 let ss = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
557821 if ((ss == ss))
558822 then nil
559823 else throw("Strict value is not equal to itself.")
560824 }
561825 else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
562826 (state ++ lpTrnsfr)
563827 }
564828 else throw("Strict value is not equal to itself.")
565829 }
566830 else throw("Strict value is not equal to itself.")
567831 }
568832 else throw("Strict value is not equal to itself.")
569833 }
570834 else throw("Strict value is not equal to itself.")
571835 }
572836 }
573837
574838
575839
576840 @Callable(i)
577-func putOneTkn (amAssetPart,prAssetPart,outLp,slippage,autoStake) = {
578- let cfg = gfc()
579- let stakingCntr = valueOrErrorMessage(addressFromString(cfg[idxFactStakCntr]), "Wr st addr")
580- let slipCntr = valueOrErrorMessage(addressFromString(cfg[idxFactSlippCntr]), "Wr sl addr")
581- let gwxCntr = valueOrErrorMessage(addressFromString(cfg[idxFactGwxRewCntr]), "Wr gwx addr")
582- let poolCfg = gpc()
583- let amId = poolCfg[idxAmAsId]
584- let prId = poolCfg[idxPrAsId]
585- let amDcm = parseIntValue(poolCfg[idxAmtAsDcm])
586- let prDcm = parseIntValue(poolCfg[idxPriceAsDcm])
587- let addon = valueOrElse(getString(this, ada()), "")
588- let userAddress = if ((addon == toString(i.caller)))
589- then i.originCaller
590- else i.caller
591- let addonContract = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(ada()), "no addons")), "addon address in not valid")
592- let check = reentrantInvoke(addonContract, "ensureCanPutOneTkn", [toString(userAddress)], nil)
593- if ((check == check))
594- then if (if (if (if ((0 >= slippage))
595- then true
596- else (0 >= amAssetPart))
597- then true
598- else (0 >= prAssetPart))
599- then true
600- else (0 >= outLp))
601- then throw("Wrong params")
602- else if ((size(i.payments) != 1))
603- then throw("1 pmnt expd")
604- else {
605- let pmt = value(i.payments[0])
606- let pmtAssetId = toBase58String(value(pmt.assetId))
607- let pmtAmt = pmt.amount
608- if ((10000000 > pmtAmt))
609- then throw("Wrong pmt amt")
610- else {
611- let amBalance = getAccBalance(amId)
612- let prBalance = getAccBalance(prId)
613- let $t02485925435 = if ((pmtAssetId == amId))
614- then if (if ((pmtAmt > amBalance))
615- then true
616- else (amAssetPart > pmtAmt))
617- then throw("invalid payment amount")
618- else $Tuple6((amBalance - pmtAmt), prBalance, (pmtAmt - amAssetPart), prAssetPart, 0, 0)
619- else if ((pmtAssetId == prId))
620- then if (if ((pmtAmt > prBalance))
621- then true
622- else (prAssetPart > pmtAmt))
623- then throw("invalid payment amount")
624- else $Tuple6(amBalance, (prBalance - pmtAmt), 0, 0, (pmtAmt - prAssetPart), amAssetPart)
625- else throw("wrong pmtAssetId")
626- let amBalanceNow = $t02485925435._1
627- let prBalanceNow = $t02485925435._2
628- let virtSwapInAm = $t02485925435._3
629- let virtSwapOutPr = $t02485925435._4
630- let virtSwapInPr = $t02485925435._5
631- let virtSwapOutAm = $t02485925435._6
632- let D0 = invoke(gwxCntr, "calcD", [toString(amBalanceNow), toString(prBalanceNow), A, Amult, Dconv], nil)
633- let D1 = invoke(gwxCntr, "calcD", [toString(toBigInt(((amBalanceNow + virtSwapInAm) - virtSwapOutAm))), toString(toBigInt(((prBalanceNow + virtSwapInPr) - virtSwapOutPr))), A, Amult, Dconv], nil)
634- let D0vsD1 = vd(parseBigIntValue(str(D1)), parseBigIntValue(str(D0)), slippage4D)
635- if ((D0vsD1 == D0vsD1))
636- then {
637- let estPut = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(fromBase58String(amId), amAssetPart), AttachedPayment(fromBase58String(prId), prAssetPart), slippage, true, true, pmtAmt, pmtAssetId)
638- let estimLP = estPut._2
639- let lpAssetId = estPut._7
640- let state = estPut._9
641- let amDiff = estPut._10
642- let prDiff = estPut._11
643- let lpCalcRes = vad(toBigInt(estimLP), toBigInt(outLp), toBigInt(slippage))
644- let emitLpAmt = toInt(lpCalcRes._2)
645- let e = invoke(fca, "emit", [emitLpAmt], nil)
646- if ((e == e))
647- then {
648- let el = match e {
649- case legacy: Address =>
650- invoke(legacy, "emit", [emitLpAmt], nil)
651- case _ =>
652- unit
653- }
654- if ((el == el))
655- then {
656- let sa = if ((amDiff > 0))
657- then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(amId), amDiff)])
658- else nil
659- if ((sa == sa))
660- then {
661- let sp = if ((prDiff > 0))
662- then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(prId), prDiff)])
663- else nil
664- if ((sp == sp))
665- then {
666- let lpTrnsfr = if (autoStake)
667- then {
668- let ss = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
669- if ((ss == ss))
670- then nil
671- else throw("Strict value is not equal to itself.")
672- }
673- else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
674- (state ++ lpTrnsfr)
675- }
676- else throw("Strict value is not equal to itself.")
677- }
678- else throw("Strict value is not equal to itself.")
679- }
680- else throw("Strict value is not equal to itself.")
681- }
682- else throw("Strict value is not equal to itself.")
683- }
684- else throw("Strict value is not equal to itself.")
685- }
686- }
687- else throw("Strict value is not equal to itself.")
688- }
841+func putOneTknV2 (minOutAmount,autoStake) = if ((size(i.payments) != 1))
842+ then throw("1 pmnt expd")
843+ else {
844+ let poolConfig = gpc()
845+ let amId = poolConfig[idxAmAsId]
846+ let prId = poolConfig[idxPrAsId]
847+ let lpId = fromBase58String(poolConfig[idxLPAsId])
848+ let amDecimals = parseIntValue(poolConfig[idxAmtAsDcm])
849+ let prDecimals = parseIntValue(poolConfig[idxPriceAsDcm])
850+ let userAddress = if ((i.caller == this))
851+ then i.originCaller
852+ else i.caller
853+ let pmt = value(i.payments[0])
854+ let pmtAssetId = toBase58String(value(pmt.assetId))
855+ let pmtAmt = pmt.amount
856+ if ((10000000 > pmtAmt))
857+ then throw("Wrong pmt amt")
858+ else {
859+ let $t03173531860 = calcPutOneTkn(pmtAmt, pmtAssetId, toString(userAddress), toBase58String(i.transactionId))
860+ let estimLP = $t03173531860._1
861+ let state = $t03173531860._2
862+ let feeAmount = $t03173531860._3
863+ let emitLpAmt = if (if ((minOutAmount > 0))
864+ then (minOutAmount > estimLP)
865+ else false)
866+ then throw(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
867+ else estimLP
868+ let e = invoke(fca, "emit", [emitLpAmt], nil)
869+ if ((e == e))
870+ then {
871+ let el = match e {
872+ case legacy: Address =>
873+ invoke(legacy, "emit", [emitLpAmt], nil)
874+ case _ =>
875+ unit
876+ }
877+ if ((el == el))
878+ then {
879+ let lpTrnsfr = if (autoStake)
880+ then {
881+ let ss = invoke(stakingContract, "stake", nil, [AttachedPayment(lpId, emitLpAmt)])
882+ if ((ss == ss))
883+ then nil
884+ else throw("Strict value is not equal to itself.")
885+ }
886+ else [ScriptTransfer(i.caller, emitLpAmt, lpId)]
887+ let sendFeeToMatcher = if ((feeAmount > 0))
888+ then [ScriptTransfer(feeCollectorAddress, feeAmount, fromBase58String(pmtAssetId))]
889+ else nil
890+ $Tuple2(((state ++ lpTrnsfr) ++ sendFeeToMatcher), emitLpAmt)
891+ }
892+ else throw("Strict value is not equal to itself.")
893+ }
894+ else throw("Strict value is not equal to itself.")
895+ }
896+ }
689897
690898
691899
692900 @Callable(i)
693901 func putForFree (maxSlpg) = if ((0 > maxSlpg))
694902 then throw("Wrong slpg")
695903 else if ((size(i.payments) != 2))
696904 then throw("2 pmnts expd")
697905 else {
698- let estPut = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(value(i.payments[0]).assetId, value(i.payments[0]).amount), i.payments[1], maxSlpg, false, false, 0, "")
906+ let estPut = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(value(i.payments[0]).assetId, value(i.payments[0]).amount), i.payments[1], maxSlpg, false, false, true, 0, "")
699907 estPut._9
700908 }
701909
702910
703911
704912 @Callable(i)
705913 func get () = {
706914 let r = cg(i)
707915 let outAmtAmt = r._1
708916 let outPrAmt = r._2
709917 let pmtAmt = r._3
710918 let pmtAssetId = r._4
711919 let state = r._5
712920 let b = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
713921 if ((b == b))
714922 then state
715923 else throw("Strict value is not equal to itself.")
716924 }
717925
718926
719927
720928 @Callable(i)
721-func getOneTkn (exchResult,notUsed,outAmount,outAssetId,slippage) = if ((size(i.payments) != 1))
722- then throw("1 pmnt expd")
723- else {
724- let cfg = gpc()
725- let lpId = cfg[idxLPAsId]
726- let amId = cfg[idxAmAsId]
727- let prId = cfg[idxPrAsId]
728- let amDcm = parseIntValue(cfg[idxAmtAsDcm])
729- let prDcm = parseIntValue(cfg[idxPriceAsDcm])
730- let sts = cfg[idxPoolSt]
731- let factCfg = gfc()
732- let gwxCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactGwxRewCntr]), "Wr sl addr")
733- let pmt = value(i.payments[0])
734- let addon = valueOrElse(getString(this, ada()), "")
735- let userAddress = if ((addon == toString(i.caller)))
736- then i.originCaller
737- else i.caller
738- let txId58 = toBase58String(i.transactionId)
739- let pmtAssetId = value(pmt.assetId)
740- let pmtAmt = pmt.amount
741- let addonContract = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(ada()), "no addons")), "addon address in not valid")
742- let check = reentrantInvoke(addonContract, "ensureCanGetOneTkn", [toString(userAddress)], nil)
743- if ((check == check))
744- then if ((1000000000 > pmtAmt))
745- then throw("Min pmt 10 LP")
746- else if (if (if ((0 > slippage))
747- then true
748- else (0 > exchResult))
749- then true
750- else (0 > outAmount))
751- then throw("Wrong params")
752- else if ((lpId != toBase58String(pmtAssetId)))
753- then throw("Wrong LP")
754- else {
755- let r = ego(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
756- let estimAmAmt = r._1
757- let estimPrAmt = r._2
758- let amBalance = getAccBalance(amId)
759- let prBalance = getAccBalance(prId)
760- let $t03046630923 = if ((outAssetId == amId))
761- then $Tuple7((amBalance - estimAmAmt), (prBalance - estimPrAmt), exchResult, estimPrAmt, 0, 0, (estimAmAmt + exchResult))
762- else if ((outAssetId == prId))
763- then $Tuple7((amBalance - estimAmAmt), (prBalance - estimPrAmt), 0, 0, exchResult, estimAmAmt, (estimPrAmt + exchResult))
764- else throw("wrong outAssetId")
765- let amBalanceNow = $t03046630923._1
766- let prBalanceNow = $t03046630923._2
767- let virtSwapInAm = $t03046630923._3
768- let virtSwapOutPr = $t03046630923._4
769- let virtSwapInPr = $t03046630923._5
770- let virtSwapOutAm = $t03046630923._6
771- let totalGet = $t03046630923._7
772- if (if ((0 > virtSwapInAm))
773- then true
774- else (0 > virtSwapInPr))
775- then throw("Wrong calc")
776- else {
777- let D0 = invoke(gwxCntr, "calcD", [toString(amBalanceNow), toString(prBalanceNow), A, Amult, Dconv], nil)
778- let D1 = invoke(gwxCntr, "calcD", [toString(((amBalanceNow - virtSwapInAm) + virtSwapOutAm)), toString(((prBalanceNow + virtSwapOutPr) - virtSwapInPr)), A, Amult, Dconv], nil)
779- let D0vsD1 = vd(parseBigIntValue(str(D1)), parseBigIntValue(str(D0)), slippage4D)
780- if ((D0vsD1 == D0vsD1))
781- then {
782- let finalRes = vad(toBigInt(totalGet), toBigInt(outAmount), toBigInt(slippage))
783- if ((finalRes == finalRes))
784- then {
785- let $t03162831732 = if ((outAssetId == amId))
786- then $Tuple2(toInt(finalRes._2), 0)
787- else $Tuple2(0, toInt(finalRes._2))
788- let outAm = $t03162831732._1
789- let outPr = $t03162831732._2
790- let curPrX18 = cpbi(t1(prBalance, prDcm), t1(amBalance, amDcm))
791- let curPr = f1(curPrX18, scale8)
792- let state = [ScriptTransfer(userAddress, (outAm + outPr), if ((outAssetId == "WAVES"))
793- then unit
794- else fromBase58String(outAssetId)), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAm, outPr, pmtAmt, curPr, height, lastBlock.timestamp)), IntegerEntry(pl(), curPr), IntegerEntry(ph(height, lastBlock.timestamp), curPr)]
795- if ((state == state))
796- then {
797- let burn = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
798- if ((burn == burn))
799- then state
800- else throw("Strict value is not equal to itself.")
801- }
802- else throw("Strict value is not equal to itself.")
803- }
804- else throw("Strict value is not equal to itself.")
805- }
806- else throw("Strict value is not equal to itself.")
807- }
808- }
809- else throw("Strict value is not equal to itself.")
929+func getOneTknV2 (outAssetId,minOutAmount) = {
930+ let $t03404334198 = getOneTknV2Internal(outAssetId, minOutAmount, i.payments, i.caller, i.originCaller, i.transactionId)
931+ let state = $t03404334198._1
932+ let totalAmount = $t03404334198._2
933+ $Tuple2(state, totalAmount)
934+ }
935+
936+
937+
938+@Callable(i)
939+func getOneTknV2READONLY (outAssetId,lpAssetAmount) = {
940+ let poolConfig = gpc()
941+ let amId = poolConfig[idxAmAsId]
942+ let prId = poolConfig[idxPrAsId]
943+ let lpId = poolConfig[idxLPAsId]
944+ let xp = [toBigInt(getAccBalance(amId)), toBigInt(getAccBalance(prId))]
945+ let lpEmission = toBigInt(valueOrErrorMessage(assetInfo(fromBase58String(lpId)), "invalid lp asset").quantity)
946+ let D0 = getD(xp)
947+ let D1 = (D0 - fraction(toBigInt(lpAssetAmount), D0, lpEmission))
948+ let index = if ((outAssetId == amId))
949+ then 0
950+ else if ((outAssetId == prId))
951+ then 1
952+ else throw("invalid out asset id")
953+ let newY = getYD(xp, index, D1)
954+ let dy = (xp[index] - newY)
955+ let totalGetRaw = toInt((dy - big1))
956+ let $t03497735026 = takeFee(totalGetRaw)
957+ let totalGet = $t03497735026._1
958+ let feeAmount = $t03497735026._2
959+ $Tuple2(nil, $Tuple2(totalGet, feeAmount))
960+ }
961+
962+
963+
964+@Callable(i)
965+func getOneTknV2WithBonusREADONLY (outAssetId,lpAssetAmount) = {
966+ let poolConfig = gpc()
967+ let amId = poolConfig[idxAmAsId]
968+ let prId = poolConfig[idxPrAsId]
969+ let lpId = poolConfig[idxLPAsId]
970+ let amBalance = getAccBalance(amId)
971+ let prBalance = getAccBalance(prId)
972+ let $t03537135486 = {
973+ let @ = invoke(this, "getOneTknV2READONLY", [outAssetId, lpAssetAmount], nil)
974+ if ($isInstanceOf(@, "(Int, Int)"))
975+ then @
976+ else throw(($getType(@) + " couldn't be cast to (Int, Int)"))
810977 }
978+ let totalGet = $t03537135486._1
979+ let feeAmount = $t03537135486._2
980+ let r = ego("", lpId, lpAssetAmount, this)
981+ let outAmAmt = r._1
982+ let outPrAmt = r._2
983+ let sumOfGetAssets = (outAmAmt + outPrAmt)
984+ let bonus = fraction((totalGet - sumOfGetAssets), scale8, sumOfGetAssets)
985+ $Tuple2(nil, $Tuple3(totalGet, feeAmount, bonus))
986+ }
811987
812988
813989
814990 @Callable(i)
815991 func getNoLess (noLessThenAmtAsset,noLessThenPriceAsset) = {
816992 let r = cg(i)
817993 let outAmAmt = r._1
818994 let outPrAmt = r._2
819995 let pmtAmt = r._3
820996 let pmtAssetId = r._4
821997 let state = r._5
822998 if ((noLessThenAmtAsset > outAmAmt))
823999 then throw(((("Failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
8241000 else if ((noLessThenPriceAsset > outPrAmt))
8251001 then throw(((("Failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
8261002 else {
8271003 let burnLPAssetOnFactory = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
8281004 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
8291005 then state
8301006 else throw("Strict value is not equal to itself.")
8311007 }
8321008 }
8331009
8341010
8351011
8361012 @Callable(i)
8371013 func unstakeAndGet (amount) = {
8381014 let checkPayments = if ((size(i.payments) != 0))
8391015 then throw("No pmnts expd")
8401016 else true
8411017 if ((checkPayments == checkPayments))
8421018 then {
8431019 let cfg = gpc()
8441020 let factoryCfg = gfc()
8451021 let lpAssetId = fromBase58String(cfg[idxLPAsId])
8461022 let staking = valueOrErrorMessage(addressFromString(factoryCfg[idxFactStakCntr]), "Wr st addr")
8471023 let unstakeInv = invoke(staking, "unstake", [toBase58String(lpAssetId), amount], nil)
8481024 if ((unstakeInv == unstakeInv))
8491025 then {
8501026 let r = ego(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
8511027 let sts = parseIntValue(r._9)
8521028 let state = r._10
8531029 let v = if (if (igs())
8541030 then true
8551031 else (sts == PoolShutdown))
8561032 then throw(("Blocked: " + toString(sts)))
8571033 else true
8581034 if ((v == v))
8591035 then {
8601036 let burnA = invoke(fca, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
8611037 if ((burnA == burnA))
8621038 then state
8631039 else throw("Strict value is not equal to itself.")
8641040 }
8651041 else throw("Strict value is not equal to itself.")
8661042 }
8671043 else throw("Strict value is not equal to itself.")
8681044 }
8691045 else throw("Strict value is not equal to itself.")
8701046 }
8711047
8721048
8731049
8741050 @Callable(i)
1051+func unstakeAndGetOneTknV2 (unstakeAmount,outAssetId,minOutAmount) = {
1052+ let checkPayments = if ((size(i.payments) != 0))
1053+ then throw("No pmnts expd")
1054+ else true
1055+ if ((checkPayments == checkPayments))
1056+ then {
1057+ let cfg = gpc()
1058+ let factoryCfg = gfc()
1059+ let lpAssetId = fromBase58String(cfg[idxLPAsId])
1060+ let staking = valueOrErrorMessage(addressFromString(factoryCfg[idxFactStakCntr]), "Wr st addr")
1061+ let unstakeInv = invoke(staking, "unstake", [toBase58String(lpAssetId), unstakeAmount], nil)
1062+ if ((unstakeInv == unstakeInv))
1063+ then {
1064+ let $t03779337981 = getOneTknV2Internal(outAssetId, minOutAmount, [AttachedPayment(lpAssetId, unstakeAmount)], i.caller, i.originCaller, i.transactionId)
1065+ let state = $t03779337981._1
1066+ let totalAmount = $t03779337981._2
1067+ $Tuple2(state, totalAmount)
1068+ }
1069+ else throw("Strict value is not equal to itself.")
1070+ }
1071+ else throw("Strict value is not equal to itself.")
1072+ }
1073+
1074+
1075+
1076+@Callable(i)
1077+func putOneTknV2WithBonusREADONLY (paymentAmountRaw,paymentAssetId) = {
1078+ let poolConfig = gpc()
1079+ let amId = poolConfig[idxAmAsId]
1080+ let prId = poolConfig[idxPrAsId]
1081+ let lpId = poolConfig[idxLPAsId]
1082+ let $t03824038337 = calcPutOneTkn(paymentAmountRaw, paymentAssetId, "", "")
1083+ let lpAmount = $t03824038337._1
1084+ let state = $t03824038337._2
1085+ let feeAmount = $t03824038337._3
1086+ let bonus = $t03824038337._4
1087+ $Tuple2(nil, $Tuple3(lpAmount, feeAmount, bonus))
1088+ }
1089+
1090+
1091+
1092+@Callable(i)
8751093 func activate (amtAsStr,prAsStr) = if ((toString(i.caller) != toString(fca)))
8761094 then throw("denied")
8771095 else $Tuple2([StringEntry(aa(), amtAsStr), StringEntry(pa(), prAsStr)], "success")
8781096
8791097
8801098
8811099 @Callable(i)
8821100 func setS (k,v) = if ((toString(i.caller) != strf(this, ada())))
8831101 then pd
8841102 else [StringEntry(k, v)]
8851103
8861104
8871105
8881106 @Callable(i)
8891107 func setI (k,v) = if ((toString(i.caller) != strf(this, ada())))
8901108 then pd
8911109 else [IntegerEntry(k, v)]
8921110
8931111
8941112
8951113 @Callable(i)
8961114 func getPoolConfigWrapperREADONLY () = $Tuple2(nil, gpc())
8971115
8981116
8991117
9001118 @Callable(i)
9011119 func getAccBalanceWrapperREADONLY (assetId) = $Tuple2(nil, getAccBalance(assetId))
9021120
9031121
9041122
9051123 @Callable(i)
9061124 func calcPricesWrapperREADONLY (amAmt,prAmt,lpAmt) = {
9071125 let pr = calcPrices(amAmt, prAmt, lpAmt)
9081126 $Tuple2(nil, [toString(pr[0]), toString(pr[1]), toString(pr[2])])
9091127 }
9101128
9111129
9121130
9131131 @Callable(i)
9141132 func fromX18WrapperREADONLY (val,resScaleMult) = $Tuple2(nil, f1(parseBigIntValue(val), resScaleMult))
9151133
9161134
9171135
9181136 @Callable(i)
9191137 func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(t1(origVal, origScaleMult)))
9201138
9211139
9221140
9231141 @Callable(i)
9241142 func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(cpbi(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
9251143
9261144
9271145
9281146 @Callable(i)
929-func estimatePutOperationWrapperREADONLY (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,usrAddr,isEval,emitLp) = $Tuple2(nil, epo(txId58, slippage, inAmAmt, inAmId, inPrAmt, inPrId, usrAddr, isEval, emitLp, false, 0, ""))
1147+func estimatePutOperationWrapperREADONLY (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,usrAddr,isEval,emitLp) = $Tuple2(nil, epo(txId58, slippage, inAmAmt, inAmId, inPrAmt, inPrId, usrAddr, isEval, emitLp, true, false, 0, ""))
9301148
9311149
9321150
9331151 @Callable(i)
9341152 func estimateGetOperationWrapperREADONLY (txId58,pmtAsId,pmtLpAmt,usrAddr) = {
9351153 let r = ego(txId58, pmtAsId, pmtLpAmt, addressFromStringValue(usrAddr))
9361154 $Tuple2(nil, $Tuple10(r._1, r._2, r._3, r._4, r._5, r._6, r._7, toString(r._8), r._9, r._10))
9371155 }
1156+
1157+
1158+
1159+@Callable(i)
1160+func getFeeREADONLY () = $Tuple2(nil, fee)
9381161
9391162
9401163 @Verifier(tx)
9411164 func verify () = {
9421165 let targetPublicKey = match m() {
9431166 case pk: ByteVector =>
9441167 pk
9451168 case _: Unit =>
9461169 tx.senderPublicKey
9471170 case _ =>
9481171 throw("Match error")
9491172 }
9501173 match tx {
9511174 case order: Order =>
9521175 let matcherPub = mp()
9531176 let orderValid = moa(order)
9541177 let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
9551178 let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
9561179 if (if (if (orderValid)
9571180 then senderValid
9581181 else false)
9591182 then matcherValid
9601183 else false)
9611184 then true
9621185 else toe(orderValid, senderValid, matcherValid)
9631186 case s: SetScriptTransaction =>
9641187 let newHash = blake2b256(value(s.script))
9651188 let allowedHash = fromBase64String(value(getString(fca, keyAllowedLpStableScriptHash())))
9661189 let currentHash = scriptHash(this)
9671190 if (if ((allowedHash == newHash))
9681191 then (currentHash != newHash)
9691192 else false)
9701193 then true
9711194 else sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
9721195 case _ =>
9731196 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
9741197 }
9751198 }
9761199

github/deemru/w8io/786bc32 
115.52 ms