tx · FMS6w7BGyn5VFdu3yVE6gM682UXaoiJv9wY2FB3oNUPp

3MxWgDbE9EmjQj8b3LfFwa91FZizptyeQXS:  -0.10000000 Waves

2022.10.11 15:24 [2267668] smart account 3MxWgDbE9EmjQj8b3LfFwa91FZizptyeQXS > SELF 0.00000000 Waves

{ "type": 13, "id": "FMS6w7BGyn5VFdu3yVE6gM682UXaoiJv9wY2FB3oNUPp", "fee": 10000000, "feeAssetId": null, "timestamp": 1665491100127, "version": 2, "chainId": 84, "sender": "3MxWgDbE9EmjQj8b3LfFwa91FZizptyeQXS", "senderPublicKey": "C7xgcYqQ8qV8rmvzAjhQWq4cz82F6VJfXMNygvrTXsfW", "proofs": [ "3vEuraXjqNr9e1yTCqAGSKMccXQxzNknUSehzN6kt9UnbD4U1F6rgrRufTfvj6W1rLQ7GKPnYZoSy6DMqTRVcoSk" ], "script": "base64:BgJlCAISBAoCEQESBQoDCAEBEgQKAgEEEgQKAhEIEgMKAQESBgoECAgBCBIECgIIARIDCgEREgQKAhEBEgUKAwEICBIECgIIARIFCgMIAQESABIAEgQKAhEEEgQKAgEBEgASABIAEgBXAAlQUkVDSVNJT04AwIQ9AAVNQVhfQQDAhD0ADE1BWF9BX0NIQU5HRQAKAAhERUNJTUFMUwAGAA1NSU5fUkFNUF9USU1FCQBpAgCAowUAPAAHdmVyc2lvbgIFMy4wLjAACGtWZXJzaW9uAgd2ZXJzaW9uAAdrQXNzZXRzAglhc3NldF9pZHMADWtBc3NldEJhbGFuY2UCCF9iYWxhbmNlAAdrQWN0aXZlAgZhY3RpdmUABmtDYXVzZQIOc2h1dGRvd25fY2F1c2UADWtTaGFyZUFzc2V0SWQCDnNoYXJlX2Fzc2V0X2lkABFrU2hhcmVBc3NldFN1cHBseQISc2hhcmVfYXNzZXRfc3VwcGx5AARrRmVlAgpjb21taXNzaW9uABJrREFwcFRocmVzaG9sZENvZWYCEWRBcHBUaHJlc2hvbGRDb2VmAAxrVVNETkFkZHJlc3MCGHN0YWtpbmdfdXNkbm5zYnRfYWRkcmVzcwAKa0Rpc2NvdW50cwIJZGlzY291bnRzAA9rRGlzY291bnRWYWx1ZXMCD2Rpc2NvdW50X3ZhbHVlcwAOa1VzZXJTd29wSW5Hb3YCDF9TV09QX2Ftb3VudAANa0FkbWluUHViS2V5MQILYWRtaW5fcHViXzEADWtBZG1pblB1YktleTICC2FkbWluX3B1Yl8yAA1rQWRtaW5QdWJLZXkzAgthZG1pbl9wdWJfMwASa0FkbWluSW52b2tlUHViS2V5AhBhZG1pbl9pbnZva2VfcHViABBrTW9uZXlCb3hBZGRyZXNzAhFtb25leV9ib3hfYWRkcmVzcwALa0dvdkFkZHJlc3MCEmdvdmVybmFuY2VfYWRkcmVzcwAOa1ZvdGluZ0FkZHJlc3MCDnZvdGluZ19hZGRyZXNzAA9rRmFybWluZ0FkZHJlc3MCD2Zhcm1pbmdfYWRkcmVzcwARa0xQRmFybWluZ0FkZHJlc3MCCmxwX2Zhcm1pbmcABm9yYWNsZQkBB0FkZHJlc3MBARoBVEgTlwzA0zPMJTKAtin3p2RogKvjzHtLmQETZ2V0QmFzZTU4RnJvbU9yYWNsZQEDa2V5BAckbWF0Y2gwCQCdCAIFBm9yYWNsZQUDa2V5AwkAAQIFByRtYXRjaDACBlN0cmluZwQGc3RyaW5nBQckbWF0Y2gwCQDZBAEFBnN0cmluZwQHbm90aGluZwUHJG1hdGNoMAkAAgEJAKwCAgUDa2V5AghpcyBlbXB0eQAMYWRtaW5QdWJLZXkxCQETZ2V0QmFzZTU4RnJvbU9yYWNsZQEFDWtBZG1pblB1YktleTEADGFkbWluUHViS2V5MgkBE2dldEJhc2U1OEZyb21PcmFjbGUBBQ1rQWRtaW5QdWJLZXkyAAxhZG1pblB1YktleTMJARNnZXRCYXNlNThGcm9tT3JhY2xlAQUNa0FkbWluUHViS2V5MwARYWRtaW5QdWJLZXlJbnZva2UJARNnZXRCYXNlNThGcm9tT3JhY2xlAQUSa0FkbWluSW52b2tlUHViS2V5AA9tb25leUJveEFkZHJlc3MJAQdBZGRyZXNzAQkBE2dldEJhc2U1OEZyb21PcmFjbGUBBRBrTW9uZXlCb3hBZGRyZXNzAApnb3ZBZGRyZXNzCQEHQWRkcmVzcwEJARNnZXRCYXNlNThGcm9tT3JhY2xlAQULa0dvdkFkZHJlc3MAEnN0YWtpbmdVU0ROQWRkcmVzcwkBB0FkZHJlc3MBCQETZ2V0QmFzZTU4RnJvbU9yYWNsZQEFDGtVU0ROQWRkcmVzcwANdm90aW5nQWRkcmVzcwkBB0FkZHJlc3MBCQETZ2V0QmFzZTU4RnJvbU9yYWNsZQEFDmtWb3RpbmdBZGRyZXNzAA5mYXJtaW5nQWRkcmVzcwkBB0FkZHJlc3MBCQETZ2V0QmFzZTU4RnJvbU9yYWNsZQEFD2tGYXJtaW5nQWRkcmVzcwAQbHBGYXJtaW5nQWRkcmVzcwkBB0FkZHJlc3MBCQETZ2V0QmFzZTU4RnJvbU9yYWNsZQEFEWtMUEZhcm1pbmdBZGRyZXNzAARVU0ROASBvJKPKqzDcUimY6CxhWu5afyNNwi11u+mdqlTg0tAHwQANc3Rha2luZ0Fzc2V0cwkAzAgCCQDYBAEFBFVTRE4FA25pbAAGYWN0aXZlCQERQGV4dHJOYXRpdmUoMTA1MSkCBQR0aGlzBQdrQWN0aXZlAAxzaGFyZUFzc2V0SWQJANkEAQkBEUBleHRyTmF0aXZlKDEwNTMpAgUEdGhpcwUNa1NoYXJlQXNzZXRJZAALc2hhcmVTdXBwbHkJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMFEWtTaGFyZUFzc2V0U3VwcGx5AAlmZWVTY2FsZTYAwIQ9AANmZWUJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMFBGtGZWUADWZlZUdvdmVybmFuY2UJAGsDACgFCWZlZVNjYWxlNgBkAAlpbml0aWFsX0EJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMCCWluaXRpYWxfQQAIZnV0dXJlX0EJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMCCGZ1dHVyZV9BAA5pbml0aWFsX0FfdGltZQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzAg5pbml0aWFsX0FfdGltZQAAAA1mdXR1cmVfQV90aW1lCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMCDWZ1dHVyZV9BX3RpbWUAAAAIYXNzZXRJZHMJALUJAgkBEUBleHRyTmF0aXZlKDEwNTMpAgUEdGhpcwUHa0Fzc2V0cwIBLAAGbkNvaW5zCQCQAwEFCGFzc2V0SWRzAQdzdXNwZW5kAQVjYXVzZQkAzAgCCQEMQm9vbGVhbkVudHJ5AgUHa0FjdGl2ZQcJAMwIAgkBC1N0cmluZ0VudHJ5AgUGa0NhdXNlBQVjYXVzZQUDbmlsAQ10aHJvd0lzQWN0aXZlAAkAAgECFkRBcHAgaXMgYWxyZWFkeSBhY3RpdmUBCGlzQWN0aXZlAAMFBmFjdGl2ZQUEdW5pdAkAAgECH0RBcHAgaXMgaW5hY3RpdmUgYXQgdGhpcyBtb21lbnQBC2lzQWRtaW5DYWxsAQFpAwkBD2NvbnRhaW5zRWxlbWVudAIJAMwIAgUMYWRtaW5QdWJLZXkxCQDMCAIFDGFkbWluUHViS2V5MgkAzAgCBQxhZG1pblB1YktleTMFA25pbAgFAWkPY2FsbGVyUHVibGljS2V5BQR1bml0CQACAQIhT25seSBhZG1pbiBjYW4gY2FsbCB0aGlzIGZ1bmN0aW9uAQppc1NlbGZDYWxsAQFpAwkAAAIFBHRoaXMIBQFpBmNhbGxlcgUEdW5pdAkAAgECK09ubHkgY29udHJhY3QgaXRzZWxmIGNhbiBjYWxsIHRoaXMgZnVuY3Rpb24ABGJpZzIJALYCAQACAAZpdGVyMTAJAMwIAgAACQDMCAIAAQkAzAgCAAIJAMwIAgADCQDMCAIABAkAzAgCAAUJAMwIAgAGCQDMCAIABwkAzAgCAAgJAMwIAgAJBQNuaWwABml0ZXIxNQkAzAgCAAAJAMwIAgABCQDMCAIAAgkAzAgCAAMJAMwIAgAECQDMCAIABQkAzAgCAAYJAMwIAgAHCQDMCAIACAkAzAgCAAkJAMwIAgAKCQDMCAIACwkAzAgCAAwJAMwIAgANCQDMCAIADgUDbmlsAAZpdGVyMTYJAMwIAgAACQDMCAIAAQkAzAgCAAIJAMwIAgADCQDMCAIABAkAzAgCAAUJAMwIAgAGCQDMCAIABwkAzAgCAAgJAMwIAgAJCQDMCAIACgkAzAgCAAsJAMwIAgAMCQDMCAIADQkAzAgCAA4JAMwIAgAPBQNuaWwADmJsb2NrVGltZXN0YW1wBQZoZWlnaHQBBmFzc2VydAEBYQMFAWEHBgEUY2FsY3VsYXRlRmVlRGlzY291bnQBCHVzZXJBZGRyBAR1c2VyBAckbWF0Y2gwBQh1c2VyQWRkcgMJAAECBQckbWF0Y2gwAgdBZGRyZXNzBAF1BQckbWF0Y2gwCQClCAEFAXUDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAF1BQckbWF0Y2gwBQF1CQACAQIYVW5rbm93IHR5cGUgb2YgdXNlciBBZGRyBApzd29wQW1vdW50CQELdmFsdWVPckVsc2UCCQCaCAIFCmdvdkFkZHJlc3MJAKwCAgUEdXNlcgUOa1VzZXJTd29wSW5Hb3YAAAQOZGlzY291bnRWYWx1ZXMJALUJAgkBEUBleHRyTmF0aXZlKDEwNTMpAgUGb3JhY2xlBQ9rRGlzY291bnRWYWx1ZXMCASwECWRpc2NvdW50cwkAtQkCCQERQGV4dHJOYXRpdmUoMTA1MykCBQZvcmFjbGUFCmtEaXNjb3VudHMCASwDAwkAZwIFCnN3b3BBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5kaXNjb3VudFZhbHVlcwAACQBmAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDmRpc2NvdW50VmFsdWVzAAEFCnN3b3BBbW91bnQHCQBlAgUJZmVlU2NhbGU2CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUJZGlzY291bnRzAAADAwkAZwIFCnN3b3BBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5kaXNjb3VudFZhbHVlcwABCQBmAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDmRpc2NvdW50VmFsdWVzAAIFCnN3b3BBbW91bnQHCQBlAgUJZmVlU2NhbGU2CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUJZGlzY291bnRzAAEDAwkAZwIFCnN3b3BBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5kaXNjb3VudFZhbHVlcwACCQBmAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDmRpc2NvdW50VmFsdWVzAAMFCnN3b3BBbW91bnQHCQBlAgUJZmVlU2NhbGU2CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUJZGlzY291bnRzAAIDAwkAZwIFCnN3b3BBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5kaXNjb3VudFZhbHVlcwADCQBmAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDmRpc2NvdW50VmFsdWVzAAQFCnN3b3BBbW91bnQHCQBlAgUJZmVlU2NhbGU2CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUJZGlzY291bnRzAAMDCQBnAgUKc3dvcEFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDmRpc2NvdW50VmFsdWVzAAQJAGUCBQlmZWVTY2FsZTYJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQlkaXNjb3VudHMABAUJZmVlU2NhbGU2AQJfQQAEAnQxBQ1mdXR1cmVfQV90aW1lBAJBMQUIZnV0dXJlX0EDCQBmAgUCdDEFDmJsb2NrVGltZXN0YW1wBAJBMAUJaW5pdGlhbF9BBAJ0MAUOaW5pdGlhbF9BX3RpbWUDCQBmAgUCQTEFAkEwCQBkAgUCQTAJAGkCCQBoAgkAZQIFAkExBQJBMAkAZQIFDmJsb2NrVGltZXN0YW1wBQJ0MAkAZQIFAnQxBQJ0MAkAZQIFAkEwCQBpAgkAaAIJAGUCBQJBMAUCQTEJAGUCBQ5ibG9ja1RpbWVzdGFtcAUCdDAJAGUCBQJ0MQUCdDAFAkExAQNf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ZXRTdHJBc3NldElkAQdhc3NldElkBAckbWF0Y2gwBQdhc3NldElkAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAmlkBQckbWF0Y2gwCQDYBAEFAmlkAwkAAQIFByRtYXRjaDACBFVuaXQEBXdhdmVzBQckbWF0Y2gwAgVXQVZFUwkAAgECC01hdGNoIGVycm9yARhjYWxjU3Rha2luZ0Z1bmNBbmRBZGRyZXMCBXN0YWtlB2Fzc2V0SWQDBQVzdGFrZQkAlAoCAgxsb2NrTmV1dHJpbm8FEnN0YWtpbmdVU0ROQWRkcmVzcwkAlAoCAg51bmxvY2tOZXV0cmlubwUSc3Rha2luZ1VTRE5BZGRyZXNzARFjYWxjU3Rha2luZ1BhcmFtcwMFc3Rha2UGYW1vdW50B2Fzc2V0SWQDBQVzdGFrZQQNJHQwMTA1NzAxMDYzNgkBGGNhbGNTdGFraW5nRnVuY0FuZEFkZHJlcwIFBXN0YWtlBQdhc3NldElkBARjYWxsCAUNJHQwMTA1NzAxMDYzNgJfMQQLc3Rha2luZ0FkZHIIBQ0kdDAxMDU3MDEwNjM2Al8yCQCWCgQFBGNhbGwFC3N0YWtpbmdBZGRyBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFB2Fzc2V0SWQFBmFtb3VudAUDbmlsBA0kdDAxMDcyMjEwNzg4CQEYY2FsY1N0YWtpbmdGdW5jQW5kQWRkcmVzAgUFc3Rha2UFB2Fzc2V0SWQEBGNhbGwIBQ0kdDAxMDcyMjEwNzg4Al8xBAtzdGFraW5nQWRkcggFDSR0MDEwNzIyMTA3ODgCXzIJAJYKBAUEY2FsbAULc3Rha2luZ0FkZHIJAMwIAgUGYW1vdW50CQDMCAIJANgEAQUHYXNzZXRJZAUDbmlsBQNuaWwBBXN0YWtlAgZhbW91bnQNYXNzZXRJZFN0cmluZwMJAQ9jb250YWluc0VsZW1lbnQCBQ1zdGFraW5nQXNzZXRzBQ1hc3NldElkU3RyaW5nBA0kdDAxMDk3NTExMDc3CQERY2FsY1N0YWtpbmdQYXJhbXMDBgUGYW1vdW50CQDZBAEFDWFzc2V0SWRTdHJpbmcEBGNhbGwIBQ0kdDAxMDk3NTExMDc3Al8xBARhZGRyCAUNJHQwMTA5NzUxMTA3NwJfMgQGcGFyYW1zCAUNJHQwMTA5NzUxMTA3NwJfMwQIcGF5bWVudHMIBQ0kdDAxMDk3NTExMDc3Al80CQD8BwQFBGFkZHIFBGNhbGwFBnBhcmFtcwUIcGF5bWVudHMAAAEHdW5zdGFrZQIGYW1vdW50DWFzc2V0SWRTdHJpbmcDCQEPY29udGFpbnNFbGVtZW50AgUNc3Rha2luZ0Fzc2V0cwUNYXNzZXRJZFN0cmluZwQNJHQwMTEyNjIxMTM2NQkBEWNhbGNTdGFraW5nUGFyYW1zAwcFBmFtb3VudAkA2QQBBQ1hc3NldElkU3RyaW5nBARjYWxsCAUNJHQwMTEyNjIxMTM2NQJfMQQEYWRkcggFDSR0MDExMjYyMTEzNjUCXzIEBnBhcmFtcwgFDSR0MDExMjYyMTEzNjUCXzMECHBheW1lbnRzCAUNJHQwMTEyNjIxMTM2NQJfNAkA/AcEBQRhZGRyBQRjYWxsBQZwYXJhbXMFCHBheW1lbnRzAAABDHN0YWtlZEFtb3VudAEHYXNzZXRJZAQWc3Rha2VkQW1vdW50Q2FsY3VsYXRlZAQHJG1hdGNoMAUHYXNzZXRJZAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBANhSWQFByRtYXRjaDADCQAAAgUDYUlkBQRVU0ROCQCaCAIFEnN0YWtpbmdVU0ROQWRkcmVzcwkArAICCQCsAgIJAKwCAgIMcnBkX2JhbGFuY2VfCQDYBAEFA2FJZAIBXwkApQgBBQR0aGlzAAADCQABAgUHJG1hdGNoMAIEVW5pdAAACQACAQILTWF0Y2ggZXJyb3IEByRtYXRjaDAFFnN0YWtlZEFtb3VudENhbGN1bGF0ZWQDCQABAgUHJG1hdGNoMAIDSW50BAFpBQckbWF0Y2gwBQFpAAABD2NoZWNrU3VzcGljaW91cwAEEGNvbnRyYWN0QmFsYW5jZXMJAQNfeHAACgEMY2hlY2tCYWxhbmNlAgNhY2MHYXNzZXRJZAQNJHQwMTE5NzYxMjAwMQUDYWNjBApzdXNwaWNpb3VzCAUNJHQwMTE5NzYxMjAwMQJfMQQBaQgFDSR0MDExOTc2MTIwMDECXzIDBQpzdXNwaWNpb3VzCQCUCgIFCnN1c3BpY2lvdXMFAWkECGFCYWxhbmNlCQBkAgkA8AcCBQR0aGlzCQDZBAEFB2Fzc2V0SWQJAQxzdGFrZWRBbW91bnQBCQDZBAEFB2Fzc2V0SWQDCQBmAgkAkQMCBRBjb250cmFjdEJhbGFuY2VzBQFpBQhhQmFsYW5jZQkAlAoCBgUBaQkAlAoCBwkAZAIFAWkAAQoAAiRsBQhhc3NldElkcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgcAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEMY2hlY2tCYWxhbmNlAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKARFzdXNwZW5kU3VzcGljaW91cwEBaQkBB3N1c3BlbmQBCQCsAgICHVN1c3BpY2lvdXMgc3RhdGUgd2l0aCBhc3NldDogCQCRAwIFCGFzc2V0SWRzBQFpAQ5yZXR1cm5QYXltZW50cwIGY2FsbGVyCHBheW1lbnRzCgENcGFyc2VQYXltZW50cwIDYWNjB3BheW1lbnQJAM0IAgUDYWNjCQEOU2NyaXB0VHJhbnNmZXIDBQZjYWxsZXIIBQdwYXltZW50BmFtb3VudAgFB3BheW1lbnQHYXNzZXRJZAoAAiRsBQhwYXltZW50cwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQENcGFyc2VQYXltZW50cwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgESY2hlY2tEQXBwVGhyZXNob2xkAQtuZXdCYWxhbmNlcwQRZEFwcFRocmVzaG9sZENvZWYJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQR0aGlzBRJrREFwcFRocmVzaG9sZENvZWYCGE5vIGRBcHBUaHJlc2hvbGRDb2VmIGtleQQOdGhyZXNob2xkU2NhbGUAkE4ECm1heEJhbGFuY2UJAJYDAQULbmV3QmFsYW5jZXMECm1pbkJhbGFuY2UJAJcDAQULbmV3QmFsYW5jZXMEBXJhdGlvCQBrAwUKbWF4QmFsYW5jZQUOdGhyZXNob2xkU2NhbGUFCm1pbkJhbGFuY2UDCQBmAgUFcmF0aW8JAGgCBRFkQXBwVGhyZXNob2xkQ29lZgUOdGhyZXNob2xkU2NhbGUJAAIBAjhOZXcgYmFsYW5jZSBpbiBhc3NldHMgb2YgdGhlIERBcHAgaXMgbGVzcyB0aGFuIHRocmVzaG9sZAcBCmNoZWNrQ29pbnMBCGFzc2V0SWRzBAVjb2lucwkAtQkCBQhhc3NldElkcwIBLAMJAGYCCQCQAwEFBWNvaW5zAAoJAAIBAiBUbyBtYW55IGNvaW5zLCBtYXggY29pbnMgc2l6ZSAxMAoBCWNoZWNrQ29pbgIFZXJyb3IHYXNzZXRJZAQFYXNzZXQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA2QQBBQdhc3NldElkCQCsAgICEmZyb21CYXNlNThTdHJpbmc6IAUHYXNzZXRJZAQIZGVjaW1hbHMICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUFYXNzZXQJAKwCAgILYXNzZXRJbmZvOiAFB2Fzc2V0SWQIZGVjaW1hbHMDCQECIT0CBQhkZWNpbWFscwUIREVDSU1BTFMJAAIBAg53cm9uZyBkZWNpbWFscwcKAAIkbAUFY29pbnMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBwoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEJY2hlY2tDb2luAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKFANtc2cBAUQCAnhwA2FtcAQBRAkBDmdldF9EX2ludGVybmFsAgUCeHAFA2FtcAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCAgFEBQFEBQNuaWwFAUQDbXNnAQRpbml0Awhhc3NldElkcwJfQRJfZEFwcFRocmVzaG9sZENvZWYDCQEBIQEJAJ4IAQUEdGhpcwkAAgECE0FscmVhZHkgaW5pdGlhbGl6ZWQDCQBnAgAABQJfQQkAAgECFEFtcCBtdXN0IGJlIG11c3QgPiAwAwkAZwIAAAUSX2RBcHBUaHJlc2hvbGRDb2VmCQACAQIfZEFwcCBUaHJlc2hvbGQgQ29lZiBtdXN0IGJlID4gMAQJc2hhcmVOYW1lAgtzX011bHRpX1VTRAQQc2hhcmVEZXNjcmlwdGlvbgkArAICAkJTaGFyZVRva2VuIG9mIFN3b3BGaSBwcm90b2NvbCBmb3IgTXVsdGlTdGFibGUgVVNEIHBvb2wgYXQgYWRkcmVzcyAJAKUIAQUEdGhpcwQKaXNzdWVUb2tlbgkAwggFBQlzaGFyZU5hbWUFEHNoYXJlRGVzY3JpcHRpb24AAAAGBgQHdG9rZW5JZAkAuAgBBQppc3N1ZVRva2VuAwkBCmNoZWNrQ29pbnMBBQhhc3NldElkcwkBBXRocm93AAkAzAgCCQELU3RyaW5nRW50cnkCBQhrVmVyc2lvbgUHdmVyc2lvbgkAzAgCCQELU3RyaW5nRW50cnkCBQdrQXNzZXRzBQhhc3NldElkcwkAzAgCCQEMSW50ZWdlckVudHJ5AgIJaW5pdGlhbF9BBQJfQQkAzAgCCQEMSW50ZWdlckVudHJ5AgIIZnV0dXJlX0EFAl9BCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQRrRmVlCQERQGV4dHJOYXRpdmUoMTA1MCkCBQZvcmFjbGUCDWJhc2VfZmVlX2ZsYXQJAMwIAgkBC1N0cmluZ0VudHJ5AgUNa1NoYXJlQXNzZXRJZAkA2AQBBQd0b2tlbklkCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRFrU2hhcmVBc3NldFN1cHBseQAACQDMCAIJAQxJbnRlZ2VyRW50cnkCBRJrREFwcFRocmVzaG9sZENvZWYFEl9kQXBwVGhyZXNob2xkQ29lZgkAzAgCCQEMQm9vbGVhbkVudHJ5AgUHa0FjdGl2ZQYJAMwIAgUKaXNzdWVUb2tlbgUDbmlsA21zZwEMYWRkTGlxdWlkaXR5Ag1taW5NaW50QW1vdW50DHN0YWtlRmFybWluZwkBC3ZhbHVlT3JFbHNlAgkBCGlzQWN0aXZlAAQDYW1wCQECX0EABAJ4cAkBA194cAAEAkQwAwkAAAIFC3NoYXJlU3VwcGx5AAAAAAkBB2dldERNZW0CBQJ4cAUDYW1wBAhwYXltZW50cwgFA21zZwhwYXltZW50cwQMcGF5bWVudHNTaXplCQCQAwEFCHBheW1lbnRzCgENdmFsaWRQYXltZW50cwEBbgMJAGYCBQxwYXltZW50c1NpemUFBm5Db2lucwkAAgEJAKwCAgIQcGF5bWVudHMgc2l6ZSA+IAkApAMBBQZuQ29pbnMDCQBmAgABBQxwYXltZW50c1NpemUJAAIBAhFwYXltZW50cyBzaXplIDwgMQMDCQAAAgULc2hhcmVTdXBwbHkAAAkBAiE9AgUGbkNvaW5zBQxwYXltZW50c1NpemUHCQACAQIiaW5pdGlhbCBkZXBvc2l0IHJlcXVpcmVzIGFsbCBjb2lucwoBDHBheW1hbnRWYWxpZAIDYWNjB3BheW1lbnQDCQEPY29udGFpbnNFbGVtZW50AgUIYXNzZXRJZHMJAQ1nZXRTdHJBc3NldElkAQgFB3BheW1lbnQHYXNzZXRJZAYJAAIBAhhJbnZhbGlkIGFzc2V0IGluIHBheW1lbnQKAAIkbAUIcGF5bWVudHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBwoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEMcGF5bWFudFZhbGlkAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAwkBASEBCQENdmFsaWRQYXltZW50cwEFDHBheW1lbnRzU2l6ZQkBBXRocm93AAQKc3VzcGljaW91cwkBD2NoZWNrU3VzcGljaW91cwADCAUKc3VzcGljaW91cwJfMQkAzggCCQERc3VzcGVuZFN1c3BpY2lvdXMBCAUKc3VzcGljaW91cwJfMgkBDnJldHVyblBheW1lbnRzAggFA21zZwZjYWxsZXIFCHBheW1lbnRzCgENcGFyc2VQYXltZW50cwIDYWNjB2Fzc2V0SWQEDSR0MDE2MDkyMTYxMTgFA2FjYwQLbmV3QmFsYW5jZXMIBQ0kdDAxNjA5MjE2MTE4Al8xBAFpCAUNJHQwMTYwOTIxNjExOAJfMgoBDHBhcnNlUGF5bWVudAIKbmV3QmFsYW5jZQdwYXltZW50AwkAAAIJAQ1nZXRTdHJBc3NldElkAQgFB3BheW1lbnQHYXNzZXRJZAUHYXNzZXRJZAkAZAIFCm5ld0JhbGFuY2UIBQdwYXltZW50BmFtb3VudAUKbmV3QmFsYW5jZQQJbmV3QmFsYWNlCgACJGwFCHBheW1lbnRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAkQMCBQJ4cAUBaQoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEMcGFyc2VQYXltZW50AgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKCQCUCgIJAM0IAgULbmV3QmFsYW5jZXMFCW5ld0JhbGFjZQkAZAIFAWkAAQQNJHQwMTY0NjgxNjUzNQoAAiRsBQhhc3NldElkcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgUDbmlsAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBDXBhcnNlUGF5bWVudHMCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoEC25ld0JhbGFuY2VzCAUNJHQwMTY0NjgxNjUzNQJfMQQBawgFDSR0MDE2NDY4MTY1MzUCXzIDCQESY2hlY2tEQXBwVGhyZXNob2xkAQULbmV3QmFsYW5jZXMJAQV0aHJvdwAEAkQxCQEHZ2V0RE1lbQIFC25ld0JhbGFuY2VzBQNhbXADCQEGYXNzZXJ0AQkAZgIFAkQxBQJEMAkAAgECB0QxID4gRDAEC2ZlZURpc2NvdW50CQEUY2FsY3VsYXRlRmVlRGlzY291bnQBCAUDbXNnBmNhbGxlcgoBEWNhbGNTY3JpcHRBY3Rpb25zAgNhY2MKbmV3QmFsYW5jZQQNJHQwMTY4NTUxNjg5NgUDYWNjBAtpbnZCYWxhbmNlcwgFDSR0MDE2ODU1MTY4OTYCXzEEDXNjcmlwdEFjdGlvbnMIBQ0kdDAxNjg1NTE2ODk2Al8yBAFpCAUNJHQwMTY4NTUxNjg5NgJfMwMJAGYCBQtzaGFyZVN1cHBseQAABARfZmVlCQBpAgkAaAIJAG4EBQNmZWUFC2ZlZURpc2NvdW50BQlmZWVTY2FsZTYFB0NFSUxJTkcFBm5Db2lucwkAaAIABAkAZQIFBm5Db2lucwABBARmZWVzBAxpZGVhbEJhbGFuY2UJAGsDBQJEMQkAkQMCBQJ4cAUBaQUCRDAECmRpZmZlcmVuY2UDCQBmAgUMaWRlYWxCYWxhbmNlBQpuZXdCYWxhbmNlCQBlAgUMaWRlYWxCYWxhbmNlBQpuZXdCYWxhbmNlCQBlAgUKbmV3QmFsYW5jZQUMaWRlYWxCYWxhbmNlCQBrAwUEX2ZlZQUKZGlmZmVyZW5jZQUJZmVlU2NhbGU2BA5nb3Zlcm5hbmNlRmVlcwkAawMFBGZlZXMFDWZlZUdvdmVybmFuY2UFCWZlZVNjYWxlNgQMZmluYWxCYWxhbmNlCQBlAgUKbmV3QmFsYW5jZQUEZmVlcwQQaW52YXJpYW50QmFsYW5jZQkAZQIFCm5ld0JhbGFuY2UFBGZlZXMEA3BtdAkAZQIFCm5ld0JhbGFuY2UJAJEDAgUCeHAFAWkEBmxwRmVlcwkAZQIFBGZlZXMFDmdvdmVybmFuY2VGZWVzBANpbnYDCQBmAgUDcG10AAAJAQVzdGFrZQIJAGUCBQNwbXQFBGZlZXMJAJEDAgUIYXNzZXRJZHMFAWkJAQd1bnN0YWtlAgUEZmVlcwkAkQMCBQhhc3NldElkcwUBaQMJAAACBQNpbnYFA2ludgQHYWlyZHJvcAMJAGYCBQZscEZlZXMAAAkA/AcEBRBscEZhcm1pbmdBZGRyZXNzAgdhaXJEcm9wBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIJANkEAQkAkQMCBQhhc3NldElkcwUBaQUGbHBGZWVzBQNuaWwAAAMJAAACBQdhaXJkcm9wBQdhaXJkcm9wCQCVCgMJAM0IAgULaW52QmFsYW5jZXMFEGludmFyaWFudEJhbGFuY2UJAM4IAgUNc2NyaXB0QWN0aW9ucwkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQ9tb25leUJveEFkZHJlc3MFDmdvdmVybmFuY2VGZWVzCQDZBAEJAJEDAgUIYXNzZXRJZHMFAWkJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkAkQMCBQhhc3NldElkcwUBaQUNa0Fzc2V0QmFsYW5jZQUMZmluYWxCYWxhbmNlBQNuaWwJAGQCBQFpAAEJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4EA2ludgkBBXN0YWtlAgUKbmV3QmFsYW5jZQkAkQMCBQhhc3NldElkcwUBaQMJAAACBQNpbnYFA2ludgkAlQoDCQDNCAIFC2ludkJhbGFuY2VzBQpuZXdCYWxhbmNlCQDNCAIFDXNjcmlwdEFjdGlvbnMJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAJEDAgUIYXNzZXRJZHMFAWkFDWtBc3NldEJhbGFuY2UFCm5ld0JhbGFuY2UJAGQCBQFpAAEJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4EDSR0MDE4NjAxMTg2ODkKAAIkbAULbmV3QmFsYW5jZXMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCVCgMFA25pbAUDbmlsAAAKAQUkZjFfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBEWNhbGNTY3JpcHRBY3Rpb25zAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYxXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMV8yAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKBAtpbnZCYWxhbmNlcwgFDSR0MDE4NjAxMTg2ODkCXzEEDXNjcmlwdEFjdGlvbnMIBQ0kdDAxODYwMTE4Njg5Al8yBAJEMgkBB2dldERNZW0CBQtpbnZCYWxhbmNlcwUDYW1wBAttaW50X2Ftb3VudAMJAAACBQtzaGFyZVN1cHBseQAABQJEMQkAawMFC3NoYXJlU3VwcGx5CQBlAgUCRDIFAkQwBQJEMAMJAQZhc3NlcnQBCQBnAgULbWludF9hbW91bnQFDW1pbk1pbnRBbW91bnQJAAIBAhRTbGlwcGFnZSBzY3Jld2VkIHlvdQMFDHN0YWtlRmFybWluZwQCcmUJAPwHBAUEdGhpcwIMcmVpc3N1ZVNoYXJlCQDMCAIFC21pbnRfYW1vdW50BQNuaWwFA25pbAMJAAACBQJyZQUCcmUEAXMJAPwHBAUOZmFybWluZ0FkZHJlc3MCD2xvY2tTaGFyZVRva2VucwkAzAgCCQClCAEFBHRoaXMFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUMc2hhcmVBc3NldElkBQttaW50X2Ftb3VudAUDbmlsAwkAAAIFAXMFAXMJAM0IAgUNc2NyaXB0QWN0aW9ucwkBDEludGVnZXJFbnRyeQIFEWtTaGFyZUFzc2V0U3VwcGx5CQBkAgULc2hhcmVTdXBwbHkFC21pbnRfYW1vdW50CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQDOCAIFDXNjcmlwdEFjdGlvbnMJAMwIAgkBB1JlaXNzdWUDBQxzaGFyZUFzc2V0SWQFC21pbnRfYW1vdW50BgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUDbXNnBmNhbGxlcgULbWludF9hbW91bnQFDHNoYXJlQXNzZXRJZAkAzAgCCQEMSW50ZWdlckVudHJ5AgURa1NoYXJlQXNzZXRTdXBwbHkJAGQCBQtzaGFyZVN1cHBseQULbWludF9hbW91bnQFA25pbANtc2cBDmNhbGNNaW50QW1vdW50AgtuZXdCYWxhbmNlcwR1c2VyBANhbXAJAQJfQQAEAnhwCQEDX3hwAAQCRDEJAQdnZXRETWVtAgULbmV3QmFsYW5jZXMFA2FtcAMJAAACBQtzaGFyZVN1cHBseQAACQCUCgIFA25pbAUCRDEEAkQwCQEHZ2V0RE1lbQIFAnhwBQNhbXAEC2ZlZURpc2NvdW50CQEUY2FsY3VsYXRlRmVlRGlzY291bnQBBQR1c2VyCgEPY2FsY0ludkJhbGFuY2VzAgNhY2MKbmV3QmFsYW5jZQQNJHQwMTk4NzgxOTkwNAUDYWNjBAtpbnZCYWxhbmNlcwgFDSR0MDE5ODc4MTk5MDQCXzEEAWkIBQ0kdDAxOTg3ODE5OTA0Al8yBARfZmVlCQBpAgkAaAIJAG4EBQNmZWUFC2ZlZURpc2NvdW50BQlmZWVTY2FsZTYFB0NFSUxJTkcFBm5Db2lucwkAaAIABAkAZQIFBm5Db2lucwABBARmZWVzBAxpZGVhbEJhbGFuY2UJAGsDBQJEMQkAkQMCBQJ4cAUBaQUCRDAECmRpZmZlcmVuY2UDCQBmAgUMaWRlYWxCYWxhbmNlBQpuZXdCYWxhbmNlCQBlAgUMaWRlYWxCYWxhbmNlBQpuZXdCYWxhbmNlCQBlAgUKbmV3QmFsYW5jZQUMaWRlYWxCYWxhbmNlCQBrAwUEX2ZlZQUKZGlmZmVyZW5jZQUJZmVlU2NhbGU2BBBpbnZhcmlhbnRCYWxhbmNlCQBlAgUKbmV3QmFsYW5jZQUEZmVlcwkAlAoCCQDNCAIFC2ludkJhbGFuY2VzBRBpbnZhcmlhbnRCYWxhbmNlCQBkAgUBaQABBA0kdDAyMDUwNjIwNTc2CgACJGwFC25ld0JhbGFuY2VzCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlAoCBQNuaWwAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEPY2FsY0ludkJhbGFuY2VzAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKBAtpbnZCYWxhbmNlcwgFDSR0MDIwNTA2MjA1NzYCXzEEAWsIBQ0kdDAyMDUwNjIwNTc2Al8yBAJEMgkBB2dldERNZW0CBQtpbnZCYWxhbmNlcwUDYW1wBAptaW50QW1vdW50CQBrAwULc2hhcmVTdXBwbHkJAGUCBQJEMgUCRDAFAkQwCQCUCgIFA25pbAUKbWludEFtb3VudANtc2cBDHJlaXNzdWVTaGFyZQEGYW1vdW50CQELdmFsdWVPckVsc2UCCQEKaXNTZWxmQ2FsbAEFA21zZwkAzAgCCQEHUmVpc3N1ZQMFDHNoYXJlQXNzZXRJZAUGYW1vdW50BgUDbmlsA21zZwEFZ2V0RHkECWFzc2V0RnJvbQdhc3NldFRvAmR4C3VzZXJBZGRyZXNzBAJ4cAkBA194cAAECWZyb21JbmRleAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDPCAIFCGFzc2V0SWRzBQlhc3NldEZyb20CEHVua25vd24gdG9rZW4gaW4EB3RvSW5kZXgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAzwgCBQhhc3NldElkcwUHYXNzZXRUbwIRdW5rbm93biB0b2tlbiBvdXQEAXgJAGQCCQCRAwIFAnhwBQlmcm9tSW5kZXgFAmR4BAF5CQEEZ2V0WQQFCWZyb21JbmRleAUHdG9JbmRleAUBeAUCeHAEAmR5CQBlAgkAZQIJAJEDAgUCeHAFB3RvSW5kZXgFAXkAAQQLZmVlRGlzY291bnQJARRjYWxjdWxhdGVGZWVEaXNjb3VudAEJAQdBZGRyZXNzAQkA2QQBBQt1c2VyQWRkcmVzcwQEX2ZlZQkAawMJAG4EBQNmZWUFC2ZlZURpc2NvdW50BQlmZWVTY2FsZTYFB0NFSUxJTkcFAmR5BQlmZWVTY2FsZTYJAJQKAgUDbmlsCQCUCgIJAGUCBQJkeQUEX2ZlZQUEX2ZlZQNtc2cBCGV4Y2hhbmdlAgh0b2tlbk91dAZtaW5fZHkJAQt2YWx1ZU9yRWxzZQIJAQhpc0FjdGl2ZQADCQECIT0CCQCQAwEIBQNtc2cIcGF5bWVudHMAAQkAAgECE3NpemUocGF5bWVudHMpICE9IDEECnN1c3BpY2lvdXMJAQ9jaGVja1N1c3BpY2lvdXMAAwgFCnN1c3BpY2lvdXMCXzEJAM4IAgkBEXN1c3BlbmRTdXNwaWNpb3VzAQgFCnN1c3BpY2lvdXMCXzIJAQ5yZXR1cm5QYXltZW50cwIIBQNtc2cGY2FsbGVyCAUDbXNnCHBheW1lbnRzBAdwYXltZW50CQCRAwIIBQNtc2cIcGF5bWVudHMAAAQHdG9rZW5JbgkBDWdldFN0ckFzc2V0SWQBCAUHcGF5bWVudAdhc3NldElkBAt0b2tlbk91dEI1OAkA2QQBBQh0b2tlbk91dAQCZHgIBQdwYXltZW50BmFtb3VudAQJZnJvbUluZGV4CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAM8IAgUIYXNzZXRJZHMFB3Rva2VuSW4CEHVua25vd24gdG9rZW4gaW4EB3RvSW5kZXgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAzwgCBQhhc3NldElkcwUIdG9rZW5PdXQCEXVua25vd24gdG9rZW4gb3V0BAJ4cAkBA194cAAEAXgJAGQCCQCRAwIFAnhwBQlmcm9tSW5kZXgFAmR4BAF5CQEEZ2V0WQQFCWZyb21JbmRleAUHdG9JbmRleAUBeAUCeHAEA19keQkAZQIJAGUCCQCRAwIFAnhwBQd0b0luZGV4BQF5AAEEC2ZlZURpc2NvdW50CQEUY2FsY3VsYXRlRmVlRGlzY291bnQBCAUDbXNnDG9yaWdpbkNhbGxlcgQEX2ZlZQkAawMFA19keQkAbgQFA2ZlZQULZmVlRGlzY291bnQFCWZlZVNjYWxlNgUHQ0VJTElORwUJZmVlU2NhbGU2BAJkeQkAZQIFA19keQUEX2ZlZQQOZ292ZXJuYW5jZUZlZXMJAGsDBQRfZmVlBQ1mZWVHb3Zlcm5hbmNlBQlmZWVTY2FsZTYDCQEGYXNzZXJ0AQkAZwIFAmR5BQZtaW5fZHkJAAIBAi5FeGNoYW5nZSByZXN1bHRlZCBpbiBmZXdlciBjb2lucyB0aGFuIGV4cGVjdGVkCgEPbWFrZU5ld0JhbGFuY2VzAgNhY2MMdG9rZW5CYWxhbmNlBA0kdDAyMjYxNzIyNjQzBQNhY2MEC25ld0JhbGFuY2VzCAUNJHQwMjI2MTcyMjY0MwJfMQQBaQgFDSR0MDIyNjE3MjI2NDMCXzIDCQAAAgUBaQUJZnJvbUluZGV4CQCUCgIJAM0IAgULbmV3QmFsYW5jZXMJAGQCBQx0b2tlbkJhbGFuY2UFAmR4CQBkAgUBaQABAwkAAAIFAWkFB3RvSW5kZXgJAJQKAgkAzQgCBQtuZXdCYWxhbmNlcwkAZQIFDHRva2VuQmFsYW5jZQUDX2R5CQBkAgUBaQABCQCUCgIJAM0IAgULbmV3QmFsYW5jZXMFDHRva2VuQmFsYW5jZQkAZAIFAWkAAQQNJHQwMjI4OTQyMjk1NQoAAiRsBQJ4cAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgUDbmlsAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBD21ha2VOZXdCYWxhbmNlcwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgQLbmV3QmFsYW5jZXMIBQ0kdDAyMjg5NDIyOTU1Al8xBAFpCAUNJHQwMjI4OTQyMjk1NQJfMgMJARJjaGVja0RBcHBUaHJlc2hvbGQBBQtuZXdCYWxhbmNlcwkBBXRocm93AAQBcwkBBXN0YWtlAggFB3BheW1lbnQGYW1vdW50CQENZ2V0U3RyQXNzZXRJZAEIBQdwYXltZW50B2Fzc2V0SWQDCQAAAgUBcwUBcwQCdXMJAQd1bnN0YWtlAgUDX2R5BQh0b2tlbk91dAMJAAACBQJ1cwUCdXMEBmxwRmVlcwkAZQIFBF9mZWUFDmdvdmVybmFuY2VGZWVzBAdhaXJkcm9wAwkAZgIFBmxwRmVlcwAACQD8BwQFEGxwRmFybWluZ0FkZHJlc3MCB2FpckRyb3AFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgULdG9rZW5PdXRCNTgFBmxwRmVlcwUDbmlsAAADCQAAAgUHYWlyZHJvcAUHYWlyZHJvcAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFB3Rva2VuSW4FDWtBc3NldEJhbGFuY2UFAXgJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUIdG9rZW5PdXQFDWtBc3NldEJhbGFuY2UJAGUCCQCRAwIFAnhwBQd0b0luZGV4BQNfZHkJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFA21zZwZjYWxsZXIFAmR5BQt0b2tlbk91dEI1OAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQ9tb25leUJveEFkZHJlc3MFDmdvdmVybmFuY2VGZWVzBQt0b2tlbk91dEI1OAUDbmlsCQDMCAIFAmR5CQDMCAIFC3Rva2VuT3V0QjU4BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4DbXNnAQh3aXRoZHJhdwEKbWluQW1vdW50cwkBC3ZhbHVlT3JFbHNlAgkBCGlzQWN0aXZlAAMJAQIhPQIJAJADAQgFA21zZwhwYXltZW50cwABCQACAQITc2l6ZShwYXltZW50cykgIT0gMQQJcG10QW1vdW50CAkAkQMCCAUDbXNnCHBheW1lbnRzAAAGYW1vdW50BApwbXRBc3NldElkCAkAkQMCCAUDbXNnCHBheW1lbnRzAAAHYXNzZXRJZAMJAQIhPQIFDHNoYXJlQXNzZXRJZAUKcG10QXNzZXRJZAkAAgECFXVua25vd24gcGF5bWVudCB0b2tlbgQKc3VzcGljaW91cwkBD2NoZWNrU3VzcGljaW91cwADCAUKc3VzcGljaW91cwJfMQkAzggCCQERc3VzcGVuZFN1c3BpY2lvdXMBCAUKc3VzcGljaW91cwJfMgkBDnJldHVyblBheW1lbnRzAggFA21zZwxvcmlnaW5DYWxsZXIIBQNtc2cIcGF5bWVudHMKARFjYWxjU2NyaXB0QWN0aW9ucwIDYWNjB2JhbGFuY2UEDSR0MDI0MjQ2MjQyNzQFA2FjYwQNc2NyaXB0QWN0aW9ucwgFDSR0MDI0MjQ2MjQyNzQCXzEEAWkIBQ0kdDAyNDI0NjI0Mjc0Al8yBAd3QW1vdW50CQBrAwUHYmFsYW5jZQUJcG10QW1vdW50BQtzaGFyZVN1cHBseQMJAQZhc3NlcnQBCQBnAgUHd0Ftb3VudAkAkQMCBQptaW5BbW91bnRzBQFpCQACAQIwV2l0aGRyYXdhbCByZXN1bHRlZCBpbiBmZXdlciBjb2lucyB0aGFuIGV4cGVjdGVkBAJ1cwkBB3Vuc3Rha2UCBQd3QW1vdW50CQCRAwIFCGFzc2V0SWRzBQFpAwkAAAIFAnVzBQJ1cwkAlAoCCQDOCAIFDXNjcmlwdEFjdGlvbnMJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkAkQMCBQhhc3NldElkcwUBaQUNa0Fzc2V0QmFsYW5jZQkAZQIFB2JhbGFuY2UFB3dBbW91bnQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFA21zZwxvcmlnaW5DYWxsZXIFB3dBbW91bnQJANkEAQkAkQMCBQhhc3NldElkcwUBaQUDbmlsCQBkAgUBaQABCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBA0kdDAyNDc2NDI0ODMyCgACJGwJAQNfeHAACgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlAoCBQNuaWwAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQERY2FsY1NjcmlwdEFjdGlvbnMCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoEDXNjcmlwdEFjdGlvbnMIBQ0kdDAyNDc2NDI0ODMyAl8xBAFpCAUNJHQwMjQ3NjQyNDgzMgJfMgkAzggCBQ1zY3JpcHRBY3Rpb25zCQDMCAIJAQRCdXJuAgUMc2hhcmVBc3NldElkBQlwbXRBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIFEWtTaGFyZUFzc2V0U3VwcGx5CQBlAgULc2hhcmVTdXBwbHkFCXBtdEFtb3VudAUDbmlsA21zZwESd2l0aGRyYXdXaXRoVW5sb2NrAgptaW5BbW91bnRzDHVubG9ja0Ftb3VudAkBC3ZhbHVlT3JFbHNlAgkBCGlzQWN0aXZlAAMJAGcCAAAFDHVubG9ja0Ftb3VudAkAAgECHlVubG9jayBhbW91bnQgbXVzdCBiZSBwb3NpdGl2ZQQKc3VzcGljaW91cwkBD2NoZWNrU3VzcGljaW91cwADCAUKc3VzcGljaW91cwJfMQkAzggCCQERc3VzcGVuZFN1c3BpY2lvdXMBCAUKc3VzcGljaW91cwJfMgkBDnJldHVyblBheW1lbnRzAggFA21zZwZjYWxsZXIIBQNtc2cIcGF5bWVudHMECXBtdEFtb3VudAMJAGYCCQCQAwEIBQNtc2cIcGF5bWVudHMAAAMJAQIhPQIJAJADAQgFA21zZwhwYXltZW50cwABCQACAQITc2l6ZShwYXltZW50cykgIT0gMQQKcG10QXNzZXRJZAgJAJEDAggFA21zZwhwYXltZW50cwAAB2Fzc2V0SWQDCQECIT0CBQxzaGFyZUFzc2V0SWQFCnBtdEFzc2V0SWQJAAIBAhV1bmtub3duIHBheW1lbnQgdG9rZW4ICQCRAwIIBQNtc2cIcGF5bWVudHMAAAZhbW91bnQAAAQGdW5sb2NrCQD8BwQFDmZhcm1pbmdBZGRyZXNzAhN3aXRoZHJhd1NoYXJlVG9rZW5zCQDMCAIJAKUIAQUEdGhpcwkAzAgCBQx1bmxvY2tBbW91bnQFA25pbAUDbmlsAwkAAAIFBnVubG9jawUGdW5sb2NrBA53aXRoZHJhd0Ftb3VudAkAZAIFCXBtdEFtb3VudAUMdW5sb2NrQW1vdW50BANpbnYJAPwHBAUEdGhpcwIId2l0aGRyYXcJAMwIAgUKbWluQW1vdW50cwUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQxzaGFyZUFzc2V0SWQFDndpdGhkcmF3QW1vdW50BQNuaWwDCQAAAgUDaW52BQNpbnYFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgNtc2cBE2NhbGNXaXRoZHJhd09uZUNvaW4DC3Rva2VuQW1vdW50CHRva2VuT3V0BHVzZXIDCQBnAgAABQt0b2tlbkFtb3VudAkAAgECF0Ftb3VudCBtdXN0IGJlIHBvc2l0aXZlBAFpCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAM8IAgUIYXNzZXRJZHMFCHRva2VuT3V0AhF1bmtub3duIHRva2VuIG91dAkAlAoCBQNuaWwICQEUX2NhbGNXaXRoZHJhd09uZUNvaW4ECQEDX3hwAAULdG9rZW5BbW91bnQFAWkJAQdBZGRyZXNzAQkA2QQBBQR1c2VyAl8xA21zZwEPd2l0aGRyYXdPbmVDb2luAgh0b2tlbk91dAltaW5BbW91bnQJAQt2YWx1ZU9yRWxzZQIJAQhpc0FjdGl2ZQADCQECIT0CCQCQAwEIBQNtc2cIcGF5bWVudHMAAQkAAgECE3NpemUocGF5bWVudHMpICE9IDEECnN1c3BpY2lvdXMJAQ9jaGVja1N1c3BpY2lvdXMAAwgFCnN1c3BpY2lvdXMCXzEJAM4IAgkBEXN1c3BlbmRTdXNwaWNpb3VzAQgFCnN1c3BpY2lvdXMCXzIJAQ5yZXR1cm5QYXltZW50cwIIBQNtc2cMb3JpZ2luQ2FsbGVyCAUDbXNnCHBheW1lbnRzBAlwbXRBbW91bnQICQCRAwIIBQNtc2cIcGF5bWVudHMAAAZhbW91bnQECnBtdEFzc2V0SWQICQCRAwIIBQNtc2cIcGF5bWVudHMAAAdhc3NldElkAwkBAiE9AgUKcG10QXNzZXRJZAUMc2hhcmVBc3NldElkCQACAQINdW5rbm93biB0b2tlbgQIb3V0SW5kZXgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAzwgCBQhhc3NldElkcwUIdG9rZW5PdXQCEXVua25vd24gdG9rZW4gb3V0BAt0b2tlbk91dEI1OAkA2QQBBQh0b2tlbk91dAQCeHAJAQNfeHAABA0kdDAyNjg2NDI2OTQ2CQEUX2NhbGNXaXRoZHJhd09uZUNvaW4EBQJ4cAUJcG10QW1vdW50BQhvdXRJbmRleAgFA21zZwxvcmlnaW5DYWxsZXIEAmR5CAUNJHQwMjY4NjQyNjk0NgJfMQQGZHlfZmVlCAUNJHQwMjY4NjQyNjk0NgJfMgMJAQZhc3NlcnQBCQBnAgUCZHkFCW1pbkFtb3VudAkAAgECGE5vdCBlbm91Z2ggY29pbnMgcmVtb3ZlZAQOZ292ZXJuYW5jZUZlZXMJAGsDBQZkeV9mZWUFDWZlZUdvdmVybmFuY2UFCWZlZVNjYWxlNgQKZHlfYW5kX2ZlZQkAZAIFAmR5BQZkeV9mZWUKAQ9tYWtlTmV3QmFsYW5jZXMCA2FjYwx0b2tlbkJhbGFuY2UEDSR0MDI3MjA0MjcyMzAFA2FjYwQLbmV3QmFsYW5jZXMIBQ0kdDAyNzIwNDI3MjMwAl8xBAFpCAUNJHQwMjcyMDQyNzIzMAJfMgMJAAACBQFpBQhvdXRJbmRleAkAlAoCCQDNCAIFC25ld0JhbGFuY2VzCQBlAgUMdG9rZW5CYWxhbmNlBQpkeV9hbmRfZmVlCQBkAgUBaQABCQCUCgIJAM0IAgULbmV3QmFsYW5jZXMFDHRva2VuQmFsYW5jZQkAZAIFAWkAAQQNJHQwMjczOTcyNzQ1OAoAAiRsBQJ4cAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgUDbmlsAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBD21ha2VOZXdCYWxhbmNlcwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgQLbmV3QmFsYW5jZXMIBQ0kdDAyNzM5NzI3NDU4Al8xBAF2CAUNJHQwMjczOTcyNzQ1OAJfMgMJARJjaGVja0RBcHBUaHJlc2hvbGQBBQtuZXdCYWxhbmNlcwkBBXRocm93AAQCdXMJAQd1bnN0YWtlAgUKZHlfYW5kX2ZlZQUIdG9rZW5PdXQDCQAAAgUCdXMFAnVzBAZscEZlZXMJAGUCBQZkeV9mZWUFDmdvdmVybmFuY2VGZWVzBAdhaXJkcm9wAwkAZgIFBmxwRmVlcwAACQD8BwQFEGxwRmFybWluZ0FkZHJlc3MCB2FpckRyb3AFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgULdG9rZW5PdXRCNTgFBmxwRmVlcwUDbmlsAAADCQAAAgUHYWlyZHJvcAUHYWlyZHJvcAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUDbXNnDG9yaWdpbkNhbGxlcgUCZHkFC3Rva2VuT3V0QjU4CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAJEDAgUIYXNzZXRJZHMFCG91dEluZGV4BQ1rQXNzZXRCYWxhbmNlCQBlAgkAkQMCBQJ4cAUIb3V0SW5kZXgFCmR5X2FuZF9mZWUJAMwIAgkBBEJ1cm4CBQxzaGFyZUFzc2V0SWQFCXBtdEFtb3VudAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQ9tb25leUJveEFkZHJlc3MFDmdvdmVybmFuY2VGZWVzBQt0b2tlbk91dEI1OAkAzAgCCQEMSW50ZWdlckVudHJ5AgURa1NoYXJlQXNzZXRTdXBwbHkJAGUCBQtzaGFyZVN1cHBseQUJcG10QW1vdW50BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4DbXNnARl3aXRoZHJhd09uZUNvaW5XaXRoVW5sb2NrAwh0b2tlbk91dAltaW5BbW91bnQMdW5sb2NrQW1vdW50CQELdmFsdWVPckVsc2UCCQEIaXNBY3RpdmUAAwkAZwIAAAUMdW5sb2NrQW1vdW50CQACAQIeVW5sb2NrIGFtb3VudCBtdXN0IGJlIHBvc2l0aXZlBApzdXNwaWNpb3VzCQEPY2hlY2tTdXNwaWNpb3VzAAMIBQpzdXNwaWNpb3VzAl8xCQDOCAIJARFzdXNwZW5kU3VzcGljaW91cwEIBQpzdXNwaWNpb3VzAl8yCQEOcmV0dXJuUGF5bWVudHMCCAUDbXNnBmNhbGxlcggFA21zZwhwYXltZW50cwQJcG10QW1vdW50AwkAZgIJAJADAQgFA21zZwhwYXltZW50cwAAAwkBAiE9AgkAkAMBCAUDbXNnCHBheW1lbnRzAAEJAAIBAhNzaXplKHBheW1lbnRzKSAhPSAxBApwbXRBc3NldElkCAkAkQMCCAUDbXNnCHBheW1lbnRzAAAHYXNzZXRJZAMJAQIhPQIFDHNoYXJlQXNzZXRJZAUKcG10QXNzZXRJZAkAAgECFXVua25vd24gcGF5bWVudCB0b2tlbggJAJEDAggFA21zZwhwYXltZW50cwAABmFtb3VudAAABAZ1bmxvY2sJAPwHBAUOZmFybWluZ0FkZHJlc3MCE3dpdGhkcmF3U2hhcmVUb2tlbnMJAMwIAgkApQgBBQR0aGlzCQDMCAIFDHVubG9ja0Ftb3VudAUDbmlsBQNuaWwDCQAAAgUGdW5sb2NrBQZ1bmxvY2sEDndpdGhkcmF3QW1vdW50CQBkAgUJcG10QW1vdW50BQx1bmxvY2tBbW91bnQEA2ludgkA/AcEBQR0aGlzAg93aXRoZHJhd09uZUNvaW4JAMwIAgUIdG9rZW5PdXQJAMwIAgUJbWluQW1vdW50BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFDHNoYXJlQXNzZXRJZAUOd2l0aGRyYXdBbW91bnQFA25pbAMJAAACBQNpbnYFA2ludgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuA21zZwEBQQAJAJQKAgUDbmlsCQECX0EAA21zZwEPZ2V0VmlydHVhbFByaWNlAAQBRAkBBWdldF9EAgkBA194cAAJAQJfQQAJAJQKAgUDbmlsCQBrAwUBRAUJUFJFQ0lTSU9OBQtzaGFyZVN1cHBseQNtc2cBD2NhbGNUb2tlbkFtb3VudAIHYW1vdW50cwdkZXBvc2l0BANhbXAJAQJfQQAECGJhbGFuY2VzCQEDX3hwAAQCRDAJAQdnZXRETWVtAgUIYmFsYW5jZXMFA2FtcAoBD2NhbGNOZXdCYWxhbmNlcwIDYWNjB2JhbGFuY2UEDSR0MDI5NDc1Mjk1MDEFA2FjYwQLbmV3QmFsYW5jZXMIBQ0kdDAyOTQ3NTI5NTAxAl8xBAFpCAUNJHQwMjk0NzUyOTUwMQJfMgQKbmV3QmFsYW5jZQkAZAIFB2JhbGFuY2UDBQdkZXBvc2l0CQCRAwIFB2Ftb3VudHMFAWkJAQEtAQkAkQMCBQdhbW91bnRzBQFpCQCUCgIJAM0IAgULbmV3QmFsYW5jZXMFCm5ld0JhbGFuY2UJAGQCBQFpAAEEC25ld0JhbGFuY2VzCAoAAiRsBQhiYWxhbmNlcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgUDbmlsAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBD2NhbGNOZXdCYWxhbmNlcwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgJfMQQCRDEJAQdnZXRETWVtAgULbmV3QmFsYW5jZXMFA2FtcAQEZGlmZgMFB2RlcG9zaXQJAGUCBQJEMQUCRDAJAGUCBQJEMAUCRDEJAJQKAgUDbmlsCQBrAwUEZGlmZgULc2hhcmVTdXBwbHkFAkQwA21zZwEFcmFtcEECCF9mdXR1cmVBC19mdXR1cmVUaW1lCQELdmFsdWVPckVsc2UCCQEIaXNBY3RpdmUACQELdmFsdWVPckVsc2UCCQELaXNBZG1pbkNhbGwBBQNtc2cDCQEGYXNzZXJ0AQkAZwIFDmJsb2NrVGltZXN0YW1wCQBkAgUOaW5pdGlhbF9BX3RpbWUFDU1JTl9SQU1QX1RJTUUJAAIBAgl0b28gb2Z0ZW4DCQEGYXNzZXJ0AQkAZwIFC19mdXR1cmVUaW1lCQBkAgUOYmxvY2tUaW1lc3RhbXAFDU1JTl9SQU1QX1RJTUUJAAIBAhFpbnN1ZmZpY2llbnQgdGltZQQKX2luaXRpYWxfQQkBAl9BAAMJAQZhc3NlcnQBAwkAZgIFCF9mdXR1cmVBAAAJAGYCBQVNQVhfQQUIX2Z1dHVyZUEHCQACAQIRb3V0IG9mIGJhc2UgcmFuZ2UDCQEGYXNzZXJ0AQMDCQBnAgUIX2Z1dHVyZUEFCl9pbml0aWFsX0EJAGcCCQBoAgUKX2luaXRpYWxfQQUMTUFYX0FfQ0hBTkdFBQhfZnV0dXJlQQcGAwkAZgIFCl9pbml0aWFsX0EFCF9mdXR1cmVBCQBnAgkAaAIFCF9mdXR1cmVBBQxNQVhfQV9DSEFOR0UFCl9pbml0aWFsX0EHCQACAQIMb3V0IG9mIHJhbmdlCQDMCAIJAQxJbnRlZ2VyRW50cnkCAglpbml0aWFsX0EFCl9pbml0aWFsX0EJAMwIAgkBDEludGVnZXJFbnRyeQICCGZ1dHVyZV9BBQhfZnV0dXJlQQkAzAgCCQEMSW50ZWdlckVudHJ5AgIOaW5pdGlhbF9BX3RpbWUFDmJsb2NrVGltZXN0YW1wCQDMCAIJAQxJbnRlZ2VyRW50cnkCAg1mdXR1cmVfQV90aW1lBQtfZnV0dXJlVGltZQUDbmlsA21zZwEJc3RvcFJhbXBBAAkBC3ZhbHVlT3JFbHNlAgkBCGlzQWN0aXZlAAkBC3ZhbHVlT3JFbHNlAgkBC2lzQWRtaW5DYWxsAQUDbXNnBAhjdXJyZW50QQkBAl9BAAkAzAgCCQEMSW50ZWdlckVudHJ5AgIJaW5pdGlhbF9BBQhjdXJyZW50QQkAzAgCCQEMSW50ZWdlckVudHJ5AgIIZnV0dXJlX0EFCGN1cnJlbnRBCQDMCAIJAQxJbnRlZ2VyRW50cnkCAg5pbml0aWFsX0FfdGltZQUOYmxvY2tUaW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQICDWZ1dHVyZV9BX3RpbWUFDmJsb2NrVGltZXN0YW1wBQNuaWwDbXNnAQhzaHV0ZG93bgAJAQt2YWx1ZU9yRWxzZQIJAQtpc0FkbWluQ2FsbAEFA21zZwMJAQEhAQUGYWN0aXZlCQACAQkArAICAiJEQXBwIGlzIGFscmVhZHkgc3VzcGVuZGVkLiBDYXVzZTogCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFBmtDYXVzZQIadGhlIGNhdXNlIHdhc24ndCBzcGVjaWZpZWQJAQdzdXNwZW5kAQIPUGF1c2VkIGJ5IGFkbWluA21zZwEIYWN0aXZhdGUACQELdmFsdWVPckVsc2UCCQELaXNBZG1pbkNhbGwBBQNtc2cDBQZhY3RpdmUJAQ10aHJvd0lzQWN0aXZlAAkAzAgCCQEMQm9vbGVhbkVudHJ5AgUHa0FjdGl2ZQYJAMwIAgkBC0RlbGV0ZUVudHJ5AQUGa0NhdXNlBQNuaWwDbXNnARl0YWtlSW50b0FjY291bnRFeHRyYUZ1bmRzAAkBC3ZhbHVlT3JFbHNlAgkBCGlzQWN0aXZlAAMJAQIhPQIIBQNtc2cGY2FsbGVyBQ9tb25leUJveEFkZHJlc3MJAAIBAiZPbmx5IHRoZSB3YWxsZXQgY2FuIGNhbGwgdGhpcyBmdW5jdGlvbgQIYmFsYW5jZXMJAQNfeHAACgEOdGFrZUV4dHJhRnVuZHMCA2FjYwdhc3NldElkBA0kdDAzMTg0MzMxODYxBQNhY2MEA3N1bQgFDSR0MDMxODQzMzE4NjECXzEEAWkIBQ0kdDAzMTg0MzMxODYxAl8yBAh0b2tlbkI1OAkA2QQBBQdhc3NldElkBAhyQmFsYW5jZQkAZAIJAPAHAgUEdGhpcwUIdG9rZW5CNTgJAQxzdGFrZWRBbW91bnQBBQh0b2tlbkI1OAQMZW5yb2xsQW1vdW50CQBlAgUIckJhbGFuY2UJAJEDAgUIYmFsYW5jZXMFAWkDCQBmAgAABQxlbnJvbGxBbW91bnQJAQdzdXNwZW5kAQkArAICAiBFbnJvbGwgYW1vdW50IG5lZ2F0aXZlIGZvciBhc3NldAUHYXNzZXRJZAQHYWlyZHJvcAMJAGYCBQxlbnJvbGxBbW91bnQAAAkA/AcEBRBscEZhcm1pbmdBZGRyZXNzAgdhaXJEcm9wBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFCHRva2VuQjU4BQxlbnJvbGxBbW91bnQFA25pbAAAAwkAAAIFB2FpcmRyb3AFB2FpcmRyb3AJAJQKAgkAZAIFA3N1bQUMZW5yb2xsQW1vdW50CQBkAgUBaQABCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBAFrCgACJGwFCGFzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlAoCAAAAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEOdGFrZUV4dHJhRnVuZHMCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoDCQAAAggFAWsCXzEAAAkAAgECEE5vIG1vbmV5IHRvIHRha2UFA25pbAECdHgBBnZlcmlmeQAEE211bHRpU2lnbmVkQnlBZG1pbnMEEmFkbWluUHViS2V5MVNpZ25lZAMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAFDGFkbWluUHViS2V5MQABAAAEEmFkbWluUHViS2V5MlNpZ25lZAMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAEFDGFkbWluUHViS2V5MgABAAAEEmFkbWluUHViS2V5M1NpZ25lZAMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAIFDGFkbWluUHViS2V5MwABAAAJAGcCCQBkAgkAZAIFEmFkbWluUHViS2V5MVNpZ25lZAUSYWRtaW5QdWJLZXkyU2lnbmVkBRJhZG1pblB1YktleTNTaWduZWQAAgQHJG1hdGNoMAUCdHgDCQABAgUHJG1hdGNoMAIXSW52b2tlU2NyaXB0VHJhbnNhY3Rpb24EA2ludgUHJG1hdGNoMAQTY2FsbFRha2VJbnRvQWNjb3VudAMJAAACCAUDaW52BGRBcHAFBHRoaXMJAAACCAUDaW52CGZ1bmN0aW9uAhl0YWtlSW50b0FjY291bnRFeHRyYUZ1bmRzBwQNc2lnbmVkQnlBZG1pbgMDAwkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAUMYWRtaW5QdWJLZXkxBgkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAUMYWRtaW5QdWJLZXkyBgkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAUMYWRtaW5QdWJLZXkzBgkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAURYWRtaW5QdWJLZXlJbnZva2UDAwUTY2FsbFRha2VJbnRvQWNjb3VudAUNc2lnbmVkQnlBZG1pbgcGBRNtdWx0aVNpZ25lZEJ5QWRtaW5zBRNtdWx0aVNpZ25lZEJ5QWRtaW5zz3XOLA==", "height": 2267668, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: none Next: 9GDJqh7tMaqmqFFHYGC89reXt68bGsNyNuufFpxj1mEp Full:
OldNewDifferences
1-# no script
1+{-# STDLIB_VERSION 6 #-}
2+{-# SCRIPT_TYPE ACCOUNT #-}
3+{-# CONTENT_TYPE DAPP #-}
4+let PRECISION = 1000000
5+
6+let MAX_A = 1000000
7+
8+let MAX_A_CHANGE = 10
9+
10+let DECIMALS = 6
11+
12+let MIN_RAMP_TIME = (86400 / 60)
13+
14+let version = "3.0.0"
15+
16+let kVersion = "version"
17+
18+let kAssets = "asset_ids"
19+
20+let kAssetBalance = "_balance"
21+
22+let kActive = "active"
23+
24+let kCause = "shutdown_cause"
25+
26+let kShareAssetId = "share_asset_id"
27+
28+let kShareAssetSupply = "share_asset_supply"
29+
30+let kFee = "commission"
31+
32+let kDAppThresholdCoef = "dAppThresholdCoef"
33+
34+let kUSDNAddress = "staking_usdnnsbt_address"
35+
36+let kDiscounts = "discounts"
37+
38+let kDiscountValues = "discount_values"
39+
40+let kUserSwopInGov = "_SWOP_amount"
41+
42+let kAdminPubKey1 = "admin_pub_1"
43+
44+let kAdminPubKey2 = "admin_pub_2"
45+
46+let kAdminPubKey3 = "admin_pub_3"
47+
48+let kAdminInvokePubKey = "admin_invoke_pub"
49+
50+let kMoneyBoxAddress = "money_box_address"
51+
52+let kGovAddress = "governance_address"
53+
54+let kVotingAddress = "voting_address"
55+
56+let kFarmingAddress = "farming_address"
57+
58+let kLPFarmingAddress = "lp_farming"
59+
60+let oracle = Address(base58'3MvVBtsXroQpy1tsPw21TU2ET9A8WfmrNjz')
61+
62+func getBase58FromOracle (key) = match getString(oracle, key) {
63+ case string: String =>
64+ fromBase58String(string)
65+ case nothing =>
66+ throw((key + "is empty"))
67+}
68+
69+
70+let adminPubKey1 = getBase58FromOracle(kAdminPubKey1)
71+
72+let adminPubKey2 = getBase58FromOracle(kAdminPubKey2)
73+
74+let adminPubKey3 = getBase58FromOracle(kAdminPubKey3)
75+
76+let adminPubKeyInvoke = getBase58FromOracle(kAdminInvokePubKey)
77+
78+let moneyBoxAddress = Address(getBase58FromOracle(kMoneyBoxAddress))
79+
80+let govAddress = Address(getBase58FromOracle(kGovAddress))
81+
82+let stakingUSDNAddress = Address(getBase58FromOracle(kUSDNAddress))
83+
84+let votingAddress = Address(getBase58FromOracle(kVotingAddress))
85+
86+let farmingAddress = Address(getBase58FromOracle(kFarmingAddress))
87+
88+let lpFarmingAddress = Address(getBase58FromOracle(kLPFarmingAddress))
89+
90+let USDN = base58'8UrfDVd5GreeUwm7uPk7eYz1eMv376kzR52C6sANPkwS'
91+
92+let stakingAssets = [toBase58String(USDN)]
93+
94+let active = getBooleanValue(this, kActive)
95+
96+let shareAssetId = fromBase58String(getStringValue(this, kShareAssetId))
97+
98+let shareSupply = getIntegerValue(this, kShareAssetSupply)
99+
100+let feeScale6 = 1000000
101+
102+let fee = getIntegerValue(this, kFee)
103+
104+let feeGovernance = fraction(40, feeScale6, 100)
105+
106+let initial_A = getIntegerValue(this, "initial_A")
107+
108+let future_A = getIntegerValue(this, "future_A")
109+
110+let initial_A_time = valueOrElse(getInteger(this, "initial_A_time"), 0)
111+
112+let future_A_time = valueOrElse(getInteger(this, "future_A_time"), 0)
113+
114+let assetIds = split(getStringValue(this, kAssets), ",")
115+
116+let nCoins = size(assetIds)
117+
118+func suspend (cause) = [BooleanEntry(kActive, false), StringEntry(kCause, cause)]
119+
120+
121+func throwIsActive () = throw("DApp is already active")
122+
123+
124+func isActive () = if (active)
125+ then unit
126+ else throw("DApp is inactive at this moment")
127+
128+
129+func isAdminCall (i) = if (containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey))
130+ then unit
131+ else throw("Only admin can call this function")
132+
133+
134+func isSelfCall (i) = if ((this == i.caller))
135+ then unit
136+ else throw("Only contract itself can call this function")
137+
138+
139+let big2 = toBigInt(2)
140+
141+let iter10 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
142+
143+let iter15 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
144+
145+let iter16 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
146+
147+let blockTimestamp = height
148+
149+func assert (a) = if (a)
150+ then false
151+ else true
152+
153+
154+func calculateFeeDiscount (userAddr) = {
155+ let user = match userAddr {
156+ case u: Address =>
157+ toString(u)
158+ case u: String =>
159+ u
160+ case _ =>
161+ throw("Unknow type of user Addr")
162+ }
163+ let swopAmount = valueOrElse(getInteger(govAddress, (user + kUserSwopInGov)), 0)
164+ let discountValues = split(getStringValue(oracle, kDiscountValues), ",")
165+ let discounts = split(getStringValue(oracle, kDiscounts), ",")
166+ if (if ((swopAmount >= parseIntValue(discountValues[0])))
167+ then (parseIntValue(discountValues[1]) > swopAmount)
168+ else false)
169+ then (feeScale6 - parseIntValue(discounts[0]))
170+ else if (if ((swopAmount >= parseIntValue(discountValues[1])))
171+ then (parseIntValue(discountValues[2]) > swopAmount)
172+ else false)
173+ then (feeScale6 - parseIntValue(discounts[1]))
174+ else if (if ((swopAmount >= parseIntValue(discountValues[2])))
175+ then (parseIntValue(discountValues[3]) > swopAmount)
176+ else false)
177+ then (feeScale6 - parseIntValue(discounts[2]))
178+ else if (if ((swopAmount >= parseIntValue(discountValues[3])))
179+ then (parseIntValue(discountValues[4]) > swopAmount)
180+ else false)
181+ then (feeScale6 - parseIntValue(discounts[3]))
182+ else if ((swopAmount >= parseIntValue(discountValues[4])))
183+ then (feeScale6 - parseIntValue(discounts[4]))
184+ else feeScale6
185+ }
186+
187+
188+func _A () = {
189+ let t1 = future_A_time
190+ let A1 = future_A
191+ if ((t1 > blockTimestamp))
192+ then {
193+ let A0 = initial_A
194+ let t0 = initial_A_time
195+ if ((A1 > A0))
196+ then (A0 + (((A1 - A0) * (blockTimestamp - t0)) / (t1 - t0)))
197+ else (A0 - (((A0 - A1) * (blockTimestamp - t0)) / (t1 - t0)))
198+ }
199+ else A1
200+ }
201+
202+
203+func _xp () = {
204+ func assetBalances (acc,assetId) = (acc :+ valueOrElse(getInteger(this, (assetId + kAssetBalance)), 0))
205+
206+ let $l = assetIds
207+ let $s = size($l)
208+ let $acc0 = nil
209+ func $f0_1 ($a,$i) = if (($i >= $s))
210+ then $a
211+ else assetBalances($a, $l[$i])
212+
213+ func $f0_2 ($a,$i) = if (($i >= $s))
214+ then $a
215+ else throw("List size exceeds 10")
216+
217+ $f0_2($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)
218+ }
219+
220+
221+func _xp_mem (xp) = xp
222+
223+
224+func sumList (acc,element) = (acc + element)
225+
226+
227+func get_D (xp,amp) = {
228+ let @ = invoke(this, "D", [xp, amp], nil)
229+ if ($isInstanceOf(@, "Int"))
230+ then @
231+ else throw(($getType(@) + " couldn't be cast to Int"))
232+ }
233+
234+
235+func get_D_internal (xp,amp) = {
236+ let S = {
237+ let $l = xp
238+ let $s = size($l)
239+ let $acc0 = 0
240+ func $f0_1 ($a,$i) = if (($i >= $s))
241+ then $a
242+ else sumList($a, $l[$i])
243+
244+ func $f0_2 ($a,$i) = if (($i >= $s))
245+ then $a
246+ else throw("List size exceeds 10")
247+
248+ $f0_2($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)
249+ }
250+ if ((S == 0))
251+ then 0
252+ else {
253+ let Ann = (amp * nCoins)
254+ let AnnS = (toBigInt(Ann) * toBigInt(S))
255+ let Ann1 = toBigInt((Ann - 1))
256+ func Dproc (acc,i) = if ((acc._2 == true))
257+ then acc
258+ else {
259+ let Dprev = acc._1
260+ func D_PProc (D_P,i) = if ((nCoins > i))
261+ then ((D_P * Dprev) / (toBigInt(xp[i]) * toBigInt(nCoins)))
262+ else D_P
263+
264+ let D_P = {
265+ let $l = iter10
266+ let $s = size($l)
267+ let $acc0 = Dprev
268+ func $f1_1 ($a,$i) = if (($i >= $s))
269+ then $a
270+ else D_PProc($a, $l[$i])
271+
272+ func $f1_2 ($a,$i) = if (($i >= $s))
273+ then $a
274+ else throw("List size exceeds 10")
275+
276+ $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
277+ }
278+ let D = fraction((AnnS + (toBigInt(nCoins) * D_P)), Dprev, ((Ann1 * Dprev) + (toBigInt((nCoins + 1)) * D_P)))
279+ if ((D > Dprev))
280+ then if ((1 >= toInt((D - Dprev))))
281+ then $Tuple2(D, true)
282+ else $Tuple2(D, false)
283+ else if ((1 >= toInt((Dprev - D))))
284+ then $Tuple2(D, true)
285+ else $Tuple2(D, false)
286+ }
287+
288+ let $t063216387 = {
289+ let $l = iter15
290+ let $s = size($l)
291+ let $acc0 = $Tuple2(toBigInt(S), false)
292+ func $f1_1 ($a,$i) = if (($i >= $s))
293+ then $a
294+ else Dproc($a, $l[$i])
295+
296+ func $f1_2 ($a,$i) = if (($i >= $s))
297+ then $a
298+ else throw("List size exceeds 15")
299+
300+ $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15)
301+ }
302+ let D = $t063216387._1
303+ let finished = $t063216387._2
304+ if ((finished == false))
305+ then throw(("get_D() not finished with " + toString(D)))
306+ else toInt(D)
307+ }
308+ }
309+
310+
311+func getDMem (xp,amp) = get_D(_xp_mem(xp), amp)
312+
313+
314+func getY (in,out,x,xp_) = if (assert((in != out)))
315+ then throw("same coin")
316+ else if (assert(if ((out >= 0))
317+ then (in >= 0)
318+ else false))
319+ then throw("below zero")
320+ else if (assert(if ((nCoins > out))
321+ then (nCoins > in)
322+ else false))
323+ then throw("above N_COINS")
324+ else {
325+ let amp = _A()
326+ let D = get_D(xp_, amp)
327+ let Ann = (amp * nCoins)
328+ func S_c (acc,i) = {
329+ let $t069586975 = acc
330+ let S_ = $t069586975._1
331+ let c = $t069586975._2
332+ let x_ = if ((in == i))
333+ then x
334+ else xp_[i]
335+ if (if ((i != out))
336+ then (nCoins > i)
337+ else false)
338+ then $Tuple2((S_ + x_), fraction(c, toBigInt(D), toBigInt((x_ * nCoins))))
339+ else $Tuple2(S_, c)
340+ }
341+
342+ let $t071837238 = {
343+ let $l = iter10
344+ let $s = size($l)
345+ let $acc0 = $Tuple2(0, toBigInt(D))
346+ func $f0_1 ($a,$i) = if (($i >= $s))
347+ then $a
348+ else S_c($a, $l[$i])
349+
350+ func $f0_2 ($a,$i) = if (($i >= $s))
351+ then $a
352+ else throw("List size exceeds 10")
353+
354+ $f0_2($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)
355+ }
356+ let S_ = $t071837238._1
357+ let c_ = $t071837238._2
358+ let c = fraction(c_, toBigInt(D), toBigInt((Ann * nCoins)))
359+ let bD = toBigInt(((S_ + (D / Ann)) - D))
360+ func y_proc (acc,_i) = if ((acc._2 == true))
361+ then acc
362+ else {
363+ let y_prev = acc._1
364+ let y = (((y_prev * y_prev) + c) / ((big2 * y_prev) + bD))
365+ if ((y > y_prev))
366+ then if ((1 >= toInt((y - y_prev))))
367+ then $Tuple2(y, true)
368+ else $Tuple2(y, false)
369+ else if ((1 >= toInt((y_prev - y))))
370+ then $Tuple2(y, true)
371+ else $Tuple2(y, false)
372+ }
373+
374+ let $t077207787 = {
375+ let $l = iter16
376+ let $s = size($l)
377+ let $acc0 = $Tuple2(toBigInt(D), false)
378+ func $f1_1 ($a,$i) = if (($i >= $s))
379+ then $a
380+ else y_proc($a, $l[$i])
381+
382+ func $f1_2 ($a,$i) = if (($i >= $s))
383+ then $a
384+ else throw("List size exceeds 16")
385+
386+ $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16)
387+ }
388+ let y = $t077207787._1
389+ let finished = $t077207787._2
390+ if ((finished == false))
391+ then throw(("getY() not finished with " + toString(y)))
392+ else toInt(y)
393+ }
394+
395+
396+func get_y_D (A_,in,xp,D) = if (assert((in >= 0)))
397+ then throw("i below zero")
398+ else if (assert((nCoins > in)))
399+ then throw("i above N_COINS")
400+ else {
401+ let Ann = (A_ * nCoins)
402+ func S_c (acc,i) = {
403+ let $t081668183 = acc
404+ let S_ = $t081668183._1
405+ let c = $t081668183._2
406+ let x_ = if (if ((in != i))
407+ then (nCoins > i)
408+ else false)
409+ then xp[i]
410+ else 0
411+ if (if ((nCoins > i))
412+ then (in != i)
413+ else false)
414+ then $Tuple2((S_ + x_), fraction(c, toBigInt(D), toBigInt((x_ * nCoins))))
415+ else $Tuple2(S_, c)
416+ }
417+
418+ let $t084038458 = {
419+ let $l = iter10
420+ let $s = size($l)
421+ let $acc0 = $Tuple2(0, toBigInt(D))
422+ func $f0_1 ($a,$i) = if (($i >= $s))
423+ then $a
424+ else S_c($a, $l[$i])
425+
426+ func $f0_2 ($a,$i) = if (($i >= $s))
427+ then $a
428+ else throw("List size exceeds 10")
429+
430+ $f0_2($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)
431+ }
432+ let S_ = $t084038458._1
433+ let c_ = $t084038458._2
434+ let c = fraction(c_, toBigInt(D), toBigInt((Ann * nCoins)))
435+ let bD = toBigInt(((S_ + (D / Ann)) - D))
436+ func y_D_proc (acc,i) = if ((acc._2 == true))
437+ then acc
438+ else {
439+ let y_prev = acc._1
440+ let y = (((y_prev * y_prev) + c) / ((big2 * y_prev) + bD))
441+ if ((y > y_prev))
442+ then if ((1 >= toInt((y - y_prev))))
443+ then $Tuple2(y, true)
444+ else $Tuple2(y, false)
445+ else if ((1 >= toInt((y_prev - y))))
446+ then $Tuple2(y, true)
447+ else $Tuple2(y, false)
448+ }
449+
450+ let $t089419010 = {
451+ let $l = iter16
452+ let $s = size($l)
453+ let $acc0 = $Tuple2(toBigInt(D), false)
454+ func $f1_1 ($a,$i) = if (($i >= $s))
455+ then $a
456+ else y_D_proc($a, $l[$i])
457+
458+ func $f1_2 ($a,$i) = if (($i >= $s))
459+ then $a
460+ else throw("List size exceeds 16")
461+
462+ $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16)
463+ }
464+ let y = $t089419010._1
465+ let finished = $t089419010._2
466+ if ((finished == false))
467+ then throw(("get_y_D() not finished with " + toString(y)))
468+ else toInt(y)
469+ }
470+
471+
472+func _calcWithdrawOneCoin (xp,_token_amount,i,caller) = {
473+ let feeDiscount = calculateFeeDiscount(caller)
474+ let amp = _A()
475+ let _fee = ((fraction(fee, feeDiscount, feeScale6, CEILING) * nCoins) / (4 * (nCoins - 1)))
476+ let total_supply = shareSupply
477+ let D0 = get_D(xp, amp)
478+ let D1 = (D0 - fraction(_token_amount, D0, total_supply))
479+ let new_y = get_y_D(amp, i, xp, D1)
480+ let dy_0 = (xp[i] - new_y)
481+ func xp_reduced_proc (acc,xp_j) = {
482+ let $t096519680 = acc
483+ let xp_reduced = $t096519680._1
484+ let index = $t096519680._2
485+ let dx_expected = if ((index == i))
486+ then (fraction(xp_j, D1, D0) - new_y)
487+ else (xp_j - fraction(xp_j, D1, D0))
488+ $Tuple2((xp_reduced :+ (xp_j - fraction(_fee, dx_expected, feeScale6))), (index + 1))
489+ }
490+
491+ let $t0994210006 = {
492+ let $l = xp
493+ let $s = size($l)
494+ let $acc0 = $Tuple2(nil, 0)
495+ func $f0_1 ($a,$i) = if (($i >= $s))
496+ then $a
497+ else xp_reduced_proc($a, $l[$i])
498+
499+ func $f0_2 ($a,$i) = if (($i >= $s))
500+ then $a
501+ else throw("List size exceeds 10")
502+
503+ $f0_2($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)
504+ }
505+ let xp_reduced = $t0994210006._1
506+ let index = $t0994210006._2
507+ let xp_reduced_i = xp_reduced[i]
508+ let dy = ((xp_reduced_i - get_y_D(amp, i, xp_reduced, D1)) - 1)
509+ $Tuple2(dy, (dy_0 - dy))
510+ }
511+
512+
513+func getStrAssetId (assetId) = match assetId {
514+ case id: ByteVector =>
515+ toBase58String(id)
516+ case waves: Unit =>
517+ "WAVES"
518+ case _ =>
519+ throw("Match error")
520+}
521+
522+
523+func calcStakingFuncAndAddres (stake,assetId) = if (stake)
524+ then $Tuple2("lockNeutrino", stakingUSDNAddress)
525+ else $Tuple2("unlockNeutrino", stakingUSDNAddress)
526+
527+
528+func calcStakingParams (stake,amount,assetId) = if (stake)
529+ then {
530+ let $t01057010636 = calcStakingFuncAndAddres(stake, assetId)
531+ let call = $t01057010636._1
532+ let stakingAddr = $t01057010636._2
533+ $Tuple4(call, stakingAddr, nil, [AttachedPayment(assetId, amount)])
534+ }
535+ else {
536+ let $t01072210788 = calcStakingFuncAndAddres(stake, assetId)
537+ let call = $t01072210788._1
538+ let stakingAddr = $t01072210788._2
539+ $Tuple4(call, stakingAddr, [amount, toBase58String(assetId)], nil)
540+ }
541+
542+
543+func stake (amount,assetIdString) = if (containsElement(stakingAssets, assetIdString))
544+ then {
545+ let $t01097511077 = calcStakingParams(true, amount, fromBase58String(assetIdString))
546+ let call = $t01097511077._1
547+ let addr = $t01097511077._2
548+ let params = $t01097511077._3
549+ let payments = $t01097511077._4
550+ invoke(addr, call, params, payments)
551+ }
552+ else 0
553+
554+
555+func unstake (amount,assetIdString) = if (containsElement(stakingAssets, assetIdString))
556+ then {
557+ let $t01126211365 = calcStakingParams(false, amount, fromBase58String(assetIdString))
558+ let call = $t01126211365._1
559+ let addr = $t01126211365._2
560+ let params = $t01126211365._3
561+ let payments = $t01126211365._4
562+ invoke(addr, call, params, payments)
563+ }
564+ else 0
565+
566+
567+func stakedAmount (assetId) = {
568+ let stakedAmountCalculated = match assetId {
569+ case aId: ByteVector =>
570+ if ((aId == USDN))
571+ then getInteger(stakingUSDNAddress, ((("rpd_balance_" + toBase58String(aId)) + "_") + toString(this)))
572+ else 0
573+ case _: Unit =>
574+ 0
575+ case _ =>
576+ throw("Match error")
577+ }
578+ match stakedAmountCalculated {
579+ case i: Int =>
580+ i
581+ case _ =>
582+ 0
583+ }
584+ }
585+
586+
587+func checkSuspicious () = {
588+ let contractBalances = _xp()
589+ func checkBalance (acc,assetId) = {
590+ let $t01197612001 = acc
591+ let suspicious = $t01197612001._1
592+ let i = $t01197612001._2
593+ if (suspicious)
594+ then $Tuple2(suspicious, i)
595+ else {
596+ let aBalance = (assetBalance(this, fromBase58String(assetId)) + stakedAmount(fromBase58String(assetId)))
597+ if ((contractBalances[i] > aBalance))
598+ then $Tuple2(true, i)
599+ else $Tuple2(false, (i + 1))
600+ }
601+ }
602+
603+ let $l = assetIds
604+ let $s = size($l)
605+ let $acc0 = $Tuple2(false, 0)
606+ func $f0_1 ($a,$i) = if (($i >= $s))
607+ then $a
608+ else checkBalance($a, $l[$i])
609+
610+ func $f0_2 ($a,$i) = if (($i >= $s))
611+ then $a
612+ else throw("List size exceeds 10")
613+
614+ $f0_2($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)
615+ }
616+
617+
618+func suspendSuspicious (i) = suspend(("Suspicious state with asset: " + assetIds[i]))
619+
620+
621+func returnPayments (caller,payments) = {
622+ func parsePayments (acc,payment) = (acc :+ ScriptTransfer(caller, payment.amount, payment.assetId))
623+
624+ let $l = payments
625+ let $s = size($l)
626+ let $acc0 = nil
627+ func $f0_1 ($a,$i) = if (($i >= $s))
628+ then $a
629+ else parsePayments($a, $l[$i])
630+
631+ func $f0_2 ($a,$i) = if (($i >= $s))
632+ then $a
633+ else throw("List size exceeds 10")
634+
635+ $f0_2($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)
636+ }
637+
638+
639+func checkDAppThreshold (newBalances) = {
640+ let dAppThresholdCoef = valueOrErrorMessage(getInteger(this, kDAppThresholdCoef), "No dAppThresholdCoef key")
641+ let thresholdScale = 10000
642+ let maxBalance = max(newBalances)
643+ let minBalance = min(newBalances)
644+ let ratio = fraction(maxBalance, thresholdScale, minBalance)
645+ if ((ratio > (dAppThresholdCoef * thresholdScale)))
646+ then throw("New balance in assets of the DApp is less than threshold")
647+ else false
648+ }
649+
650+
651+func checkCoins (assetIds) = {
652+ let coins = split(assetIds, ",")
653+ if ((size(coins) > 10))
654+ then throw("To many coins, max coins size 10")
655+ else {
656+ func checkCoin (error,assetId) = {
657+ let asset = valueOrErrorMessage(fromBase58String(assetId), ("fromBase58String: " + assetId))
658+ let decimals = valueOrErrorMessage(assetInfo(asset), ("assetInfo: " + assetId)).decimals
659+ if ((decimals != DECIMALS))
660+ then throw("wrong decimals")
661+ else false
662+ }
663+
664+ let $l = coins
665+ let $s = size($l)
666+ let $acc0 = false
667+ func $f0_1 ($a,$i) = if (($i >= $s))
668+ then $a
669+ else checkCoin($a, $l[$i])
670+
671+ func $f0_2 ($a,$i) = if (($i >= $s))
672+ then $a
673+ else throw("List size exceeds 10")
674+
675+ $f0_2($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)
676+ }
677+ }
678+
679+
680+@Callable(msg)
681+func D (xp,amp) = {
682+ let D = get_D_internal(xp, amp)
683+ $Tuple2([IntegerEntry("D", D)], D)
684+ }
685+
686+
687+
688+@Callable(msg)
689+func init (assetIds,_A,_dAppThresholdCoef) = if (!(isDataStorageUntouched(this)))
690+ then throw("Already initialized")
691+ else if ((0 >= _A))
692+ then throw("Amp must be must > 0")
693+ else if ((0 >= _dAppThresholdCoef))
694+ then throw("dApp Threshold Coef must be > 0")
695+ else {
696+ let shareName = "s_Multi_USD"
697+ let shareDescription = ("ShareToken of SwopFi protocol for MultiStable USD pool at address " + toString(this))
698+ let issueToken = Issue(shareName, shareDescription, 0, 6, true)
699+ let tokenId = calculateAssetId(issueToken)
700+ if (checkCoins(assetIds))
701+ then throw()
702+ else [StringEntry(kVersion, version), StringEntry(kAssets, assetIds), IntegerEntry("initial_A", _A), IntegerEntry("future_A", _A), IntegerEntry(kFee, getIntegerValue(oracle, "base_fee_flat")), StringEntry(kShareAssetId, toBase58String(tokenId)), IntegerEntry(kShareAssetSupply, 0), IntegerEntry(kDAppThresholdCoef, _dAppThresholdCoef), BooleanEntry(kActive, true), issueToken]
703+ }
704+
705+
706+
707+@Callable(msg)
708+func addLiquidity (minMintAmount,stakeFarming) = valueOrElse(isActive(), {
709+ let amp = _A()
710+ let xp = _xp()
711+ let D0 = if ((shareSupply == 0))
712+ then 0
713+ else getDMem(xp, amp)
714+ let payments = msg.payments
715+ let paymentsSize = size(payments)
716+ func validPayments (n) = if ((paymentsSize > nCoins))
717+ then throw(("payments size > " + toString(nCoins)))
718+ else if ((1 > paymentsSize))
719+ then throw("payments size < 1")
720+ else if (if ((shareSupply == 0))
721+ then (nCoins != paymentsSize)
722+ else false)
723+ then throw("initial deposit requires all coins")
724+ else {
725+ func paymantValid (acc,payment) = if (containsElement(assetIds, getStrAssetId(payment.assetId)))
726+ then true
727+ else throw("Invalid asset in payment")
728+
729+ let $l = payments
730+ let $s = size($l)
731+ let $acc0 = false
732+ func $f0_1 ($a,$i) = if (($i >= $s))
733+ then $a
734+ else paymantValid($a, $l[$i])
735+
736+ func $f0_2 ($a,$i) = if (($i >= $s))
737+ then $a
738+ else throw("List size exceeds 10")
739+
740+ $f0_2($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)
741+ }
742+
743+ if (!(validPayments(paymentsSize)))
744+ then throw()
745+ else {
746+ let suspicious = checkSuspicious()
747+ if (suspicious._1)
748+ then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.caller, payments))
749+ else {
750+ func parsePayments (acc,assetId) = {
751+ let $t01609216118 = acc
752+ let newBalances = $t01609216118._1
753+ let i = $t01609216118._2
754+ func parsePayment (newBalance,payment) = if ((getStrAssetId(payment.assetId) == assetId))
755+ then (newBalance + payment.amount)
756+ else newBalance
757+
758+ let newBalace = {
759+ let $l = payments
760+ let $s = size($l)
761+ let $acc0 = xp[i]
762+ func $f0_1 ($a,$i) = if (($i >= $s))
763+ then $a
764+ else parsePayment($a, $l[$i])
765+
766+ func $f0_2 ($a,$i) = if (($i >= $s))
767+ then $a
768+ else throw("List size exceeds 10")
769+
770+ $f0_2($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)
771+ }
772+ $Tuple2((newBalances :+ newBalace), (i + 1))
773+ }
774+
775+ let $t01646816535 = {
776+ let $l = assetIds
777+ let $s = size($l)
778+ let $acc0 = $Tuple2(nil, 0)
779+ func $f0_1 ($a,$i) = if (($i >= $s))
780+ then $a
781+ else parsePayments($a, $l[$i])
782+
783+ func $f0_2 ($a,$i) = if (($i >= $s))
784+ then $a
785+ else throw("List size exceeds 10")
786+
787+ $f0_2($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)
788+ }
789+ let newBalances = $t01646816535._1
790+ let k = $t01646816535._2
791+ if (checkDAppThreshold(newBalances))
792+ then throw()
793+ else {
794+ let D1 = getDMem(newBalances, amp)
795+ if (assert((D1 > D0)))
796+ then throw("D1 > D0")
797+ else {
798+ let feeDiscount = calculateFeeDiscount(msg.caller)
799+ func calcScriptActions (acc,newBalance) = {
800+ let $t01685516896 = acc
801+ let invBalances = $t01685516896._1
802+ let scriptActions = $t01685516896._2
803+ let i = $t01685516896._3
804+ if ((shareSupply > 0))
805+ then {
806+ let _fee = ((fraction(fee, feeDiscount, feeScale6, CEILING) * nCoins) / (4 * (nCoins - 1)))
807+ let fees = {
808+ let idealBalance = fraction(D1, xp[i], D0)
809+ let difference = if ((idealBalance > newBalance))
810+ then (idealBalance - newBalance)
811+ else (newBalance - idealBalance)
812+ fraction(_fee, difference, feeScale6)
813+ }
814+ let governanceFees = fraction(fees, feeGovernance, feeScale6)
815+ let finalBalance = (newBalance - fees)
816+ let invariantBalance = (newBalance - fees)
817+ let pmt = (newBalance - xp[i])
818+ let lpFees = (fees - governanceFees)
819+ let inv = if ((pmt > 0))
820+ then stake((pmt - fees), assetIds[i])
821+ else unstake(fees, assetIds[i])
822+ if ((inv == inv))
823+ then {
824+ let airdrop = if ((lpFees > 0))
825+ then invoke(lpFarmingAddress, "airDrop", nil, [AttachedPayment(fromBase58String(assetIds[i]), lpFees)])
826+ else 0
827+ if ((airdrop == airdrop))
828+ then $Tuple3((invBalances :+ invariantBalance), (scriptActions ++ [ScriptTransfer(moneyBoxAddress, governanceFees, fromBase58String(assetIds[i])), IntegerEntry((assetIds[i] + kAssetBalance), finalBalance)]), (i + 1))
829+ else throw("Strict value is not equal to itself.")
830+ }
831+ else throw("Strict value is not equal to itself.")
832+ }
833+ else {
834+ let inv = stake(newBalance, assetIds[i])
835+ if ((inv == inv))
836+ then $Tuple3((invBalances :+ newBalance), (scriptActions :+ IntegerEntry((assetIds[i] + kAssetBalance), newBalance)), (i + 1))
837+ else throw("Strict value is not equal to itself.")
838+ }
839+ }
840+
841+ let $t01860118689 = {
842+ let $l = newBalances
843+ let $s = size($l)
844+ let $acc0 = $Tuple3(nil, nil, 0)
845+ func $f1_1 ($a,$i) = if (($i >= $s))
846+ then $a
847+ else calcScriptActions($a, $l[$i])
848+
849+ func $f1_2 ($a,$i) = if (($i >= $s))
850+ then $a
851+ else throw("List size exceeds 10")
852+
853+ $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
854+ }
855+ let invBalances = $t01860118689._1
856+ let scriptActions = $t01860118689._2
857+ let D2 = getDMem(invBalances, amp)
858+ let mint_amount = if ((shareSupply == 0))
859+ then D1
860+ else fraction(shareSupply, (D2 - D0), D0)
861+ if (assert((mint_amount >= minMintAmount)))
862+ then throw("Slippage screwed you")
863+ else if (stakeFarming)
864+ then {
865+ let re = invoke(this, "reissueShare", [mint_amount], nil)
866+ if ((re == re))
867+ then {
868+ let s = invoke(farmingAddress, "lockShareTokens", [toString(this)], [AttachedPayment(shareAssetId, mint_amount)])
869+ if ((s == s))
870+ then (scriptActions :+ IntegerEntry(kShareAssetSupply, (shareSupply + mint_amount)))
871+ else throw("Strict value is not equal to itself.")
872+ }
873+ else throw("Strict value is not equal to itself.")
874+ }
875+ else (scriptActions ++ [Reissue(shareAssetId, mint_amount, true), ScriptTransfer(msg.caller, mint_amount, shareAssetId), IntegerEntry(kShareAssetSupply, (shareSupply + mint_amount))])
876+ }
877+ }
878+ }
879+ }
880+ })
881+
882+
883+
884+@Callable(msg)
885+func calcMintAmount (newBalances,user) = {
886+ let amp = _A()
887+ let xp = _xp()
888+ let D1 = getDMem(newBalances, amp)
889+ if ((shareSupply == 0))
890+ then $Tuple2(nil, D1)
891+ else {
892+ let D0 = getDMem(xp, amp)
893+ let feeDiscount = calculateFeeDiscount(user)
894+ func calcInvBalances (acc,newBalance) = {
895+ let $t01987819904 = acc
896+ let invBalances = $t01987819904._1
897+ let i = $t01987819904._2
898+ let _fee = ((fraction(fee, feeDiscount, feeScale6, CEILING) * nCoins) / (4 * (nCoins - 1)))
899+ let fees = {
900+ let idealBalance = fraction(D1, xp[i], D0)
901+ let difference = if ((idealBalance > newBalance))
902+ then (idealBalance - newBalance)
903+ else (newBalance - idealBalance)
904+ fraction(_fee, difference, feeScale6)
905+ }
906+ let invariantBalance = (newBalance - fees)
907+ $Tuple2((invBalances :+ invariantBalance), (i + 1))
908+ }
909+
910+ let $t02050620576 = {
911+ let $l = newBalances
912+ let $s = size($l)
913+ let $acc0 = $Tuple2(nil, 0)
914+ func $f0_1 ($a,$i) = if (($i >= $s))
915+ then $a
916+ else calcInvBalances($a, $l[$i])
917+
918+ func $f0_2 ($a,$i) = if (($i >= $s))
919+ then $a
920+ else throw("List size exceeds 10")
921+
922+ $f0_2($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)
923+ }
924+ let invBalances = $t02050620576._1
925+ let k = $t02050620576._2
926+ let D2 = getDMem(invBalances, amp)
927+ let mintAmount = fraction(shareSupply, (D2 - D0), D0)
928+ $Tuple2(nil, mintAmount)
929+ }
930+ }
931+
932+
933+
934+@Callable(msg)
935+func reissueShare (amount) = valueOrElse(isSelfCall(msg), [Reissue(shareAssetId, amount, true)])
936+
937+
938+
939+@Callable(msg)
940+func getDy (assetFrom,assetTo,dx,userAddress) = {
941+ let xp = _xp()
942+ let fromIndex = valueOrErrorMessage(indexOf(assetIds, assetFrom), "unknown token in")
943+ let toIndex = valueOrErrorMessage(indexOf(assetIds, assetTo), "unknown token out")
944+ let x = (xp[fromIndex] + dx)
945+ let y = getY(fromIndex, toIndex, x, xp)
946+ let dy = ((xp[toIndex] - y) - 1)
947+ let feeDiscount = calculateFeeDiscount(Address(fromBase58String(userAddress)))
948+ let _fee = fraction(fraction(fee, feeDiscount, feeScale6, CEILING), dy, feeScale6)
949+ $Tuple2(nil, $Tuple2((dy - _fee), _fee))
950+ }
951+
952+
953+
954+@Callable(msg)
955+func exchange (tokenOut,min_dy) = valueOrElse(isActive(), if ((size(msg.payments) != 1))
956+ then throw("size(payments) != 1")
957+ else {
958+ let suspicious = checkSuspicious()
959+ if (suspicious._1)
960+ then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.caller, msg.payments))
961+ else {
962+ let payment = msg.payments[0]
963+ let tokenIn = getStrAssetId(payment.assetId)
964+ let tokenOutB58 = fromBase58String(tokenOut)
965+ let dx = payment.amount
966+ let fromIndex = valueOrErrorMessage(indexOf(assetIds, tokenIn), "unknown token in")
967+ let toIndex = valueOrErrorMessage(indexOf(assetIds, tokenOut), "unknown token out")
968+ let xp = _xp()
969+ let x = (xp[fromIndex] + dx)
970+ let y = getY(fromIndex, toIndex, x, xp)
971+ let _dy = ((xp[toIndex] - y) - 1)
972+ let feeDiscount = calculateFeeDiscount(msg.originCaller)
973+ let _fee = fraction(_dy, fraction(fee, feeDiscount, feeScale6, CEILING), feeScale6)
974+ let dy = (_dy - _fee)
975+ let governanceFees = fraction(_fee, feeGovernance, feeScale6)
976+ if (assert((dy >= min_dy)))
977+ then throw("Exchange resulted in fewer coins than expected")
978+ else {
979+ func makeNewBalances (acc,tokenBalance) = {
980+ let $t02261722643 = acc
981+ let newBalances = $t02261722643._1
982+ let i = $t02261722643._2
983+ if ((i == fromIndex))
984+ then $Tuple2((newBalances :+ (tokenBalance + dx)), (i + 1))
985+ else if ((i == toIndex))
986+ then $Tuple2((newBalances :+ (tokenBalance - _dy)), (i + 1))
987+ else $Tuple2((newBalances :+ tokenBalance), (i + 1))
988+ }
989+
990+ let $t02289422955 = {
991+ let $l = xp
992+ let $s = size($l)
993+ let $acc0 = $Tuple2(nil, 0)
994+ func $f0_1 ($a,$i) = if (($i >= $s))
995+ then $a
996+ else makeNewBalances($a, $l[$i])
997+
998+ func $f0_2 ($a,$i) = if (($i >= $s))
999+ then $a
1000+ else throw("List size exceeds 10")
1001+
1002+ $f0_2($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)
1003+ }
1004+ let newBalances = $t02289422955._1
1005+ let i = $t02289422955._2
1006+ if (checkDAppThreshold(newBalances))
1007+ then throw()
1008+ else {
1009+ let s = stake(payment.amount, getStrAssetId(payment.assetId))
1010+ if ((s == s))
1011+ then {
1012+ let us = unstake(_dy, tokenOut)
1013+ if ((us == us))
1014+ then {
1015+ let lpFees = (_fee - governanceFees)
1016+ let airdrop = if ((lpFees > 0))
1017+ then invoke(lpFarmingAddress, "airDrop", nil, [AttachedPayment(tokenOutB58, lpFees)])
1018+ else 0
1019+ if ((airdrop == airdrop))
1020+ then $Tuple2([IntegerEntry((tokenIn + kAssetBalance), x), IntegerEntry((tokenOut + kAssetBalance), (xp[toIndex] - _dy)), ScriptTransfer(msg.caller, dy, tokenOutB58), ScriptTransfer(moneyBoxAddress, governanceFees, tokenOutB58)], [dy, tokenOutB58])
1021+ else throw("Strict value is not equal to itself.")
1022+ }
1023+ else throw("Strict value is not equal to itself.")
1024+ }
1025+ else throw("Strict value is not equal to itself.")
1026+ }
1027+ }
1028+ }
1029+ })
1030+
1031+
1032+
1033+@Callable(msg)
1034+func withdraw (minAmounts) = valueOrElse(isActive(), if ((size(msg.payments) != 1))
1035+ then throw("size(payments) != 1")
1036+ else {
1037+ let pmtAmount = msg.payments[0].amount
1038+ let pmtAssetId = msg.payments[0].assetId
1039+ if ((shareAssetId != pmtAssetId))
1040+ then throw("unknown payment token")
1041+ else {
1042+ let suspicious = checkSuspicious()
1043+ if (suspicious._1)
1044+ then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.originCaller, msg.payments))
1045+ else {
1046+ func calcScriptActions (acc,balance) = {
1047+ let $t02424624274 = acc
1048+ let scriptActions = $t02424624274._1
1049+ let i = $t02424624274._2
1050+ let wAmount = fraction(balance, pmtAmount, shareSupply)
1051+ if (assert((wAmount >= minAmounts[i])))
1052+ then throw("Withdrawal resulted in fewer coins than expected")
1053+ else {
1054+ let us = unstake(wAmount, assetIds[i])
1055+ if ((us == us))
1056+ then $Tuple2((scriptActions ++ [IntegerEntry((assetIds[i] + kAssetBalance), (balance - wAmount)), ScriptTransfer(msg.originCaller, wAmount, fromBase58String(assetIds[i]))]), (i + 1))
1057+ else throw("Strict value is not equal to itself.")
1058+ }
1059+ }
1060+
1061+ let $t02476424832 = {
1062+ let $l = _xp()
1063+ let $s = size($l)
1064+ let $acc0 = $Tuple2(nil, 0)
1065+ func $f0_1 ($a,$i) = if (($i >= $s))
1066+ then $a
1067+ else calcScriptActions($a, $l[$i])
1068+
1069+ func $f0_2 ($a,$i) = if (($i >= $s))
1070+ then $a
1071+ else throw("List size exceeds 10")
1072+
1073+ $f0_2($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)
1074+ }
1075+ let scriptActions = $t02476424832._1
1076+ let i = $t02476424832._2
1077+ (scriptActions ++ [Burn(shareAssetId, pmtAmount), IntegerEntry(kShareAssetSupply, (shareSupply - pmtAmount))])
1078+ }
1079+ }
1080+ })
1081+
1082+
1083+
1084+@Callable(msg)
1085+func withdrawWithUnlock (minAmounts,unlockAmount) = valueOrElse(isActive(), if ((0 >= unlockAmount))
1086+ then throw("Unlock amount must be positive")
1087+ else {
1088+ let suspicious = checkSuspicious()
1089+ if (suspicious._1)
1090+ then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.caller, msg.payments))
1091+ else {
1092+ let pmtAmount = if ((size(msg.payments) > 0))
1093+ then if ((size(msg.payments) != 1))
1094+ then throw("size(payments) != 1")
1095+ else {
1096+ let pmtAssetId = msg.payments[0].assetId
1097+ if ((shareAssetId != pmtAssetId))
1098+ then throw("unknown payment token")
1099+ else msg.payments[0].amount
1100+ }
1101+ else 0
1102+ let unlock = invoke(farmingAddress, "withdrawShareTokens", [toString(this), unlockAmount], nil)
1103+ if ((unlock == unlock))
1104+ then {
1105+ let withdrawAmount = (pmtAmount + unlockAmount)
1106+ let inv = invoke(this, "withdraw", [minAmounts], [AttachedPayment(shareAssetId, withdrawAmount)])
1107+ if ((inv == inv))
1108+ then nil
1109+ else throw("Strict value is not equal to itself.")
1110+ }
1111+ else throw("Strict value is not equal to itself.")
1112+ }
1113+ })
1114+
1115+
1116+
1117+@Callable(msg)
1118+func calcWithdrawOneCoin (tokenAmount,tokenOut,user) = if ((0 >= tokenAmount))
1119+ then throw("Amount must be positive")
1120+ else {
1121+ let i = valueOrErrorMessage(indexOf(assetIds, tokenOut), "unknown token out")
1122+ $Tuple2(nil, _calcWithdrawOneCoin(_xp(), tokenAmount, i, Address(fromBase58String(user)))._1)
1123+ }
1124+
1125+
1126+
1127+@Callable(msg)
1128+func withdrawOneCoin (tokenOut,minAmount) = valueOrElse(isActive(), if ((size(msg.payments) != 1))
1129+ then throw("size(payments) != 1")
1130+ else {
1131+ let suspicious = checkSuspicious()
1132+ if (suspicious._1)
1133+ then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.originCaller, msg.payments))
1134+ else {
1135+ let pmtAmount = msg.payments[0].amount
1136+ let pmtAssetId = msg.payments[0].assetId
1137+ if ((pmtAssetId != shareAssetId))
1138+ then throw("unknown token")
1139+ else {
1140+ let outIndex = valueOrErrorMessage(indexOf(assetIds, tokenOut), "unknown token out")
1141+ let tokenOutB58 = fromBase58String(tokenOut)
1142+ let xp = _xp()
1143+ let $t02686426946 = _calcWithdrawOneCoin(xp, pmtAmount, outIndex, msg.originCaller)
1144+ let dy = $t02686426946._1
1145+ let dy_fee = $t02686426946._2
1146+ if (assert((dy >= minAmount)))
1147+ then throw("Not enough coins removed")
1148+ else {
1149+ let governanceFees = fraction(dy_fee, feeGovernance, feeScale6)
1150+ let dy_and_fee = (dy + dy_fee)
1151+ func makeNewBalances (acc,tokenBalance) = {
1152+ let $t02720427230 = acc
1153+ let newBalances = $t02720427230._1
1154+ let i = $t02720427230._2
1155+ if ((i == outIndex))
1156+ then $Tuple2((newBalances :+ (tokenBalance - dy_and_fee)), (i + 1))
1157+ else $Tuple2((newBalances :+ tokenBalance), (i + 1))
1158+ }
1159+
1160+ let $t02739727458 = {
1161+ let $l = xp
1162+ let $s = size($l)
1163+ let $acc0 = $Tuple2(nil, 0)
1164+ func $f0_1 ($a,$i) = if (($i >= $s))
1165+ then $a
1166+ else makeNewBalances($a, $l[$i])
1167+
1168+ func $f0_2 ($a,$i) = if (($i >= $s))
1169+ then $a
1170+ else throw("List size exceeds 10")
1171+
1172+ $f0_2($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)
1173+ }
1174+ let newBalances = $t02739727458._1
1175+ let v = $t02739727458._2
1176+ if (checkDAppThreshold(newBalances))
1177+ then throw()
1178+ else {
1179+ let us = unstake(dy_and_fee, tokenOut)
1180+ if ((us == us))
1181+ then {
1182+ let lpFees = (dy_fee - governanceFees)
1183+ let airdrop = if ((lpFees > 0))
1184+ then invoke(lpFarmingAddress, "airDrop", nil, [AttachedPayment(tokenOutB58, lpFees)])
1185+ else 0
1186+ if ((airdrop == airdrop))
1187+ then [ScriptTransfer(msg.originCaller, dy, tokenOutB58), IntegerEntry((assetIds[outIndex] + kAssetBalance), (xp[outIndex] - dy_and_fee)), Burn(shareAssetId, pmtAmount), ScriptTransfer(moneyBoxAddress, governanceFees, tokenOutB58), IntegerEntry(kShareAssetSupply, (shareSupply - pmtAmount))]
1188+ else throw("Strict value is not equal to itself.")
1189+ }
1190+ else throw("Strict value is not equal to itself.")
1191+ }
1192+ }
1193+ }
1194+ }
1195+ })
1196+
1197+
1198+
1199+@Callable(msg)
1200+func withdrawOneCoinWithUnlock (tokenOut,minAmount,unlockAmount) = valueOrElse(isActive(), if ((0 >= unlockAmount))
1201+ then throw("Unlock amount must be positive")
1202+ else {
1203+ let suspicious = checkSuspicious()
1204+ if (suspicious._1)
1205+ then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.caller, msg.payments))
1206+ else {
1207+ let pmtAmount = if ((size(msg.payments) > 0))
1208+ then if ((size(msg.payments) != 1))
1209+ then throw("size(payments) != 1")
1210+ else {
1211+ let pmtAssetId = msg.payments[0].assetId
1212+ if ((shareAssetId != pmtAssetId))
1213+ then throw("unknown payment token")
1214+ else msg.payments[0].amount
1215+ }
1216+ else 0
1217+ let unlock = invoke(farmingAddress, "withdrawShareTokens", [toString(this), unlockAmount], nil)
1218+ if ((unlock == unlock))
1219+ then {
1220+ let withdrawAmount = (pmtAmount + unlockAmount)
1221+ let inv = invoke(this, "withdrawOneCoin", [tokenOut, minAmount], [AttachedPayment(shareAssetId, withdrawAmount)])
1222+ if ((inv == inv))
1223+ then nil
1224+ else throw("Strict value is not equal to itself.")
1225+ }
1226+ else throw("Strict value is not equal to itself.")
1227+ }
1228+ })
1229+
1230+
1231+
1232+@Callable(msg)
1233+func A () = $Tuple2(nil, _A())
1234+
1235+
1236+
1237+@Callable(msg)
1238+func getVirtualPrice () = {
1239+ let D = get_D(_xp(), _A())
1240+ $Tuple2(nil, fraction(D, PRECISION, shareSupply))
1241+ }
1242+
1243+
1244+
1245+@Callable(msg)
1246+func calcTokenAmount (amounts,deposit) = {
1247+ let amp = _A()
1248+ let balances = _xp()
1249+ let D0 = getDMem(balances, amp)
1250+ func calcNewBalances (acc,balance) = {
1251+ let $t02947529501 = acc
1252+ let newBalances = $t02947529501._1
1253+ let i = $t02947529501._2
1254+ let newBalance = (balance + (if (deposit)
1255+ then amounts[i]
1256+ else -(amounts[i])))
1257+ $Tuple2((newBalances :+ newBalance), (i + 1))
1258+ }
1259+
1260+ let newBalances = ( let $l = balances
1261+ let $s = size($l)
1262+ let $acc0 = $Tuple2(nil, 0)
1263+ func $f0_1 ($a,$i) = if (($i >= $s))
1264+ then $a
1265+ else calcNewBalances($a, $l[$i])
1266+
1267+ func $f0_2 ($a,$i) = if (($i >= $s))
1268+ then $a
1269+ else throw("List size exceeds 10")
1270+
1271+ $f0_2($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))._1
1272+ let D1 = getDMem(newBalances, amp)
1273+ let diff = if (deposit)
1274+ then (D1 - D0)
1275+ else (D0 - D1)
1276+ $Tuple2(nil, fraction(diff, shareSupply, D0))
1277+ }
1278+
1279+
1280+
1281+@Callable(msg)
1282+func rampA (_futureA,_futureTime) = valueOrElse(isActive(), valueOrElse(isAdminCall(msg), if (assert((blockTimestamp >= (initial_A_time + MIN_RAMP_TIME))))
1283+ then throw("too often")
1284+ else if (assert((_futureTime >= (blockTimestamp + MIN_RAMP_TIME))))
1285+ then throw("insufficient time")
1286+ else {
1287+ let _initial_A = _A()
1288+ if (assert(if ((_futureA > 0))
1289+ then (MAX_A > _futureA)
1290+ else false))
1291+ then throw("out of base range")
1292+ else if (assert(if (if ((_futureA >= _initial_A))
1293+ then ((_initial_A * MAX_A_CHANGE) >= _futureA)
1294+ else false)
1295+ then true
1296+ else if ((_initial_A > _futureA))
1297+ then ((_futureA * MAX_A_CHANGE) >= _initial_A)
1298+ else false))
1299+ then throw("out of range")
1300+ else [IntegerEntry("initial_A", _initial_A), IntegerEntry("future_A", _futureA), IntegerEntry("initial_A_time", blockTimestamp), IntegerEntry("future_A_time", _futureTime)]
1301+ }))
1302+
1303+
1304+
1305+@Callable(msg)
1306+func stopRampA () = valueOrElse(isActive(), valueOrElse(isAdminCall(msg), {
1307+ let currentA = _A()
1308+[IntegerEntry("initial_A", currentA), IntegerEntry("future_A", currentA), IntegerEntry("initial_A_time", blockTimestamp), IntegerEntry("future_A_time", blockTimestamp)]
1309+ }))
1310+
1311+
1312+
1313+@Callable(msg)
1314+func shutdown () = valueOrElse(isAdminCall(msg), if (!(active))
1315+ then throw(("DApp is already suspended. Cause: " + valueOrElse(getString(this, kCause), "the cause wasn't specified")))
1316+ else suspend("Paused by admin"))
1317+
1318+
1319+
1320+@Callable(msg)
1321+func activate () = valueOrElse(isAdminCall(msg), if (active)
1322+ then throwIsActive()
1323+ else [BooleanEntry(kActive, true), DeleteEntry(kCause)])
1324+
1325+
1326+
1327+@Callable(msg)
1328+func takeIntoAccountExtraFunds () = valueOrElse(isActive(), if ((msg.caller != moneyBoxAddress))
1329+ then throw("Only the wallet can call this function")
1330+ else {
1331+ let balances = _xp()
1332+ func takeExtraFunds (acc,assetId) = {
1333+ let $t03184331861 = acc
1334+ let sum = $t03184331861._1
1335+ let i = $t03184331861._2
1336+ let tokenB58 = fromBase58String(assetId)
1337+ let rBalance = (assetBalance(this, tokenB58) + stakedAmount(tokenB58))
1338+ let enrollAmount = (rBalance - balances[i])
1339+ if ((0 > enrollAmount))
1340+ then suspend(("Enroll amount negative for asset" + assetId))
1341+ else {
1342+ let airdrop = if ((enrollAmount > 0))
1343+ then invoke(lpFarmingAddress, "airDrop", nil, [AttachedPayment(tokenB58, enrollAmount)])
1344+ else 0
1345+ if ((airdrop == airdrop))
1346+ then $Tuple2((sum + enrollAmount), (i + 1))
1347+ else throw("Strict value is not equal to itself.")
1348+ }
1349+ }
1350+
1351+ let k = {
1352+ let $l = assetIds
1353+ let $s = size($l)
1354+ let $acc0 = $Tuple2(0, 0)
1355+ func $f0_1 ($a,$i) = if (($i >= $s))
1356+ then $a
1357+ else takeExtraFunds($a, $l[$i])
1358+
1359+ func $f0_2 ($a,$i) = if (($i >= $s))
1360+ then $a
1361+ else throw("List size exceeds 10")
1362+
1363+ $f0_2($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)
1364+ }
1365+ if ((k._1 == 0))
1366+ then throw("No money to take")
1367+ else nil
1368+ })
1369+
1370+
1371+@Verifier(tx)
1372+func verify () = {
1373+ let multiSignedByAdmins = {
1374+ let adminPubKey1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
1375+ then 1
1376+ else 0
1377+ let adminPubKey2Signed = if (sigVerify(tx.bodyBytes, tx.proofs[1], adminPubKey2))
1378+ then 1
1379+ else 0
1380+ let adminPubKey3Signed = if (sigVerify(tx.bodyBytes, tx.proofs[2], adminPubKey3))
1381+ then 1
1382+ else 0
1383+ (((adminPubKey1Signed + adminPubKey2Signed) + adminPubKey3Signed) >= 2)
1384+ }
1385+ match tx {
1386+ case inv: InvokeScriptTransaction =>
1387+ let callTakeIntoAccount = if ((inv.dApp == this))
1388+ then (inv.function == "takeIntoAccountExtraFunds")
1389+ else false
1390+ let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
1391+ then true
1392+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey2))
1393+ then true
1394+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey3))
1395+ then true
1396+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKeyInvoke)
1397+ if (if (callTakeIntoAccount)
1398+ then signedByAdmin
1399+ else false)
1400+ then true
1401+ else multiSignedByAdmins
1402+ case _ =>
1403+ multiSignedByAdmins
1404+ }
1405+ }
1406+

github/deemru/w8io/3ef1775 
92.87 ms