tx · 4q3Vp3qM3eNq4RPCGQm1hT9GtXi47KZS539WZp4kZnkL

3MxWgDbE9EmjQj8b3LfFwa91FZizptyeQXS:  -0.07000000 Waves

2022.10.25 18:32 [2288105] smart account 3MxWgDbE9EmjQj8b3LfFwa91FZizptyeQXS > SELF 0.00000000 Waves

{ "type": 13, "id": "4q3Vp3qM3eNq4RPCGQm1hT9GtXi47KZS539WZp4kZnkL", "fee": 7000000, "feeAssetId": null, "timestamp": 1666711914493, "version": 2, "chainId": 84, "sender": "3MxWgDbE9EmjQj8b3LfFwa91FZizptyeQXS", "senderPublicKey": "C7xgcYqQ8qV8rmvzAjhQWq4cz82F6VJfXMNygvrTXsfW", "proofs": [ "R3vqL1YPKZ6SDAtnAzx4ikRZCW5KGhaRR7mVRCZA8av4CHDPddYF4R8C8weUrDQPBheCRQN526KR1xn9jGWe38k", "2PrZoLqzCq6yRKgFJnybVkbNPVdToPBLR7h9Pjr9NnVsMsaHm6WuUxN2cz2UPbyUGmbGmATZyLsJsGt8BqBKPYJ1" ], "script": "base64:BgJmCAISBAoCEQESBQoDCAEBEgUKAwEEARIECgIRCBIDCgEBEgYKBAgIAQgSBAoCCAESAwoBERIECgIRARIFCgMBCAgSBAoCCAESBQoDCAEBEgASABIECgIRBBIECgIBARIAEgASABIAWAAJUFJFQ0lTSU9OAMCEPQAFTUFYX0EAwIQ9AAxNQVhfQV9DSEFOR0UACgAIREVDSU1BTFMABgANTUlOX1JBTVBfVElNRQkAaQIAgKMFADwAB3ZlcnNpb24CBTMuMC4wAAhrVmVyc2lvbgIHdmVyc2lvbgAHa0Fzc2V0cwIJYXNzZXRfaWRzAA1rQXNzZXRCYWxhbmNlAghfYmFsYW5jZQAHa0FjdGl2ZQIGYWN0aXZlAAZrQ2F1c2UCDnNodXRkb3duX2NhdXNlAA1rU2hhcmVBc3NldElkAg5zaGFyZV9hc3NldF9pZAARa1NoYXJlQXNzZXRTdXBwbHkCEnNoYXJlX2Fzc2V0X3N1cHBseQAEa0ZlZQIKY29tbWlzc2lvbgASa0RBcHBUaHJlc2hvbGRDb2VmAhFkQXBwVGhyZXNob2xkQ29lZgAMa1VTRE5BZGRyZXNzAhhzdGFraW5nX3VzZG5uc2J0X2FkZHJlc3MACmtEaXNjb3VudHMCCWRpc2NvdW50cwAPa0Rpc2NvdW50VmFsdWVzAg9kaXNjb3VudF92YWx1ZXMADmtVc2VyU3dvcEluR292AgxfU1dPUF9hbW91bnQAD2tVc2VyR1N3b3BJbkdvdgINX0dTd29wX2Ftb3VudAANa0FkbWluUHViS2V5MQILYWRtaW5fcHViXzEADWtBZG1pblB1YktleTICC2FkbWluX3B1Yl8yAA1rQWRtaW5QdWJLZXkzAgthZG1pbl9wdWJfMwASa0FkbWluSW52b2tlUHViS2V5AhBhZG1pbl9pbnZva2VfcHViABBrTW9uZXlCb3hBZGRyZXNzAhFtb25leV9ib3hfYWRkcmVzcwALa0dvdkFkZHJlc3MCEmdvdmVybmFuY2VfYWRkcmVzcwAOa1ZvdGluZ0FkZHJlc3MCDnZvdGluZ19hZGRyZXNzAA9rRmFybWluZ0FkZHJlc3MCD2Zhcm1pbmdfYWRkcmVzcwARa0xQRmFybWluZ0FkZHJlc3MCCmxwX2Zhcm1pbmcABm9yYWNsZQkBB0FkZHJlc3MBARoBVEgTlwzA0zPMJTKAtin3p2RogKvjzHtLmQETZ2V0QmFzZTU4RnJvbU9yYWNsZQEDa2V5BAckbWF0Y2gwCQCdCAIFBm9yYWNsZQUDa2V5AwkAAQIFByRtYXRjaDACBlN0cmluZwQGc3RyaW5nBQckbWF0Y2gwCQDZBAEFBnN0cmluZwQHbm90aGluZwUHJG1hdGNoMAkAAgEJAKwCAgUDa2V5AghpcyBlbXB0eQAMYWRtaW5QdWJLZXkxCQETZ2V0QmFzZTU4RnJvbU9yYWNsZQEFDWtBZG1pblB1YktleTEADGFkbWluUHViS2V5MgkBE2dldEJhc2U1OEZyb21PcmFjbGUBBQ1rQWRtaW5QdWJLZXkyAAxhZG1pblB1YktleTMJARNnZXRCYXNlNThGcm9tT3JhY2xlAQUNa0FkbWluUHViS2V5MwARYWRtaW5QdWJLZXlJbnZva2UJARNnZXRCYXNlNThGcm9tT3JhY2xlAQUSa0FkbWluSW52b2tlUHViS2V5AA9tb25leUJveEFkZHJlc3MJAQdBZGRyZXNzAQkBE2dldEJhc2U1OEZyb21PcmFjbGUBBRBrTW9uZXlCb3hBZGRyZXNzAApnb3ZBZGRyZXNzCQEHQWRkcmVzcwEJARNnZXRCYXNlNThGcm9tT3JhY2xlAQULa0dvdkFkZHJlc3MAEnN0YWtpbmdVU0ROQWRkcmVzcwkBB0FkZHJlc3MBCQETZ2V0QmFzZTU4RnJvbU9yYWNsZQEFDGtVU0ROQWRkcmVzcwANdm90aW5nQWRkcmVzcwkBB0FkZHJlc3MBCQETZ2V0QmFzZTU4RnJvbU9yYWNsZQEFDmtWb3RpbmdBZGRyZXNzAA5mYXJtaW5nQWRkcmVzcwkBB0FkZHJlc3MBCQETZ2V0QmFzZTU4RnJvbU9yYWNsZQEFD2tGYXJtaW5nQWRkcmVzcwAQbHBGYXJtaW5nQWRkcmVzcwkBB0FkZHJlc3MBCQETZ2V0QmFzZTU4RnJvbU9yYWNsZQEFEWtMUEZhcm1pbmdBZGRyZXNzAARVU0ROASBvJKPKqzDcUimY6CxhWu5afyNNwi11u+mdqlTg0tAHwQANc3Rha2luZ0Fzc2V0cwkAzAgCCQDYBAEFBFVTRE4FA25pbAAGYWN0aXZlCQERQGV4dHJOYXRpdmUoMTA1MSkCBQR0aGlzBQdrQWN0aXZlAAxzaGFyZUFzc2V0SWQJANkEAQkBEUBleHRyTmF0aXZlKDEwNTMpAgUEdGhpcwUNa1NoYXJlQXNzZXRJZAALc2hhcmVTdXBwbHkJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMFEWtTaGFyZUFzc2V0U3VwcGx5AAlmZWVTY2FsZTYAwIQ9AANmZWUJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMFBGtGZWUADWZlZUdvdmVybmFuY2UJAGsDACgFCWZlZVNjYWxlNgBkAAlpbml0aWFsX0EJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMCCWluaXRpYWxfQQAIZnV0dXJlX0EJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMCCGZ1dHVyZV9BAA5pbml0aWFsX0FfdGltZQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzAg5pbml0aWFsX0FfdGltZQAAAA1mdXR1cmVfQV90aW1lCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMCDWZ1dHVyZV9BX3RpbWUAAAAIYXNzZXRJZHMJALUJAgkBEUBleHRyTmF0aXZlKDEwNTMpAgUEdGhpcwUHa0Fzc2V0cwIBLAAGbkNvaW5zCQCQAwEFCGFzc2V0SWRzAQdzdXNwZW5kAQVjYXVzZQkAzAgCCQEMQm9vbGVhbkVudHJ5AgUHa0FjdGl2ZQcJAMwIAgkBC1N0cmluZ0VudHJ5AgUGa0NhdXNlBQVjYXVzZQUDbmlsAQ10aHJvd0lzQWN0aXZlAAkAAgECFkRBcHAgaXMgYWxyZWFkeSBhY3RpdmUBCGlzQWN0aXZlAAMFBmFjdGl2ZQUEdW5pdAkAAgECH0RBcHAgaXMgaW5hY3RpdmUgYXQgdGhpcyBtb21lbnQBC2lzQWRtaW5DYWxsAQFpAwkBD2NvbnRhaW5zRWxlbWVudAIJAMwIAgUMYWRtaW5QdWJLZXkxCQDMCAIFDGFkbWluUHViS2V5MgkAzAgCBQxhZG1pblB1YktleTMFA25pbAgFAWkPY2FsbGVyUHVibGljS2V5BQR1bml0CQACAQIhT25seSBhZG1pbiBjYW4gY2FsbCB0aGlzIGZ1bmN0aW9uAQppc1NlbGZDYWxsAQFpAwkAAAIFBHRoaXMIBQFpBmNhbGxlcgUEdW5pdAkAAgECK09ubHkgY29udHJhY3QgaXRzZWxmIGNhbiBjYWxsIHRoaXMgZnVuY3Rpb24ABGJpZzIJALYCAQACAAZpdGVyMTAJAMwIAgAACQDMCAIAAQkAzAgCAAIJAMwIAgADCQDMCAIABAkAzAgCAAUJAMwIAgAGCQDMCAIABwkAzAgCAAgJAMwIAgAJBQNuaWwABml0ZXIxNQkAzAgCAAAJAMwIAgABCQDMCAIAAgkAzAgCAAMJAMwIAgAECQDMCAIABQkAzAgCAAYJAMwIAgAHCQDMCAIACAkAzAgCAAkJAMwIAgAKCQDMCAIACwkAzAgCAAwJAMwIAgANCQDMCAIADgUDbmlsAAZpdGVyMTYJAMwIAgAACQDMCAIAAQkAzAgCAAIJAMwIAgADCQDMCAIABAkAzAgCAAUJAMwIAgAGCQDMCAIABwkAzAgCAAgJAMwIAgAJCQDMCAIACgkAzAgCAAsJAMwIAgAMCQDMCAIADQkAzAgCAA4JAMwIAgAPBQNuaWwADmJsb2NrVGltZXN0YW1wBQZoZWlnaHQBBmFzc2VydAEBYQMFAWEHBgEUY2FsY3VsYXRlRmVlRGlzY291bnQBCHVzZXJBZGRyBAR1c2VyBAckbWF0Y2gwBQh1c2VyQWRkcgMJAAECBQckbWF0Y2gwAgdBZGRyZXNzBAF1BQckbWF0Y2gwCQClCAEFAXUDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAF1BQckbWF0Y2gwBQF1CQACAQIYVW5rbm93IHR5cGUgb2YgdXNlciBBZGRyBApzd29wQW1vdW50CQELdmFsdWVPckVsc2UCCQCaCAIFCmdvdkFkZHJlc3MJAKwCAgUEdXNlcgUPa1VzZXJHU3dvcEluR292AAAEC2dTd29wQW1vdW50CQELdmFsdWVPckVsc2UCCQCaCAIFCmdvdkFkZHJlc3MJAKwCAgUEdXNlcgUPa1VzZXJHU3dvcEluR292BQpzd29wQW1vdW50BA5kaXNjb3VudFZhbHVlcwkAtQkCCQERQGV4dHJOYXRpdmUoMTA1MykCBQZvcmFjbGUFD2tEaXNjb3VudFZhbHVlcwIBLAQJZGlzY291bnRzCQC1CQIJARFAZXh0ck5hdGl2ZSgxMDUzKQIFBm9yYWNsZQUKa0Rpc2NvdW50cwIBLAMDCQBnAgULZ1N3b3BBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5kaXNjb3VudFZhbHVlcwAACQBmAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDmRpc2NvdW50VmFsdWVzAAEFC2dTd29wQW1vdW50BwkAZQIFCWZlZVNjYWxlNgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWRpc2NvdW50cwAAAwMJAGcCBQtnU3dvcEFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDmRpc2NvdW50VmFsdWVzAAEJAGYCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUOZGlzY291bnRWYWx1ZXMAAgULZ1N3b3BBbW91bnQHCQBlAgUJZmVlU2NhbGU2CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUJZGlzY291bnRzAAEDAwkAZwIFC2dTd29wQW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUOZGlzY291bnRWYWx1ZXMAAgkAZgIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5kaXNjb3VudFZhbHVlcwADBQtnU3dvcEFtb3VudAcJAGUCBQlmZWVTY2FsZTYJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQlkaXNjb3VudHMAAgMDCQBnAgULZ1N3b3BBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5kaXNjb3VudFZhbHVlcwADCQBmAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDmRpc2NvdW50VmFsdWVzAAQFC2dTd29wQW1vdW50BwkAZQIFCWZlZVNjYWxlNgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWRpc2NvdW50cwADAwkAZwIFC2dTd29wQW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUOZGlzY291bnRWYWx1ZXMABAkAZQIFCWZlZVNjYWxlNgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWRpc2NvdW50cwAEBQlmZWVTY2FsZTYBAl9BAAQCdDEFDWZ1dHVyZV9BX3RpbWUEAkExBQhmdXR1cmVfQQMJAGYCBQJ0MQUOYmxvY2tUaW1lc3RhbXAEAkEwBQlpbml0aWFsX0EEAnQwBQ5pbml0aWFsX0FfdGltZQMJAGYCBQJBMQUCQTAJAGQCBQJB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MTAxNDYCXzIEDHhwX3JlZHVjZWRfaQkAkQMCBQp4cF9yZWR1Y2VkBQFpBAJkeQkAZQIJAGUCBQx4cF9yZWR1Y2VkX2kJAQdnZXRfeV9EBAUDYW1wBQFpBQp4cF9yZWR1Y2VkBQJEMQABCQCUCgIFAmR5CQBlAgUEZHlfMAUCZHkBDWdldFN0ckFzc2V0SWQBB2Fzc2V0SWQEByRtYXRjaDAFB2Fzc2V0SWQDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQCaWQFByRtYXRjaDAJANgEAQUCaWQDCQABAgUHJG1hdGNoMAIEVW5pdAQFd2F2ZXMFByRtYXRjaDACBVdBVkVTCQACAQILTWF0Y2ggZXJyb3IBGGNhbGNTdGFraW5nRnVuY0FuZEFkZHJlcwIFc3Rha2UHYXNzZXRJZAMFBXN0YWtlCQCUCgICDGxvY2tOZXV0cmlubwUSc3Rha2luZ1VTRE5BZGRyZXNzCQCUCgICDnVubG9ja05ldXRyaW5vBRJzdGFraW5nVVNETkFkZHJlc3MBEWNhbGNTdGFraW5nUGFyYW1zAwVzdGFrZQZhbW91bnQHYXNzZXRJZAMFBXN0YWtlBA0kdDAxMDcxMDEwNzc2CQEYY2FsY1N0YWtpbmdGdW5jQW5kQWRkcmVzAgUFc3Rha2UFB2Fzc2V0SWQEBGNhbGwIBQ0kdDAxMDcxMDEwNzc2Al8xBAtzdGFraW5nQWRkcggFDSR0MDEwNzEwMTA3NzYCXzIJAJYKBAUEY2FsbAULc3Rha2luZ0FkZHIFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUHYXNzZXRJZAUGYW1vdW50BQNuaWwEDSR0MDEwODYyMTA5MjgJARhjYWxjU3Rha2luZ0Z1bmNBbmRBZGRyZXMCBQVzdGFrZQUHYXNzZXRJZAQEY2FsbAgFDSR0MDEwODYyMTA5MjgCXzEEC3N0YWtpbmdBZGRyCAUNJHQwMTA4NjIxMDkyOAJfMgkAlgoEBQRjYWxsBQtzdGFraW5nQWRkcgkAzAgCBQZhbW91bnQJAMwIAgkA2AQBBQdhc3NldElkBQNuaWwFA25pbAEFc3Rha2UCBmFtb3VudA1hc3NldElkU3RyaW5nAwkBD2NvbnRhaW5zRWxlbWVudAIFDXN0YWtpbmdBc3NldHMFDWFzc2V0SWRTdHJpbmcEDSR0MDExMTE1MTEyMTcJARFjYWxjU3Rha2luZ1BhcmFtcwMGBQZhbW91bnQJANkEAQUNYXNzZXRJZFN0cmluZwQEY2FsbAgFDSR0MDExMTE1MTEyMTcCXzEEBGFkZHIIBQ0kdDAxMTExNTExMjE3Al8yBAZwYXJhbXMIBQ0kdDAxMTExNTExMjE3Al8zBAhwYXltZW50cwgFDSR0MDExMTE1MTEyMTcCXzQJAPwHBAUEYWRkcgUEY2FsbAUGcGFyYW1zBQhwYXltZW50cwAAAQd1bnN0YWtlAgZhbW91bnQNYXNzZXRJZFN0cmluZwMJAQ9jb250YWluc0VsZW1lbnQCBQ1zdGFraW5nQXNzZXRzBQ1hc3NldElkU3RyaW5nBA0kdDAxMTQwMjExNTA1CQERY2FsY1N0YWtpbmdQYXJhbXMDBwUGYW1vdW50CQDZBAEFDWFzc2V0SWRTdHJpbmcEBGNhbGwIBQ0kdDAxMTQwMjExNTA1Al8xBARhZGRyCAUNJHQwMTE0MDIxMTUwNQJfMgQGcGFyYW1zCAUNJHQwMTE0MDIxMTUwNQJfMwQIcGF5bWVudHMIBQ0kdDAxMTQwMjExNTA1Al80CQD8BwQFBGFkZHIFBGNhbGwFBnBhcmFtcwUIcGF5bWVudHMAAAEMc3Rha2VkQW1vdW50AQdhc3NldElkBBZzdGFrZWRBbW91bnRDYWxjdWxhdGVkBAckbWF0Y2gwBQdhc3NldElkAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEA2FJZAUHJG1hdGNoMAMJAAACBQNhSWQFBFVTRE4JAJoIAgUSc3Rha2luZ1VTRE5BZGRyZXNzCQCsAgIJAKwCAgkArAICAgxycGRfYmFsYW5jZV8JANgEAQUDYUlkAgFfCQClCAEFBHRoaXMAAAMJAAECBQckbWF0Y2gwAgRVbml0AAAJAAIBAgtNYXRjaCBlcnJvcgQHJG1hdGNoMAUWc3Rha2VkQW1vdW50Q2FsY3VsYXRlZAMJAAECBQckbWF0Y2gwAgNJbnQEAWkFByRtYXRjaDAFAWkAAAEPY2hlY2tTdXNwaWNpb3VzAAQQY29udHJhY3RCYWxhbmNlcwkBA194cAAKAQxjaGVja0JhbGFuY2UCA2FjYwdhc3NldElkBA0kdDAxMjExNjEyMTQxBQNhY2MECnN1c3BpY2lvdXMIBQ0kdDAxMjExNjEyMTQxAl8xBAFpCAUNJHQwMTIxMTYxMjE0MQJfMgMFCnN1c3BpY2lvdXMJAJQKAgUKc3VzcGljaW91cwUBaQQIYUJhbGFuY2UJAGQCCQDwBwIFBHRoaXMJANkEAQUHYXNzZXRJZAkBDHN0YWtlZEFtb3VudAEJANkEAQUHYXNzZXRJZAMJAGYCCQCRAwIFEGNvbnRyYWN0QmFsYW5jZXMFAWkFCGFCYWxhbmNlCQCUCgIGBQFpCQCUCgIHCQBkAgUBaQABCgACJGwFCGFzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlAoCBwAACgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQxjaGVja0JhbGFuY2UCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoBEXN1c3BlbmRTdXNwaWNpb3VzAQFpCQEHc3VzcGVuZAEJAKwCAgIdU3VzcGljaW91cyBzdGF0ZSB3aXRoIGFzc2V0OiAJAJEDAgUIYXNzZXRJZHMFAWkBDnJldHVyblBheW1lbnRzAgZjYWxsZXIIcGF5bWVudHMKAQ1wYXJzZVBheW1lbnRzAgNhY2MHcGF5bWVudAkAzQgCBQNhY2MJAQ5TY3JpcHRUcmFuc2ZlcgMFBmNhbGxlcggFB3BheW1lbnQGYW1vdW50CAUHcGF5bWVudAdhc3NldElkCgACJGwFCHBheW1lbnRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQ1wYXJzZVBheW1lbnRzAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKARJjaGVja0RBcHBUaHJlc2hvbGQBC25ld0JhbGFuY2VzBBFkQXBwVGhyZXNob2xkQ29lZgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFBHRoaXMFEmtEQXBwVGhyZXNob2xkQ29lZgIYTm8gZEFwcFRocmVzaG9sZENvZWYga2V5BA50aHJlc2hvbGRTY2FsZQCQTgQKbWF4QmFsYW5jZQkAlgMBBQtuZXdCYWxhbmNlcwQKbWluQmFsYW5jZQkAlwMBBQtuZXdCYWxhbmNlcwQFcmF0aW8JAGsDBQptYXhCYWxhbmNlBQ50aHJlc2hvbGRTY2FsZQUKbWluQmFsYW5jZQMJAGYCBQVyYXRpbwkAaAIFEWRBcHBUaHJlc2hvbGRDb2VmBQ50aHJlc2hvbGRTY2FsZQkAAgECOE5ldyBiYWxhbmNlIGluIGFzc2V0cyBvZiB0aGUgREFwcCBpcyBsZXNzIHRoYW4gdGhyZXNob2xkBwEKY2hlY2tDb2lucwEIYXNzZXRJZHMEBWNvaW5zCQC1CQIFCGFzc2V0SWRzAgEsAwkAZgIJAJADAQUFY29pbnMACgkAAgECIFRvIG1hbnkgY29pbnMsIG1heCBjb2lucyBzaXplIDEwCgEJY2hlY2tDb2luAgVlcnJvcgdhc3NldElkBAVhc3NldAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDZBAEFB2Fzc2V0SWQJAKwCAgISZnJvbUJhc2U1OFN0cmluZzogBQdhc3NldElkBAhkZWNpbWFscwgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQVhc3NldAkArAICAgthc3NldEluZm86IAUHYXNzZXRJZAhkZWNpbWFscwMJAQIhPQIFCGRlY2ltYWxzBQhERUNJTUFMUwkAAgECDndyb25nIGRlY2ltYWxzBwoAAiRsBQVjb2lucwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAHCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQljaGVja0NvaW4CBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoUA21zZwEBRAICeHADYW1wBAFECQEOZ2V0X0RfaW50ZXJuYWwCBQJ4cAUDYW1wCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQICAUQFAUQFA25pbAUBRANtc2cBBGluaXQDCGFzc2V0SWRzAl9BEl9kQXBwVGhyZXNob2xkQ29lZgMJAQEhAQkAnggBBQR0aGlzCQACAQITQWxyZWFkeSBpbml0aWFsaXplZAMJAGcCAAAFAl9BCQACAQIUQW1wIG11c3QgYmUgbXVzdCA+IDADCQBnAgAABRJfZEFwcFRocmVzaG9sZENvZWYJAAIBAh9kQXBwIFRocmVzaG9sZCBDb2VmIG11c3QgYmUgPiAwBAlzaGFyZU5hbWUCC3NfTXVsdGlfVVNEBBBzaGFyZURlc2NyaXB0aW9uCQCsAgICQlNoYXJlVG9rZW4gb2YgU3dvcEZpIHByb3RvY29sIGZvciBNdWx0aVN0YWJsZSBVU0QgcG9vbCBhdCBhZGRyZXNzIAkApQgBBQR0aGlzBAppc3N1ZVRva2VuCQDCCAUFCXNoYXJlTmFtZQUQc2hhcmVEZXNjcmlwdGlvbgAAAAYGBAd0b2tlbklkCQC4CAEFCmlzc3VlVG9rZW4DCQEKY2hlY2tDb2lucwEFCGFzc2V0SWRzCQEFdGhyb3cACQDMCAIJAQtTdHJpbmdFbnRyeQIFCGtWZXJzaW9uBQd2ZXJzaW9uCQDMCAIJAQtTdHJpbmdFbnRyeQIFB2tBc3NldHMFCGFzc2V0SWRzCQDMCAIJAQxJbnRlZ2VyRW50cnkCAglpbml0aWFsX0EFAl9BCQDMCAIJAQxJbnRlZ2VyRW50cnkCAghmdXR1cmVfQQUCX0EJAMwIAgkBDEludGVnZXJFbnRyeQIFBGtGZWUJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBm9yYWNsZQINYmFzZV9mZWVfZmxhdAkAzAgCCQELU3RyaW5nRW50cnkCBQ1rU2hhcmVBc3NldElkCQDYBAEFB3Rva2VuSWQJAMwIAgkBDEludGVnZXJFbnRyeQIFEWtTaGFyZUFzc2V0U3VwcGx5AAAJAMwIAgkBDEludGVnZXJFbnRyeQIFEmtEQXBwVGhyZXNob2xkQ29lZgUSX2RBcHBUaHJlc2hvbGRDb2VmCQDMCAIJAQxCb29sZWFuRW50cnkCBQdrQWN0aXZlBgkAzAgCBQppc3N1ZVRva2VuBQNuaWwDbXNnAQxhZGRMaXF1aWRpdHkDDW1pbk1pbnRBbW91bnQMc3Rha2VGYXJtaW5nCGxvY2tUeXBlCQELdmFsdWVPckVsc2UCCQEIaXNBY3RpdmUABANhbXAJAQJfQQAEAnhwCQEDX3hwAAQCRDADCQAAAgULc2hhcmVTdXBwbHkAAAAACQEHZ2V0RE1lbQIFAnhwBQNhbXAEDSR0MDE1MzQ5MTU2MDQDAwkAZgIFCGxvY2tUeXBlAAAJAAACCAkAkQMCCAUDbXNnCHBheW1lbnRzCQBlAgkAkAMBCAUDbXNnCHBheW1lbnRzAAEHYXNzZXRJZAUEdW5pdAcJAJQKAgkA0QgCCAUDbXNnCHBheW1lbnRzCQBlAgkAkAMBCAUDbXNnCHBheW1lbnRzAAEJAMwIAgkAkQMCCAUDbXNnCHBheW1lbnRzCQBlAgkAkAMBCAUDbXNnCHBheW1lbnRzAAEFA25pbAkAlAoCCAUDbXNnCHBheW1lbnRzBQNuaWwECHBheW1lbnRzCAUNJHQwMTUzNDkxNTYwNAJfMQQHbG9ja0ZlZQgFDSR0MDE1MzQ5MTU2MDQCXzIEDHBheW1lbnRzU2l6ZQkAkAMBBQhwYXltZW50cwoBDXZhbGlkUGF5bWVudHMBAW4DCQBmAgUMcGF5bWVudHNTaXplBQZuQ29pbnMJAAIBCQCsAgICEHBheW1lbnRzIHNpemUgPiAJAKQDAQUGbkNvaW5zAwkAZgIAAQUMcGF5bWVudHNTaXplCQACAQIRcGF5bWVudHMgc2l6ZSA8IDEDAwkAAAIFC3NoYXJlU3VwcGx5AAAJAQIhPQIFBm5Db2lucwUMcGF5bWVudHNTaXplBwkAAgECImluaXRpYWwgZGVwb3NpdCByZXF1aXJlcyBhbGwgY29pbnMKAQxwYXltYW50VmFsaWQCA2FjYwdwYXltZW50AwkBD2NvbnRhaW5zRWxlbWVudAIFCGFzc2V0SWRzCQENZ2V0U3RyQXNzZXRJZAEIBQdwYXltZW50B2Fzc2V0SWQGCQACAQIYSW52YWxpZCBhc3NldCBpbiBwYXltZW50CgACJGwFCHBheW1lbnRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAcKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBDHBheW1hbnRWYWxpZAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgMJAQEhAQkBDXZhbGlkUGF5bWVudHMBBQxwYXltZW50c1NpemUJAQV0aHJvdwAECnN1c3BpY2lvdXMJAQ9jaGVja1N1c3BpY2lvdXMAAwgFCnN1c3BpY2lvdXMCXzEJAM4IAgkBEXN1c3BlbmRTdXNwaWNpb3VzAQgFCnN1c3BpY2lvdXMCXzIJAQ5yZXR1cm5QYXltZW50cwIIBQNtc2cGY2FsbGVyBQhwYXltZW50cwoBDXBhcnNlUGF5bWVudHMCA2FjYwdhc3NldElkBA0kdDAxNjQ3NDE2NTAwBQNhY2MEC25ld0JhbGFuY2VzCAUNJHQwMTY0NzQxNjUwMAJfMQQBaQgFDSR0MDE2NDc0MTY1MDACXzIKAQxwYXJzZVBheW1lbnQCCm5ld0JhbGFuY2UHcGF5bWVudAMJAAACCQENZ2V0U3RyQXNzZXRJZAEIBQdwYXltZW50B2Fzc2V0SWQFB2Fzc2V0SWQJAGQCBQpuZXdCYWxhbmNlCAUHcGF5bWVudAZhbW91bnQFCm5ld0JhbGFuY2UECW5ld0JhbGFjZQoAAiRsBQhwYXltZW50cwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJEDAgUCeHAFAWkKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBDHBhcnNlUGF5bWVudAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgkAlAoCCQDNCAIFC25ld0JhbGFuY2VzBQluZXdCYWxhY2UJAGQCBQFpAAEEDSR0MDE2ODUwMTY5MTcKAAIkbAUIYXNzZXRJZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgIFA25pbAAACgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQ1wYXJzZVBheW1lbnRzAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKBAtuZXdCYWxhbmNlcwgFDSR0MDE2ODUwMTY5MTcCXzEEAWsIBQ0kdDAxNjg1MDE2OTE3Al8yAwkBEmNoZWNrREFwcFRocmVzaG9sZAEFC25ld0JhbGFuY2VzCQEFdGhyb3cABAJEMQkBB2dldERNZW0CBQtuZXdCYWxhbmNlcwUDYW1wAwkBBmFzc2VydAEJAGYCBQJEMQUCRDAJAAIBAgdEMSA+IEQwBAtmZWVEaXNjb3VudAkBFGNhbGN1bGF0ZUZlZURpc2NvdW50AQgFA21zZwZjYWxsZXIKARFjYWxjU2NyaXB0QWN0aW9ucwIDYWNjCm5ld0JhbGFuY2UEDSR0MDE3MjM3MTcyNzgFA2FjYwQLaW52QmFsYW5jZXMIBQ0kdDAxNzIzNzE3Mjc4Al8xBA1zY3JpcHRBY3Rpb25zCAUNJHQwMTcyMzcxNzI3OAJfMgQBaQgFDSR0MDE3MjM3MTcyNzgCXzMDCQBmAgULc2hhcmVTdXBwbHkAAAQEX2ZlZQkAaQIJAGgCCQBuBAUDZmVlBQtmZWVEaXNjb3VudAUJZmVlU2NhbGU2BQdDRUlMSU5HBQZuQ29pbnMJAGgCAAQJAGUCBQZuQ29pbnMAAQQEZmVlcwQMaWRlYWxCYWxhbmNlCQBrAwUCRDEJAJEDAgUCeHAFAWkFAkQwBApkaWZmZXJlbmNlAwkAZgIFDGlkZWFsQmFsYW5jZQUKbmV3QmFsYW5jZQkAZQIFDGlkZWFsQmFsYW5jZQUKbmV3QmFsYW5jZQkAZQIFCm5ld0JhbGFuY2UFDGlkZWFsQmFsYW5jZQkAawMFBF9mZWUFCmRpZmZlcmVuY2UFCWZlZVNjYWxlNgQOZ292ZXJuYW5jZUZlZXMJAGsDBQRmZWVzBQ1mZWVHb3Zlcm5hbmNlBQlmZWVTY2FsZTYEDGZpbmFsQmFsYW5jZQkAZQIFCm5ld0JhbGFuY2UFBGZlZXMEEGludmFyaWFudEJhbGFuY2UJAGUCBQpuZXdCYWxhbmNlBQRmZWVzBANwbXQJAGUCBQpuZXdCYWxhbmNlCQCRAwIFAnhwBQFpBAZscEZlZXMJAGUCBQRmZWVzBQ5nb3Zlcm5hbmNlRmVlcwQDaW52AwkAZgIFA3BtdAAACQEFc3Rha2UCCQBlAgUDcG10BQRmZWVzCQCRAwIFCGFzc2V0SWRzBQFpCQEHdW5zdGFrZQIFBGZlZXMJAJEDAgUIYXNzZXRJZHMFAWkDCQAAAgUDaW52BQNpbnYEB2FpcmRyb3ADCQBmAgUGbHBGZWVzAAAJAPwHBAUQbHBGYXJtaW5nQWRkcmVzcwIHYWlyRHJvcAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCCQDZBAEJAJEDAgUIYXNzZXRJZHMFAWkFBmxwRmVlcwUDbmlsAAADCQAAAgUHYWlyZHJvcAUHYWlyZHJvcAkAlQoDCQDNCAIFC2ludkJhbGFuY2VzBRBpbnZhcmlhbnRCYWxhbmNlCQDOCAIFDXNjcmlwdEFjdGlvbnMJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUPbW9uZXlCb3hBZGRyZXNzBQ5nb3Zlcm5hbmNlRmVlcwkA2QQBCQCRAwIFCGFzc2V0SWRzBQFpCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAJEDAgUIYXNzZXRJZHMFAWkFDWtBc3NldEJhbGFuY2UFDGZpbmFsQmFsYW5jZQUDbmlsCQBkAgUBaQABCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBANpbnYJAQVzdGFrZQIFCm5ld0JhbGFuY2UJAJEDAgUIYXNzZXRJZHMFAWkDCQAAAgUDaW52BQNpbnYJAJUKAwkAzQgCBQtpbnZCYWxhbmNlcwUKbmV3QmFsYW5jZQkAzQgCBQ1zY3JpcHRBY3Rpb25zCQEMSW50ZWdlckVudHJ5AgkArAICCQCRAwIFCGFzc2V0SWRzBQFpBQ1rQXNzZXRCYWxhbmNlBQpuZXdCYWxhbmNlCQBkAgUBaQABCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBA0kdDAxODk4MzE5MDcxCgACJGwFC25ld0JhbGFuY2VzCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlQoDBQNuaWwFA25pbAAACgEFJGYxXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARFjYWxjU2NyaXB0QWN0aW9ucwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMV8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjFfMgIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgQLaW52QmFsYW5jZXMIBQ0kdDAxODk4MzE5MDcxAl8xBA1zY3JpcHRBY3Rpb25zCAUNJHQwMTg5ODMxOTA3MQJfMgQCRDIJAQdnZXRETWVtAgULaW52QmFsYW5jZXMFA2FtcAQLbWludF9hbW91bnQDCQAAAgULc2hhcmVTdXBwbHkAAAUCRDEJAGsDBQtzaGFyZVN1cHBseQkAZQIFAkQyBQJEMAUCRDADCQEGYXNzZXJ0AQkAZwIFC21pbnRfYW1vdW50BQ1taW5NaW50QW1vdW50CQACAQIUU2xpcHBhZ2Ugc2NyZXdlZCB5b3UDBQxzdGFrZUZhcm1pbmcEAnJlCQD8BwQFBHRoaXMCDHJlaXNzdWVTaGFyZQkAzAgCBQttaW50X2Ftb3VudAUDbmlsBQNuaWwDCQAAAgUCcmUFAnJlBAFzCQD8BwQFDmZhcm1pbmdBZGRyZXNzAg9sb2NrU2hhcmVUb2tlbnMJAMwIAgkApQgBBQR0aGlzCQDMCAIFCGxvY2tUeXBlBQNuaWwJAM4IAgkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUMc2hhcmVBc3NldElkBQttaW50X2Ftb3VudAUDbmlsBQdsb2NrRmVlAwkAAAIFAXMFAXMJAM0IAgUNc2NyaXB0QWN0aW9ucwkBDEludGVnZXJFbnRyeQIFEWtTaGFyZUFzc2V0U3VwcGx5CQBkAgULc2hhcmVTdXBwbHkFC21pbnRfYW1vdW50CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQDOCAIFDXNjcmlwdEFjdGlvbnMJAMwIAgkBB1JlaXNzdWUDBQxzaGFyZUFzc2V0SWQFC21pbnRfYW1vdW50BgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUDbXNnBmNhbGxlcgULbWludF9hbW91bnQFDHNoYXJlQXNzZXRJZAkAzAgCCQEMSW50ZWdlckVudHJ5AgURa1NoYXJlQXNzZXRTdXBwbHkJAGQCBQtzaGFyZVN1cHBseQULbWludF9hbW91bnQFA25pbANtc2cBDmNhbGNNaW50QW1vdW50AgtuZXdCYWxhbmNlcwR1c2VyBANhbXAJAQJfQQAEAnhwCQEDX3hwAAQCRDEJAQdnZXRETWVtAgULbmV3QmFsYW5jZXMFA2FtcAMJAAACBQtzaGFyZVN1cHBseQAACQCUCgIFA25pbAUCRDEEAkQwCQEHZ2V0RE1lbQIFAnhwBQNhbXAEC2ZlZURpc2NvdW50CQEUY2FsY3VsYXRlRmVlRGlzY291bnQBBQR1c2VyCgEPY2FsY0ludkJhbGFuY2VzAgNhY2MKbmV3QmFsYW5jZQQNJHQwMjAzMjEyMDM0NwUDYWNjBAtpbnZCYWxhbmNlcwgFDSR0MDIwMzIxMjAzNDcCXzEEAWkIBQ0kdDAyMDMyMTIwMzQ3Al8yBARfZmVlCQBpAgkAaAIJAG4EBQNmZWUFC2ZlZURpc2NvdW50BQlmZWVTY2FsZTYFB0NFSUxJTkcFBm5Db2lucwkAaAIABAkAZQIFBm5Db2lucwABBARmZWVzBAxpZGVhbEJhbGFuY2UJAGsDBQJEMQkAkQMCBQJ4cAUBaQUCRDAECmRpZmZlcmVuY2UDCQBmAgUMaWRlYWxCYWxhbmNlBQpuZXdCYWxhbmNlCQBlAgUMaWRlYWxCYWxhbmNlBQpuZXdCYWxhbmNlCQBlAgUKbmV3QmFsYW5jZQUMaWRlYWxCYWxhbmNlCQBrAwUEX2ZlZQUKZGlmZmVyZW5jZQUJZmVlU2NhbGU2BBBpbnZhcmlhbnRCYWxhbmNlCQBlAgUKbmV3QmFsYW5jZQUEZmVlcwkAlAoCCQDNCAIFC2ludkJhbGFuY2VzBRBpbnZhcmlhbnRCYWxhbmNlCQBkAgUBaQABBA0kdDAyMDk0OTIxMDE5CgACJGwFC25ld0JhbGFuY2VzCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlAoCBQNuaWwAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEPY2FsY0ludkJhbGFuY2VzAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKBAtpbnZCYWxhbmNlcwgFDSR0MDIwOTQ5MjEwMTkCXzEEAWsIBQ0kdDAyMDk0OTIxMDE5Al8yBAJEMgkBB2dldERNZW0CBQtpbnZCYWxhbmNlcwUDYW1wBAptaW50QW1vdW50CQBrAwULc2hhcmVTdXBwbHkJAGUCBQJEMgUCRDAFAkQwCQCUCgIFA25pbAUKbWludEFtb3VudANtc2cBDHJlaXNzdWVTaGFyZQEGYW1vdW50CQELdmFsdWVPckVsc2UCCQEKaXNTZWxmQ2FsbAEFA21zZwkAzAgCCQEHUmVpc3N1ZQMFDHNoYXJlQXNzZXRJZAUGYW1vdW50BgUDbmlsA21zZwEFZ2V0RHkECWFzc2V0RnJvbQdhc3NldFRvAmR4C3VzZXJBZGRyZXNzBAJ4cAkBA194cAAECWZyb21JbmRleAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDPCAIFCGFzc2V0SWRzBQlhc3NldEZyb20CEHVua25vd24gdG9rZW4gaW4EB3RvSW5kZXgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAzwgCBQhhc3NldElkcwUHYXNzZXRUbwIRdW5rbm93biB0b2tlbiBvdXQEAXgJAGQCCQCRAwIFAnhwBQlmcm9tSW5kZXgFAmR4BAF5CQEEZ2V0WQQFCWZyb21JbmRleAUHdG9JbmRleAUBeAUCeHAEAmR5CQBlAgkAZQIJAJEDAgUCeHAFB3RvSW5kZXgFAXkAAQQLZmVlRGlzY291bnQJARRjYWxjdWxhdGVGZWVEaXNjb3VudAEJAQdBZGRyZXNzAQkA2QQBBQt1c2VyQWRkcmVzcwQEX2ZlZQkAawMJAG4EBQNmZWUFC2ZlZURpc2NvdW50BQlmZWVTY2FsZTYFB0NFSUxJTkcFAmR5BQlmZWVTY2FsZTYJAJQKAgUDbmlsCQCUCgIJAGUCBQJkeQUEX2ZlZQUEX2ZlZQNtc2cBCGV4Y2hhbmdlAgh0b2tlbk91dAZtaW5fZHkJAQt2YWx1ZU9yRWxzZQIJAQhpc0FjdGl2ZQADCQECIT0CCQCQAwEIBQNtc2cIcGF5bWVudHMAAQkAAgECE3NpemUocGF5bWVudHMpICE9IDEECnN1c3BpY2lvdXMJAQ9jaGVja1N1c3BpY2lvdXMAAwgFCnN1c3BpY2lvdXMCXzEJAM4IAgkBEXN1c3BlbmRTdXNwaWNpb3VzAQgFCnN1c3BpY2lvdXMCXzIJAQ5yZXR1cm5QYXltZW50cwIIBQNtc2cGY2FsbGVyCAUDbXNnCHBheW1lbnRzBAdwYXltZW50CQCRAwIIBQNtc2cIcGF5bWVudHMAAAQHdG9rZW5JbgkBDWdldFN0ckFzc2V0SWQBCAUHcGF5bWVudAdhc3NldElkBAt0b2tlbk91dEI1OAkA2QQBBQh0b2tlbk91dAQCZHgIBQdwYXltZW50BmFtb3VudAQJZnJvbUluZGV4CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAM8IAgUIYXNzZXRJZHMFB3Rva2VuSW4CEHVua25vd24gdG9rZW4gaW4EB3RvSW5kZXgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAzwgCBQhhc3NldElkcwUIdG9rZW5PdXQCEXVua25vd24gdG9rZW4gb3V0BAJ4cAkBA194cAAEAXgJAGQCCQCRAwIFAnhwBQlmcm9tSW5kZXgFAmR4BAF5CQEEZ2V0WQQFCWZyb21JbmRleAUHdG9JbmRleAUBeAUCeHAEA19keQkAZQIJAGUCCQCRAwIFAnhwBQd0b0luZGV4BQF5AAEEC2ZlZURpc2NvdW50CQEUY2FsY3VsYXRlRmVlRGlzY291bnQBCAUDbXNnDG9yaWdpbkNhbGxlcgQEX2ZlZQkAawMFA19keQkAbgQFA2ZlZQULZmVlRGlzY291bnQFCWZlZVNjYWxlNgUHQ0VJTElORwUJZmVlU2NhbGU2BAJkeQkAZQIFA19keQUEX2ZlZQQOZ292ZXJuYW5jZUZlZXMJAGsDBQRfZmVlBQ1mZWVHb3Zlcm5hbmNlBQlmZWVTY2FsZTYDCQEGYXNzZXJ0AQkAZwIFAmR5BQZtaW5fZHkJAAIBAi5FeGNoYW5nZSByZXN1bHRlZCBpbiBmZXdlciBjb2lucyB0aGFuIGV4cGVjdGVkCgEPbWFrZU5ld0JhbGFuY2VzAgNhY2MMdG9rZW5CYWxhbmNlBA0kdDAyMzA2MDIzMDg2BQNhY2MEC25ld0JhbGFuY2VzCAUNJHQwMjMwNjAyMzA4NgJfMQQBaQgFDSR0MDIzMDYwMjMwODYCXzIDCQAAAgUBaQUJZnJvbUluZGV4CQCUCgIJAM0IAgULbmV3QmFsYW5jZXMJAGQCBQx0b2tlbkJhbGFuY2UFAmR4CQBkAgUBaQABAwkAAAIFAWkFB3RvSW5kZXgJAJQKAgkAzQgCBQtuZXdCYWxhbmNlcwkAZQIFDHRva2VuQmFsYW5jZQUDX2R5CQBkAgUBaQABCQCUCgIJAM0IAgULbmV3QmFsYW5jZXMFDHRva2VuQmFsYW5jZQkAZAIFAWkAAQQNJHQwMjMzMzcyMzM5OAoAAiRsBQJ4cAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgUDbmlsAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBD21ha2VOZXdCYWxhbmNlcwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgQLbmV3QmFsYW5jZXMIBQ0kdDAyMzMzNzIzMzk4Al8xBAFpCAUNJHQwMjMzMzcyMzM5OAJfMgMJARJjaGVja0RBcHBUaHJlc2hvbGQBBQtuZXdCYWxhbmNlcwkBBXRocm93AAQBcwkBBXN0YWtlAggFB3BheW1lbnQGYW1vdW50CQENZ2V0U3RyQXNzZXRJZAEIBQdwYXltZW50B2Fzc2V0SWQDCQAAAgUBcwUBcwQCdXMJAQd1bnN0YWtlAgUDX2R5BQh0b2tlbk91dAMJAAACBQJ1cwUCdXMEBmxwRmVlcwkAZQIFBF9mZWUFDmdvdmVybmFuY2VGZWVzBAdhaXJkcm9wAwkAZgIFBmxwRmVlcwAACQD8BwQFEGxwRmFybWluZ0FkZHJlc3MCB2FpckRyb3AFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgULdG9rZW5PdXRCNTgFBmxwRmVlcwUDbmlsAAADCQAAAgUHYWlyZHJvcAUHYWlyZHJvcAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFB3Rva2VuSW4FDWtBc3NldEJhbGFuY2UFAXgJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUIdG9rZW5PdXQFDWtBc3NldEJhbGFuY2UJAGUCCQCRAwIFAnhwBQd0b0luZGV4BQNfZHkJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFA21zZwZjYWxsZXIFAmR5BQt0b2tlbk91dEI1OAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQ9tb25leUJveEFkZHJlc3MFDmdvdmVybmFuY2VGZWVzBQt0b2tlbk91dEI1OAUDbmlsCQDMCAIFAmR5CQDMCAIFC3Rva2VuT3V0QjU4BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4DbXNnAQh3aXRoZHJhdwEKbWluQW1vdW50cwkBC3ZhbHVlT3JFbHNlAgkBCGlzQWN0aXZlAAMJAQIhPQIJAJADAQgFA21zZwhwYXltZW50cwABCQACAQITc2l6ZShwYXltZW50cykgIT0gMQQJcG10QW1vdW50CAkAkQMCCAUDbXNnCHBheW1lbnRzAAAGYW1vdW50BApwbXRBc3NldElkCAkAkQMCCAUDbXNnCHBheW1lbnRzAAAHYXNzZXRJZAMJAQIhPQIFDHNoYXJlQXNzZXRJZAUKcG10QXNzZXRJZAkAAgECFXVua25vd24gcGF5bWVudCB0b2tlbgQKc3VzcGljaW91cwkBD2NoZWNrU3VzcGljaW91cwADCAUKc3VzcGljaW91cwJfMQkAzggCCQERc3VzcGVuZFN1c3BpY2lvdXMBCAUKc3VzcGljaW91cwJfMgkBDnJldHVyblBheW1lbnRzAggFA21zZwxvcmlnaW5DYWxsZXIIBQNtc2cIcGF5bWVudHMKARFjYWxjU2NyaXB0QWN0aW9ucwIDYWNjB2JhbGFuY2UEDSR0MDI0Njg5MjQ3MTcFA2FjYwQNc2NyaXB0QWN0aW9ucwgFDSR0MDI0Njg5MjQ3MTcCXzEEAWkIBQ0kdDAyNDY4OTI0NzE3Al8yBAd3QW1vdW50CQBrAwUHYmFsYW5jZQUJcG10QW1vdW50BQtzaGFyZVN1cHBseQMJAQZhc3NlcnQBCQBnAgUHd0Ftb3VudAkAkQMCBQptaW5BbW91bnRzBQFpCQACAQIwV2l0aGRyYXdhbCByZXN1bHRlZCBpbiBmZXdlciBjb2lucyB0aGFuIGV4cGVjdGVkBAJ1cwkBB3Vuc3Rha2UCBQd3QW1vdW50CQCRAwIFCGFzc2V0SWRzBQFpAwkAAAIFAnVzBQJ1cwkAlAoCCQDOCAIFDXNjcmlwdEFjdGlvbnMJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkAkQMCBQhhc3NldElkcwUBaQUNa0Fzc2V0QmFsYW5jZQkAZQIFB2JhbGFuY2UFB3dBbW91bnQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFA21zZwxvcmlnaW5DYWxsZXIFB3dBbW91bnQJANkEAQkAkQMCBQhhc3NldElkcwUBaQUDbmlsCQBkAgUBaQABCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBA0kdDAyNTIwNzI1Mjc1CgACJGwJAQNfeHAACgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlAoCBQNuaWwAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQERY2FsY1NjcmlwdEFjdGlvbnMCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoEDXNjcmlwdEFjdGlvbnMIBQ0kdDAyNTIwNzI1Mjc1Al8xBAFpCAUNJHQwMjUyMDcyNTI3NQJfMgkAzggCBQ1zY3JpcHRBY3Rpb25zCQDMCAIJAQRCdXJuAgUMc2hhcmVBc3NldElkBQlwbXRBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIFEWtTaGFyZUFzc2V0U3VwcGx5CQBlAgULc2hhcmVTdXBwbHkFCXBtdEFtb3VudAUDbmlsA21zZwESd2l0aGRyYXdXaXRoVW5sb2NrAgptaW5BbW91bnRzDHVubG9ja0Ftb3VudAkBC3ZhbHVlT3JFbHNlAgkBCGlzQWN0aXZlAAMJAGcCAAAFDHVubG9ja0Ftb3VudAkAAgECHlVubG9jayBhbW91bnQgbXVzdCBiZSBwb3NpdGl2ZQQKc3VzcGljaW91cwkBD2NoZWNrU3VzcGljaW91cwADCAUKc3VzcGljaW91cwJfMQkAzggCCQERc3VzcGVuZFN1c3BpY2lvdXMBCAUKc3VzcGljaW91cwJfMgkBDnJldHVyblBheW1lbnRzAggFA21zZwZjYWxsZXIIBQNtc2cIcGF5bWVudHMECXBtdEFtb3VudAMJAGYCCQCQAwEIBQNtc2cIcGF5bWVudHMAAAMJAQIhPQIJAJADAQgFA21zZwhwYXltZW50cwABCQACAQITc2l6ZShwYXltZW50cykgIT0gMQQKcG10QXNzZXRJZAgJAJEDAggFA21zZwhwYXltZW50cwAAB2Fzc2V0SWQDCQECIT0CBQxzaGFyZUFzc2V0SWQFCnBtdEFzc2V0SWQJAAIBAhV1bmtub3duIHBheW1lbnQgdG9rZW4ICQCRAwIIBQNtc2cIcGF5bWVudHMAAAZhbW91bnQAAAQGdW5sb2NrCQD8BwQFDmZhcm1pbmdBZGRyZXNzAhN3aXRoZHJhd1NoYXJlVG9rZW5zCQDMCAIJAKUIAQUEdGhpcwkAzAgCBQx1bmxvY2tBbW91bnQFA25pbAUDbmlsAwkAAAIFBnVubG9jawUGdW5sb2NrBA53aXRoZHJhd0Ftb3VudAkAZAIFCXBtdEFtb3VudAUMdW5sb2NrQW1vdW50BANpbnYJAPwHBAUEdGhpcwIId2l0aGRyYXcJAMwIAgUKbWluQW1vdW50cwUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQxzaGFyZUFzc2V0SWQFDndpdGhkcmF3QW1vdW50BQNuaWwDCQAAAgUDaW52BQNpbnYFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgNtc2cBE2NhbGNXaXRoZHJhd09uZUNvaW4DC3Rva2VuQW1vdW50CHRva2VuT3V0BHVzZXIDCQBnAgAABQt0b2tlbkFtb3VudAkAAgECF0Ftb3VudCBtdXN0IGJlIHBvc2l0aXZlBAFpCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAM8IAgUIYXNzZXRJZHMFCHRva2VuT3V0AhF1bmtub3duIHRva2VuIG91dAkAlAoCBQNuaWwICQEUX2NhbGNXaXRoZHJhd09uZUNvaW4ECQEDX3hwAAULdG9rZW5BbW91bnQFAWkJAQdBZGRyZXNzAQkA2QQBBQR1c2VyAl8xA21zZwEPd2l0aGRyYXdPbmVDb2luAgh0b2tlbk91dAltaW5BbW91bnQJAQt2YWx1ZU9yRWxzZQIJAQhpc0FjdGl2ZQADCQECIT0CCQCQAwEIBQNtc2cIcGF5bWVudHMAAQkAAgECE3NpemUocGF5bWVudHMpICE9IDEECnN1c3BpY2lvdXMJAQ9jaGVja1N1c3BpY2lvdXMAAwgFCnN1c3BpY2lvdXMCXzEJAM4IAgkBEXN1c3BlbmRTdXNwaWNpb3VzAQgFCnN1c3BpY2lvdXMCXzIJAQ5yZXR1cm5QYXltZW50cwIIBQNtc2cMb3JpZ2luQ2FsbGVyCAUDbXNnCHBheW1lbnRzBAlwbXRBbW91bnQICQCRAwIIBQNtc2cIcGF5bWVudHMAAAZhbW91bnQECnBtdEFzc2V0SWQICQCRAwIIBQNtc2cIcGF5bWVudHMAAAdhc3NldElkAwkBAiE9AgUKcG10QXNzZXRJZAUMc2hhcmVBc3NldElkCQACAQINdW5rbm93biB0b2tlbgQIb3V0SW5kZXgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAzwgCBQhhc3NldElkcwUIdG9rZW5PdXQCEXVua25vd24gdG9rZW4gb3V0BAt0b2tlbk91dEI1OAkA2QQBBQh0b2tlbk91dAQCeHAJAQNfeHAABA0kdDAyNzMwNzI3Mzg5CQEUX2NhbGNXaXRoZHJhd09uZUNvaW4EBQJ4cAUJcG10QW1vdW50BQhvdXRJbmRleAgFA21zZwxvcmlnaW5DYWxsZXIEAmR5CAUNJHQwMjczMDcyNzM4OQJfMQQGZHlfZmVlCAUNJHQwMjczMDcyNzM4OQJfMgMJAQZhc3NlcnQBCQBnAgUCZHkFCW1pbkFtb3VudAkAAgECGE5vdCBlbm91Z2ggY29pbnMgcmVtb3ZlZAQOZ292ZXJuYW5jZUZlZXMJAGsDBQZkeV9mZWUFDWZlZUdvdmVybmFuY2UFCWZlZVNjYWxlNgQKZHlfYW5kX2ZlZQkAZAIFAmR5BQZkeV9mZWUKAQ9tYWtlTmV3QmFsYW5jZXMCA2FjYwx0b2tlbkJhbGFuY2UEDSR0MDI3NjQ3Mjc2NzMFA2FjYwQLbmV3QmFsYW5jZXMIBQ0kdDAyNzY0NzI3NjczAl8xBAFpCAUNJHQwMjc2NDcyNzY3MwJfMgMJAAACBQFpBQhvdXRJbmRleAkAlAoCCQDNCAIFC25ld0JhbGFuY2VzCQBlAgUMdG9rZW5CYWxhbmNlBQpkeV9hbmRfZmVlCQBkAgUBaQABCQCUCgIJAM0IAgULbmV3QmFsYW5jZXMFDHRva2VuQmFsYW5jZQkAZAIFAWkAAQQNJHQwMjc4NDAyNzkwMQoAAiRsBQJ4cAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgUDbmlsAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBD21ha2VOZXdCYWxhbmNlcwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgQLbmV3QmFsYW5jZXMIBQ0kdDAyNzg0MDI3OTAxAl8xBAF2CAUNJHQwMjc4NDAyNzkwMQJfMgMJARJjaGVja0RBcHBUaHJlc2hvbGQBBQtuZXdCYWxhbmNlcwkBBXRocm93AAQCdXMJAQd1bnN0YWtlAgUKZHlfYW5kX2ZlZQUIdG9rZW5PdXQDCQAAAgUCdXMFAnVzBAZscEZlZXMJAGUCBQZkeV9mZWUFDmdvdmVybmFuY2VGZWVzBAdhaXJkcm9wAwkAZgIFBmxwRmVlcwAACQD8BwQFEGxwRmFybWluZ0FkZHJlc3MCB2FpckRyb3AFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgULdG9rZW5PdXRCNTgFBmxwRmVlcwUDbmlsAAADCQAAAgUHYWlyZHJvcAUHYWlyZHJvcAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUDbXNnDG9yaWdpbkNhbGxlcgUCZHkFC3Rva2VuT3V0QjU4CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAJEDAgUIYXNzZXRJZHMFCG91dEluZGV4BQ1rQXNzZXRCYWxhbmNlCQBlAgkAkQMCBQJ4cAUIb3V0SW5kZXgFCmR5X2FuZF9mZWUJAMwIAgkBBEJ1cm4CBQxzaGFyZUFzc2V0SWQFCXBtdEFtb3VudAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQ9tb25leUJveEFkZHJlc3MFDmdvdmVybmFuY2VGZWVzBQt0b2tlbk91dEI1OAkAzAgCCQEMSW50ZWdlckVudHJ5AgURa1NoYXJlQXNzZXRTdXBwbHkJAGUCBQtzaGFyZVN1cHBseQUJcG10QW1vdW50BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4DbXNnARl3aXRoZHJhd09uZUNvaW5XaXRoVW5sb2NrAwh0b2tlbk91dAltaW5BbW91bnQMdW5sb2NrQW1vdW50CQELdmFsdWVPckVsc2UCCQEIaXNBY3RpdmUAAwkAZwIAAAUMdW5sb2NrQW1vdW50CQACAQIeVW5sb2NrIGFtb3VudCBtdXN0IGJlIHBvc2l0aXZlBApzdXNwaWNpb3VzCQEPY2hlY2tTdXNwaWNpb3VzAAMIBQpzdXNwaWNpb3VzAl8xCQDOCAIJARFzdXNwZW5kU3VzcGljaW91cwEIBQpzdXNwaWNpb3VzAl8yCQEOcmV0dXJuUGF5bWVudHMCCAUDbXNnBmNhbGxlcggFA21zZwhwYXltZW50cwQJcG10QW1vdW50AwkAZgIJAJADAQgFA21zZwhwYXltZW50cwAAAwkBAiE9AgkAkAMBCAUDbXNnCHBheW1lbnRzAAEJAAIBAhNzaXplKHBheW1lbnRzKSAhPSAxBApwbXRBc3NldElkCAkAkQMCCAUDbXNnCHBheW1lbnRzAAAHYXNzZXRJZAMJAQIhPQIFDHNoYXJlQXNzZXRJZAUKcG10QXNzZXRJZAkAAgECFXVua25vd24gcGF5bWVudCB0b2tlbggJAJEDAggFA21zZwhwYXltZW50cwAABmFtb3VudAAABAZ1bmxvY2sJAPwHBAUOZmFybWluZ0FkZHJlc3MCE3dpdGhkcmF3U2hhcmVUb2tlbnMJAMwIAgkApQgBBQR0aGlzCQDMCAIFDHVubG9ja0Ftb3VudAUDbmlsBQNuaWwDCQAAAgUGdW5sb2NrBQZ1bmxvY2sEDndpdGhkcmF3QW1vdW50CQBkAgUJcG10QW1vdW50BQx1bmxvY2tBbW91bnQEA2ludgkA/AcEBQR0aGlzAg93aXRoZHJhd09uZUNvaW4JAMwIAgUIdG9rZW5PdXQJAMwIAgUJbWluQW1vdW50BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFDHNoYXJlQXNzZXRJZAUOd2l0aGRyYXdBbW91bnQFA25pbAMJAAACBQNpbnYFA2ludgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuA21zZwEBQQAJAJQKAgUDbmlsCQECX0EAA21zZwEPZ2V0VmlydHVhbFByaWNlAAQBRAkBBWdldF9EAgkBA194cAAJAQJfQQAJAJQKAgUDbmlsCQBrAwUBRAUJUFJFQ0lTSU9OBQtzaGFyZVN1cHBseQNtc2cBD2NhbGNUb2tlbkFtb3VudAIHYW1vdW50cwdkZXBvc2l0BANhbXAJAQJfQQAECGJhbGFuY2VzCQEDX3hwAAQCRDAJAQdnZXRETWVtAgUIYmFsYW5jZXMFA2FtcAoBD2NhbGNOZXdCYWxhbmNlcwIDYWNjB2JhbGFuY2UEDSR0MDI5OTE4Mjk5NDQFA2FjYwQLbmV3QmFsYW5jZXMIBQ0kdDAyOTkxODI5OTQ0Al8xBAFpCAUNJHQwMjk5MTgyOTk0NAJfMgQKbmV3QmFsYW5jZQkAZAIFB2JhbGFuY2UDBQdkZXBvc2l0CQCRAwIFB2Ftb3VudHMFAWkJAQEtAQkAkQMCBQdhbW91bnRzBQFpCQCUCgIJAM0IAgULbmV3QmFsYW5jZXMFCm5ld0JhbGFuY2UJAGQCBQFpAAEEC25ld0JhbGFuY2VzCAoAAiRsBQhiYWxhbmNlcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgUDbmlsAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBD2NhbGNOZXdCYWxhbmNlcwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgJfMQQCRDEJAQdnZXRETWVtAgULbmV3QmFsYW5jZXMFA2FtcAQEZGlmZgMFB2RlcG9zaXQJAGUCBQJEMQUCRDAJAGUCBQJEMAUCRDEJAJQKAgUDbmlsCQBrAwUEZGlmZgULc2hhcmVTdXBwbHkFAkQwA21zZwEFcmFtcEECCF9mdXR1cmVBC19mdXR1cmVUaW1lCQELdmFsdWVPckVsc2UCCQEIaXNBY3RpdmUACQELdmFsdWVPckVsc2UCCQELaXNBZG1pbkNhbGwBBQNtc2cDCQEGYXNzZXJ0AQkAZwIFDmJsb2NrVGltZXN0YW1wCQBkAgUOaW5pdGlhbF9BX3RpbWUFDU1JTl9SQU1QX1RJTUUJAAIBAgl0b28gb2Z0ZW4DCQEGYXNzZXJ0AQkAZwIFC19mdXR1cmVUaW1lCQBkAgUOYmxvY2tUaW1lc3RhbXAFDU1JTl9SQU1QX1RJTUUJAAIBAhFpbnN1ZmZpY2llbnQgdGltZQQKX2luaXRpYWxfQQkBAl9BAAMJAQZhc3NlcnQBAwkAZgIFCF9mdXR1cmVBAAAJAGYCBQVNQVhfQQUIX2Z1dHVyZUEHCQACAQIRb3V0IG9mIGJhc2UgcmFuZ2UDCQEGYXNzZXJ0AQMDCQBnAgUIX2Z1dHVyZUEFCl9pbml0aWFsX0EJAGcCCQBoAgUKX2luaXRpYWxfQQUMTUFYX0FfQ0hBTkdFBQhfZnV0dXJlQQcGAwkAZgIFCl9pbml0aWFsX0EFCF9mdXR1cmVBCQBnAgkAaAIFCF9mdXR1cmVBBQxNQVhfQV9DSEFOR0UFCl9pbml0aWFsX0EHCQACAQIMb3V0IG9mIHJhbmdlCQDMCAIJAQxJbnRlZ2VyRW50cnkCAglpbml0aWFsX0EFCl9pbml0aWFsX0EJAMwIAgkBDEludGVnZXJFbnRyeQICCGZ1dHVyZV9BBQhfZnV0dXJlQQkAzAgCCQEMSW50ZWdlckVudHJ5AgIOaW5pdGlhbF9BX3RpbWUFDmJsb2NrVGltZXN0YW1wCQDMCAIJAQxJbnRlZ2VyRW50cnkCAg1mdXR1cmVfQV90aW1lBQtfZnV0dXJlVGltZQUDbmlsA21zZwEJc3RvcFJhbXBBAAkBC3ZhbHVlT3JFbHNlAgkBCGlzQWN0aXZlAAkBC3ZhbHVlT3JFbHNlAgkBC2lzQWRtaW5DYWxsAQUDbXNnBAhjdXJyZW50QQkBAl9BAAkAzAgCCQEMSW50ZWdlckVudHJ5AgIJaW5pdGlhbF9BBQhjdXJyZW50QQkAzAgCCQEMSW50ZWdlckVudHJ5AgIIZnV0dXJlX0EFCGN1cnJlbnRBCQDMCAIJAQxJbnRlZ2VyRW50cnkCAg5pbml0aWFsX0FfdGltZQUOYmxvY2tUaW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQICDWZ1dHVyZV9BX3RpbWUFDmJsb2NrVGltZXN0YW1wBQNuaWwDbXNnAQhzaHV0ZG93bgAJAQt2YWx1ZU9yRWxzZQIJAQtpc0FkbWluQ2FsbAEFA21zZwMJAQEhAQUGYWN0aXZlCQACAQkArAICAiJEQXBwIGlzIGFscmVhZHkgc3VzcGVuZGVkLiBDYXVzZTogCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFBmtDYXVzZQIadGhlIGNhdXNlIHdhc24ndCBzcGVjaWZpZWQJAQdzdXNwZW5kAQIPUGF1c2VkIGJ5IGFkbWluA21zZwEIYWN0aXZhdGUACQELdmFsdWVPckVsc2UCCQELaXNBZG1pbkNhbGwBBQNtc2cDBQZhY3RpdmUJAQ10aHJvd0lzQWN0aXZlAAkAzAgCCQEMQm9vbGVhbkVudHJ5AgUHa0FjdGl2ZQYJAMwIAgkBC0RlbGV0ZUVudHJ5AQUGa0NhdXNlBQNuaWwDbXNnARl0YWtlSW50b0FjY291bnRFeHRyYUZ1bmRzAAkBC3ZhbHVlT3JFbHNlAgkBCGlzQWN0aXZlAAMJAQIhPQIIBQNtc2cGY2FsbGVyBQ9tb25leUJveEFkZHJlc3MJAAIBAiZPbmx5IHRoZSB3YWxsZXQgY2FuIGNhbGwgdGhpcyBmdW5jdGlvbgQIYmFsYW5jZXMJAQNfeHAACgEOdGFrZUV4dHJhRnVuZHMCA2FjYwdhc3NldElkBA0kdDAzMjI4NjMyMzA0BQNhY2MEA3N1bQgFDSR0MDMyMjg2MzIzMDQCXzEEAWkIBQ0kdDAzMjI4NjMyMzA0Al8yBAh0b2tlbkI1OAkA2QQBBQdhc3NldElkBAhyQmFsYW5jZQkAZAIJAPAHAgUEdGhpcwUIdG9rZW5CNTgJAQxzdGFrZWRBbW91bnQBBQh0b2tlbkI1OAQMZW5yb2xsQW1vdW50CQBlAgUIckJhbGFuY2UJAJEDAgUIYmFsYW5jZXMFAWkDCQBmAgAABQxlbnJvbGxBbW91bnQJAQdzdXNwZW5kAQkArAICAiBFbnJvbGwgYW1vdW50IG5lZ2F0aXZlIGZvciBhc3NldAUHYXNzZXRJZAQHYWlyZHJvcAMJAGYCBQxlbnJvbGxBbW91bnQAAAkA/AcEBRBscEZhcm1pbmdBZGRyZXNzAgdhaXJEcm9wBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFCHRva2VuQjU4BQxlbnJvbGxBbW91bnQFA25pbAAAAwkAAAIFB2FpcmRyb3AFB2FpcmRyb3AJAJQKAgkAZAIFA3N1bQUMZW5yb2xsQW1vdW50CQBkAgUBaQABCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBAFrCgACJGwFCGFzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlAoCAAAAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEOdGFrZUV4dHJhRnVuZHMCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoDCQAAAggFAWsCXzEAAAkAAgECEE5vIG1vbmV5IHRvIHRha2UFA25pbAECdHgBBnZlcmlmeQAEE211bHRpU2lnbmVkQnlBZG1pbnMEEmFkbWluUHViS2V5MVNpZ25lZAMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAFDGFkbWluUHViS2V5MQABAAAEEmFkbWluUHViS2V5MlNpZ25lZAMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAEFDGFkbWluUHViS2V5MgABAAAEEmFkbWluUHViS2V5M1NpZ25lZAMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAIFDGFkbWluUHViS2V5MwABAAAJAGcCCQBkAgkAZAIFEmFkbWluUHViS2V5MVNpZ25lZAUSYWRtaW5QdWJLZXkyU2lnbmVkBRJhZG1pblB1YktleTNTaWduZWQAAgQHJG1hdGNoMAUCdHgDCQABAgUHJG1hdGNoMAIXSW52b2tlU2NyaXB0VHJhbnNhY3Rpb24EA2ludgUHJG1hdGNoMAQTY2FsbFRha2VJbnRvQWNjb3VudAMJAAACCAUDaW52BGRBcHAFBHRoaXMJAAACCAUDaW52CGZ1bmN0aW9uAhl0YWtlSW50b0FjY291bnRFeHRyYUZ1bmRzBwQNc2lnbmVkQnlBZG1pbgMDAwkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAUMYWRtaW5QdWJLZXkxBgkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAUMYWRtaW5QdWJLZXkyBgkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAUMYWRtaW5QdWJLZXkzBgkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAURYWRtaW5QdWJLZXlJbnZva2UDAwUTY2FsbFRha2VJbnRvQWNjb3VudAUNc2lnbmVkQnlBZG1pbgcGBRNtdWx0aVNpZ25lZEJ5QWRtaW5zBRNtdWx0aVNpZ25lZEJ5QWRtaW5z4QUuPg==", "height": 2288105, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: H5nDHCAQYfWvdHmpwq6BAKet1aHwZp2YKtdkh8e4rTVo Next: FQJkm5Aogrt7psbfx8LYFeSGcqsZKB9cxWY9bE2JPVe8 Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let PRECISION = 1000000
55
66 let MAX_A = 1000000
77
88 let MAX_A_CHANGE = 10
99
1010 let DECIMALS = 6
1111
1212 let MIN_RAMP_TIME = (86400 / 60)
1313
1414 let version = "3.0.0"
1515
1616 let kVersion = "version"
1717
1818 let kAssets = "asset_ids"
1919
2020 let kAssetBalance = "_balance"
2121
2222 let kActive = "active"
2323
2424 let kCause = "shutdown_cause"
2525
2626 let kShareAssetId = "share_asset_id"
2727
2828 let kShareAssetSupply = "share_asset_supply"
2929
3030 let kFee = "commission"
3131
3232 let kDAppThresholdCoef = "dAppThresholdCoef"
3333
3434 let kUSDNAddress = "staking_usdnnsbt_address"
3535
3636 let kDiscounts = "discounts"
3737
3838 let kDiscountValues = "discount_values"
3939
4040 let kUserSwopInGov = "_SWOP_amount"
4141
4242 let kUserGSwopInGov = "_GSwop_amount"
4343
4444 let kAdminPubKey1 = "admin_pub_1"
4545
4646 let kAdminPubKey2 = "admin_pub_2"
4747
4848 let kAdminPubKey3 = "admin_pub_3"
4949
5050 let kAdminInvokePubKey = "admin_invoke_pub"
5151
5252 let kMoneyBoxAddress = "money_box_address"
5353
5454 let kGovAddress = "governance_address"
5555
5656 let kVotingAddress = "voting_address"
5757
5858 let kFarmingAddress = "farming_address"
5959
6060 let kLPFarmingAddress = "lp_farming"
6161
6262 let oracle = Address(base58'3MvVBtsXroQpy1tsPw21TU2ET9A8WfmrNjz')
6363
6464 func getBase58FromOracle (key) = match getString(oracle, key) {
6565 case string: String =>
6666 fromBase58String(string)
6767 case nothing =>
6868 throw((key + "is empty"))
6969 }
7070
7171
7272 let adminPubKey1 = getBase58FromOracle(kAdminPubKey1)
7373
7474 let adminPubKey2 = getBase58FromOracle(kAdminPubKey2)
7575
7676 let adminPubKey3 = getBase58FromOracle(kAdminPubKey3)
7777
7878 let adminPubKeyInvoke = getBase58FromOracle(kAdminInvokePubKey)
7979
8080 let moneyBoxAddress = Address(getBase58FromOracle(kMoneyBoxAddress))
8181
8282 let govAddress = Address(getBase58FromOracle(kGovAddress))
8383
8484 let stakingUSDNAddress = Address(getBase58FromOracle(kUSDNAddress))
8585
8686 let votingAddress = Address(getBase58FromOracle(kVotingAddress))
8787
8888 let farmingAddress = Address(getBase58FromOracle(kFarmingAddress))
8989
9090 let lpFarmingAddress = Address(getBase58FromOracle(kLPFarmingAddress))
9191
9292 let USDN = base58'8UrfDVd5GreeUwm7uPk7eYz1eMv376kzR52C6sANPkwS'
9393
9494 let stakingAssets = [toBase58String(USDN)]
9595
9696 let active = getBooleanValue(this, kActive)
9797
9898 let shareAssetId = fromBase58String(getStringValue(this, kShareAssetId))
9999
100100 let shareSupply = getIntegerValue(this, kShareAssetSupply)
101101
102102 let feeScale6 = 1000000
103103
104104 let fee = getIntegerValue(this, kFee)
105105
106106 let feeGovernance = fraction(40, feeScale6, 100)
107107
108108 let initial_A = getIntegerValue(this, "initial_A")
109109
110110 let future_A = getIntegerValue(this, "future_A")
111111
112112 let initial_A_time = valueOrElse(getInteger(this, "initial_A_time"), 0)
113113
114114 let future_A_time = valueOrElse(getInteger(this, "future_A_time"), 0)
115115
116116 let assetIds = split(getStringValue(this, kAssets), ",")
117117
118118 let nCoins = size(assetIds)
119119
120120 func suspend (cause) = [BooleanEntry(kActive, false), StringEntry(kCause, cause)]
121121
122122
123123 func throwIsActive () = throw("DApp is already active")
124124
125125
126126 func isActive () = if (active)
127127 then unit
128128 else throw("DApp is inactive at this moment")
129129
130130
131131 func isAdminCall (i) = if (containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey))
132132 then unit
133133 else throw("Only admin can call this function")
134134
135135
136136 func isSelfCall (i) = if ((this == i.caller))
137137 then unit
138138 else throw("Only contract itself can call this function")
139139
140140
141141 let big2 = toBigInt(2)
142142
143143 let iter10 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
144144
145145 let iter15 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
146146
147147 let iter16 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
148148
149149 let blockTimestamp = height
150150
151151 func assert (a) = if (a)
152152 then false
153153 else true
154154
155155
156156 func calculateFeeDiscount (userAddr) = {
157157 let user = match userAddr {
158158 case u: Address =>
159159 toString(u)
160160 case u: String =>
161161 u
162162 case _ =>
163163 throw("Unknow type of user Addr")
164164 }
165165 let swopAmount = valueOrElse(getInteger(govAddress, (user + kUserGSwopInGov)), 0)
166166 let gSwopAmount = valueOrElse(getInteger(govAddress, (user + kUserGSwopInGov)), swopAmount)
167167 let discountValues = split(getStringValue(oracle, kDiscountValues), ",")
168168 let discounts = split(getStringValue(oracle, kDiscounts), ",")
169169 if (if ((gSwopAmount >= parseIntValue(discountValues[0])))
170170 then (parseIntValue(discountValues[1]) > gSwopAmount)
171171 else false)
172172 then (feeScale6 - parseIntValue(discounts[0]))
173173 else if (if ((gSwopAmount >= parseIntValue(discountValues[1])))
174174 then (parseIntValue(discountValues[2]) > gSwopAmount)
175175 else false)
176176 then (feeScale6 - parseIntValue(discounts[1]))
177177 else if (if ((gSwopAmount >= parseIntValue(discountValues[2])))
178178 then (parseIntValue(discountValues[3]) > gSwopAmount)
179179 else false)
180180 then (feeScale6 - parseIntValue(discounts[2]))
181181 else if (if ((gSwopAmount >= parseIntValue(discountValues[3])))
182182 then (parseIntValue(discountValues[4]) > gSwopAmount)
183183 else false)
184184 then (feeScale6 - parseIntValue(discounts[3]))
185185 else if ((gSwopAmount >= parseIntValue(discountValues[4])))
186186 then (feeScale6 - parseIntValue(discounts[4]))
187187 else feeScale6
188188 }
189189
190190
191191 func _A () = {
192192 let t1 = future_A_time
193193 let A1 = future_A
194194 if ((t1 > blockTimestamp))
195195 then {
196196 let A0 = initial_A
197197 let t0 = initial_A_time
198198 if ((A1 > A0))
199199 then (A0 + (((A1 - A0) * (blockTimestamp - t0)) / (t1 - t0)))
200200 else (A0 - (((A0 - A1) * (blockTimestamp - t0)) / (t1 - t0)))
201201 }
202202 else A1
203203 }
204204
205205
206206 func _xp () = {
207207 func assetBalances (acc,assetId) = (acc :+ valueOrElse(getInteger(this, (assetId + kAssetBalance)), 0))
208208
209209 let $l = assetIds
210210 let $s = size($l)
211211 let $acc0 = nil
212212 func $f0_1 ($a,$i) = if (($i >= $s))
213213 then $a
214214 else assetBalances($a, $l[$i])
215215
216216 func $f0_2 ($a,$i) = if (($i >= $s))
217217 then $a
218218 else throw("List size exceeds 10")
219219
220220 $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)
221221 }
222222
223223
224224 func _xp_mem (xp) = xp
225225
226226
227227 func sumList (acc,element) = (acc + element)
228228
229229
230230 func get_D (xp,amp) = {
231231 let @ = invoke(this, "D", [xp, amp], nil)
232232 if ($isInstanceOf(@, "Int"))
233233 then @
234234 else throw(($getType(@) + " couldn't be cast to Int"))
235235 }
236236
237237
238238 func get_D_internal (xp,amp) = {
239239 let S = {
240240 let $l = xp
241241 let $s = size($l)
242242 let $acc0 = 0
243243 func $f0_1 ($a,$i) = if (($i >= $s))
244244 then $a
245245 else sumList($a, $l[$i])
246246
247247 func $f0_2 ($a,$i) = if (($i >= $s))
248248 then $a
249249 else throw("List size exceeds 10")
250250
251251 $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)
252252 }
253253 if ((S == 0))
254254 then 0
255255 else {
256256 let Ann = (amp * nCoins)
257257 let AnnS = (toBigInt(Ann) * toBigInt(S))
258258 let Ann1 = toBigInt((Ann - 1))
259259 func Dproc (acc,i) = if ((acc._2 == true))
260260 then acc
261261 else {
262262 let Dprev = acc._1
263263 func D_PProc (D_P,i) = if ((nCoins > i))
264264 then ((D_P * Dprev) / (toBigInt(xp[i]) * toBigInt(nCoins)))
265265 else D_P
266266
267267 let D_P = {
268268 let $l = iter10
269269 let $s = size($l)
270270 let $acc0 = Dprev
271271 func $f1_1 ($a,$i) = if (($i >= $s))
272272 then $a
273273 else D_PProc($a, $l[$i])
274274
275275 func $f1_2 ($a,$i) = if (($i >= $s))
276276 then $a
277277 else throw("List size exceeds 10")
278278
279279 $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)
280280 }
281281 let D = fraction((AnnS + (toBigInt(nCoins) * D_P)), Dprev, ((Ann1 * Dprev) + (toBigInt((nCoins + 1)) * D_P)))
282282 if ((D > Dprev))
283283 then if ((1 >= toInt((D - Dprev))))
284284 then $Tuple2(D, true)
285285 else $Tuple2(D, false)
286286 else if ((1 >= toInt((Dprev - D))))
287287 then $Tuple2(D, true)
288288 else $Tuple2(D, false)
289289 }
290290
291291 let $t064616527 = {
292292 let $l = iter15
293293 let $s = size($l)
294294 let $acc0 = $Tuple2(toBigInt(S), false)
295295 func $f1_1 ($a,$i) = if (($i >= $s))
296296 then $a
297297 else Dproc($a, $l[$i])
298298
299299 func $f1_2 ($a,$i) = if (($i >= $s))
300300 then $a
301301 else throw("List size exceeds 15")
302302
303303 $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)
304304 }
305305 let D = $t064616527._1
306306 let finished = $t064616527._2
307307 if ((finished == false))
308308 then throw(("get_D() not finished with " + toString(D)))
309309 else toInt(D)
310310 }
311311 }
312312
313313
314314 func getDMem (xp,amp) = get_D(_xp_mem(xp), amp)
315315
316316
317317 func getY (in,out,x,xp_) = if (assert((in != out)))
318318 then throw("same coin")
319319 else if (assert(if ((out >= 0))
320320 then (in >= 0)
321321 else false))
322322 then throw("below zero")
323323 else if (assert(if ((nCoins > out))
324324 then (nCoins > in)
325325 else false))
326326 then throw("above N_COINS")
327327 else {
328328 let amp = _A()
329329 let D = get_D(xp_, amp)
330330 let Ann = (amp * nCoins)
331331 func S_c (acc,i) = {
332332 let $t070987115 = acc
333333 let S_ = $t070987115._1
334334 let c = $t070987115._2
335335 let x_ = if ((in == i))
336336 then x
337337 else xp_[i]
338338 if (if ((i != out))
339339 then (nCoins > i)
340340 else false)
341341 then $Tuple2((S_ + x_), fraction(c, toBigInt(D), toBigInt((x_ * nCoins))))
342342 else $Tuple2(S_, c)
343343 }
344344
345345 let $t073237378 = {
346346 let $l = iter10
347347 let $s = size($l)
348348 let $acc0 = $Tuple2(0, toBigInt(D))
349349 func $f0_1 ($a,$i) = if (($i >= $s))
350350 then $a
351351 else S_c($a, $l[$i])
352352
353353 func $f0_2 ($a,$i) = if (($i >= $s))
354354 then $a
355355 else throw("List size exceeds 10")
356356
357357 $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)
358358 }
359359 let S_ = $t073237378._1
360360 let c_ = $t073237378._2
361361 let c = fraction(c_, toBigInt(D), toBigInt((Ann * nCoins)))
362362 let bD = toBigInt(((S_ + (D / Ann)) - D))
363363 func y_proc (acc,_i) = if ((acc._2 == true))
364364 then acc
365365 else {
366366 let y_prev = acc._1
367367 let y = (((y_prev * y_prev) + c) / ((big2 * y_prev) + bD))
368368 if ((y > y_prev))
369369 then if ((1 >= toInt((y - y_prev))))
370370 then $Tuple2(y, true)
371371 else $Tuple2(y, false)
372372 else if ((1 >= toInt((y_prev - y))))
373373 then $Tuple2(y, true)
374374 else $Tuple2(y, false)
375375 }
376376
377377 let $t078607927 = {
378378 let $l = iter16
379379 let $s = size($l)
380380 let $acc0 = $Tuple2(toBigInt(D), false)
381381 func $f1_1 ($a,$i) = if (($i >= $s))
382382 then $a
383383 else y_proc($a, $l[$i])
384384
385385 func $f1_2 ($a,$i) = if (($i >= $s))
386386 then $a
387387 else throw("List size exceeds 16")
388388
389389 $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)
390390 }
391391 let y = $t078607927._1
392392 let finished = $t078607927._2
393393 if ((finished == false))
394394 then throw(("getY() not finished with " + toString(y)))
395395 else toInt(y)
396396 }
397397
398398
399399 func get_y_D (A_,in,xp,D) = if (assert((in >= 0)))
400400 then throw("i below zero")
401401 else if (assert((nCoins > in)))
402402 then throw("i above N_COINS")
403403 else {
404404 let Ann = (A_ * nCoins)
405405 func S_c (acc,i) = {
406406 let $t083068323 = acc
407407 let S_ = $t083068323._1
408408 let c = $t083068323._2
409409 let x_ = if (if ((in != i))
410410 then (nCoins > i)
411411 else false)
412412 then xp[i]
413413 else 0
414414 if (if ((nCoins > i))
415415 then (in != i)
416416 else false)
417417 then $Tuple2((S_ + x_), fraction(c, toBigInt(D), toBigInt((x_ * nCoins))))
418418 else $Tuple2(S_, c)
419419 }
420420
421421 let $t085438598 = {
422422 let $l = iter10
423423 let $s = size($l)
424424 let $acc0 = $Tuple2(0, toBigInt(D))
425425 func $f0_1 ($a,$i) = if (($i >= $s))
426426 then $a
427427 else S_c($a, $l[$i])
428428
429429 func $f0_2 ($a,$i) = if (($i >= $s))
430430 then $a
431431 else throw("List size exceeds 10")
432432
433433 $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)
434434 }
435435 let S_ = $t085438598._1
436436 let c_ = $t085438598._2
437437 let c = fraction(c_, toBigInt(D), toBigInt((Ann * nCoins)))
438438 let bD = toBigInt(((S_ + (D / Ann)) - D))
439439 func y_D_proc (acc,i) = if ((acc._2 == true))
440440 then acc
441441 else {
442442 let y_prev = acc._1
443443 let y = (((y_prev * y_prev) + c) / ((big2 * y_prev) + bD))
444444 if ((y > y_prev))
445445 then if ((1 >= toInt((y - y_prev))))
446446 then $Tuple2(y, true)
447447 else $Tuple2(y, false)
448448 else if ((1 >= toInt((y_prev - y))))
449449 then $Tuple2(y, true)
450450 else $Tuple2(y, false)
451451 }
452452
453453 let $t090819150 = {
454454 let $l = iter16
455455 let $s = size($l)
456456 let $acc0 = $Tuple2(toBigInt(D), false)
457457 func $f1_1 ($a,$i) = if (($i >= $s))
458458 then $a
459459 else y_D_proc($a, $l[$i])
460460
461461 func $f1_2 ($a,$i) = if (($i >= $s))
462462 then $a
463463 else throw("List size exceeds 16")
464464
465465 $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)
466466 }
467467 let y = $t090819150._1
468468 let finished = $t090819150._2
469469 if ((finished == false))
470470 then throw(("get_y_D() not finished with " + toString(y)))
471471 else toInt(y)
472472 }
473473
474474
475475 func _calcWithdrawOneCoin (xp,_token_amount,i,caller) = {
476476 let feeDiscount = calculateFeeDiscount(caller)
477477 let amp = _A()
478478 let _fee = ((fraction(fee, feeDiscount, feeScale6, CEILING) * nCoins) / (4 * (nCoins - 1)))
479479 let total_supply = shareSupply
480480 let D0 = get_D(xp, amp)
481481 let D1 = (D0 - fraction(_token_amount, D0, total_supply))
482482 let new_y = get_y_D(amp, i, xp, D1)
483483 let dy_0 = (xp[i] - new_y)
484484 func xp_reduced_proc (acc,xp_j) = {
485485 let $t097919820 = acc
486486 let xp_reduced = $t097919820._1
487487 let index = $t097919820._2
488488 let dx_expected = if ((index == i))
489489 then (fraction(xp_j, D1, D0) - new_y)
490490 else (xp_j - fraction(xp_j, D1, D0))
491491 $Tuple2((xp_reduced :+ (xp_j - fraction(_fee, dx_expected, feeScale6))), (index + 1))
492492 }
493493
494494 let $t01008210146 = {
495495 let $l = xp
496496 let $s = size($l)
497497 let $acc0 = $Tuple2(nil, 0)
498498 func $f0_1 ($a,$i) = if (($i >= $s))
499499 then $a
500500 else xp_reduced_proc($a, $l[$i])
501501
502502 func $f0_2 ($a,$i) = if (($i >= $s))
503503 then $a
504504 else throw("List size exceeds 10")
505505
506506 $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)
507507 }
508508 let xp_reduced = $t01008210146._1
509509 let index = $t01008210146._2
510510 let xp_reduced_i = xp_reduced[i]
511511 let dy = ((xp_reduced_i - get_y_D(amp, i, xp_reduced, D1)) - 1)
512512 $Tuple2(dy, (dy_0 - dy))
513513 }
514514
515515
516516 func getStrAssetId (assetId) = match assetId {
517517 case id: ByteVector =>
518518 toBase58String(id)
519519 case waves: Unit =>
520520 "WAVES"
521521 case _ =>
522522 throw("Match error")
523523 }
524524
525525
526526 func calcStakingFuncAndAddres (stake,assetId) = if (stake)
527527 then $Tuple2("lockNeutrino", stakingUSDNAddress)
528528 else $Tuple2("unlockNeutrino", stakingUSDNAddress)
529529
530530
531531 func calcStakingParams (stake,amount,assetId) = if (stake)
532532 then {
533533 let $t01071010776 = calcStakingFuncAndAddres(stake, assetId)
534534 let call = $t01071010776._1
535535 let stakingAddr = $t01071010776._2
536536 $Tuple4(call, stakingAddr, nil, [AttachedPayment(assetId, amount)])
537537 }
538538 else {
539539 let $t01086210928 = calcStakingFuncAndAddres(stake, assetId)
540540 let call = $t01086210928._1
541541 let stakingAddr = $t01086210928._2
542542 $Tuple4(call, stakingAddr, [amount, toBase58String(assetId)], nil)
543543 }
544544
545545
546546 func stake (amount,assetIdString) = if (containsElement(stakingAssets, assetIdString))
547547 then {
548548 let $t01111511217 = calcStakingParams(true, amount, fromBase58String(assetIdString))
549549 let call = $t01111511217._1
550550 let addr = $t01111511217._2
551551 let params = $t01111511217._3
552552 let payments = $t01111511217._4
553553 invoke(addr, call, params, payments)
554554 }
555555 else 0
556556
557557
558558 func unstake (amount,assetIdString) = if (containsElement(stakingAssets, assetIdString))
559559 then {
560560 let $t01140211505 = calcStakingParams(false, amount, fromBase58String(assetIdString))
561561 let call = $t01140211505._1
562562 let addr = $t01140211505._2
563563 let params = $t01140211505._3
564564 let payments = $t01140211505._4
565565 invoke(addr, call, params, payments)
566566 }
567567 else 0
568568
569569
570570 func stakedAmount (assetId) = {
571571 let stakedAmountCalculated = match assetId {
572572 case aId: ByteVector =>
573573 if ((aId == USDN))
574574 then getInteger(stakingUSDNAddress, ((("rpd_balance_" + toBase58String(aId)) + "_") + toString(this)))
575575 else 0
576576 case _: Unit =>
577577 0
578578 case _ =>
579579 throw("Match error")
580580 }
581581 match stakedAmountCalculated {
582582 case i: Int =>
583583 i
584584 case _ =>
585585 0
586586 }
587587 }
588588
589589
590590 func checkSuspicious () = {
591591 let contractBalances = _xp()
592592 func checkBalance (acc,assetId) = {
593593 let $t01211612141 = acc
594594 let suspicious = $t01211612141._1
595595 let i = $t01211612141._2
596596 if (suspicious)
597597 then $Tuple2(suspicious, i)
598598 else {
599599 let aBalance = (assetBalance(this, fromBase58String(assetId)) + stakedAmount(fromBase58String(assetId)))
600600 if ((contractBalances[i] > aBalance))
601601 then $Tuple2(true, i)
602602 else $Tuple2(false, (i + 1))
603603 }
604604 }
605605
606606 let $l = assetIds
607607 let $s = size($l)
608608 let $acc0 = $Tuple2(false, 0)
609609 func $f0_1 ($a,$i) = if (($i >= $s))
610610 then $a
611611 else checkBalance($a, $l[$i])
612612
613613 func $f0_2 ($a,$i) = if (($i >= $s))
614614 then $a
615615 else throw("List size exceeds 10")
616616
617617 $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)
618618 }
619619
620620
621621 func suspendSuspicious (i) = suspend(("Suspicious state with asset: " + assetIds[i]))
622622
623623
624624 func returnPayments (caller,payments) = {
625625 func parsePayments (acc,payment) = (acc :+ ScriptTransfer(caller, payment.amount, payment.assetId))
626626
627627 let $l = payments
628628 let $s = size($l)
629629 let $acc0 = nil
630630 func $f0_1 ($a,$i) = if (($i >= $s))
631631 then $a
632632 else parsePayments($a, $l[$i])
633633
634634 func $f0_2 ($a,$i) = if (($i >= $s))
635635 then $a
636636 else throw("List size exceeds 10")
637637
638638 $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)
639639 }
640640
641641
642642 func checkDAppThreshold (newBalances) = {
643643 let dAppThresholdCoef = valueOrErrorMessage(getInteger(this, kDAppThresholdCoef), "No dAppThresholdCoef key")
644644 let thresholdScale = 10000
645645 let maxBalance = max(newBalances)
646646 let minBalance = min(newBalances)
647647 let ratio = fraction(maxBalance, thresholdScale, minBalance)
648648 if ((ratio > (dAppThresholdCoef * thresholdScale)))
649649 then throw("New balance in assets of the DApp is less than threshold")
650650 else false
651651 }
652652
653653
654654 func checkCoins (assetIds) = {
655655 let coins = split(assetIds, ",")
656656 if ((size(coins) > 10))
657657 then throw("To many coins, max coins size 10")
658658 else {
659659 func checkCoin (error,assetId) = {
660660 let asset = valueOrErrorMessage(fromBase58String(assetId), ("fromBase58String: " + assetId))
661661 let decimals = valueOrErrorMessage(assetInfo(asset), ("assetInfo: " + assetId)).decimals
662662 if ((decimals != DECIMALS))
663663 then throw("wrong decimals")
664664 else false
665665 }
666666
667667 let $l = coins
668668 let $s = size($l)
669669 let $acc0 = false
670670 func $f0_1 ($a,$i) = if (($i >= $s))
671671 then $a
672672 else checkCoin($a, $l[$i])
673673
674674 func $f0_2 ($a,$i) = if (($i >= $s))
675675 then $a
676676 else throw("List size exceeds 10")
677677
678678 $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)
679679 }
680680 }
681681
682682
683683 @Callable(msg)
684684 func D (xp,amp) = {
685685 let D = get_D_internal(xp, amp)
686686 $Tuple2([IntegerEntry("D", D)], D)
687687 }
688688
689689
690690
691691 @Callable(msg)
692692 func init (assetIds,_A,_dAppThresholdCoef) = if (!(isDataStorageUntouched(this)))
693693 then throw("Already initialized")
694694 else if ((0 >= _A))
695695 then throw("Amp must be must > 0")
696696 else if ((0 >= _dAppThresholdCoef))
697697 then throw("dApp Threshold Coef must be > 0")
698698 else {
699699 let shareName = "s_Multi_USD"
700700 let shareDescription = ("ShareToken of SwopFi protocol for MultiStable USD pool at address " + toString(this))
701701 let issueToken = Issue(shareName, shareDescription, 0, 6, true)
702702 let tokenId = calculateAssetId(issueToken)
703703 if (checkCoins(assetIds))
704704 then throw()
705705 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]
706706 }
707707
708708
709709
710710 @Callable(msg)
711711 func addLiquidity (minMintAmount,stakeFarming,lockType) = valueOrElse(isActive(), {
712712 let amp = _A()
713713 let xp = _xp()
714714 let D0 = if ((shareSupply == 0))
715715 then 0
716716 else getDMem(xp, amp)
717717 let $t01534915604 = if (if ((lockType > 0))
718718 then (msg.payments[(size(msg.payments) - 1)].assetId == unit)
719719 else false)
720720 then $Tuple2(removeByIndex(msg.payments, (size(msg.payments) - 1)), [msg.payments[(size(msg.payments) - 1)]])
721721 else $Tuple2(msg.payments, nil)
722722 let payments = $t01534915604._1
723723 let lockFee = $t01534915604._2
724724 let paymentsSize = size(payments)
725725 func validPayments (n) = if ((paymentsSize > nCoins))
726726 then throw(("payments size > " + toString(nCoins)))
727727 else if ((1 > paymentsSize))
728728 then throw("payments size < 1")
729729 else if (if ((shareSupply == 0))
730730 then (nCoins != paymentsSize)
731731 else false)
732732 then throw("initial deposit requires all coins")
733733 else {
734734 func paymantValid (acc,payment) = if (containsElement(assetIds, getStrAssetId(payment.assetId)))
735735 then true
736736 else throw("Invalid asset in payment")
737737
738738 let $l = payments
739739 let $s = size($l)
740740 let $acc0 = false
741741 func $f0_1 ($a,$i) = if (($i >= $s))
742742 then $a
743743 else paymantValid($a, $l[$i])
744744
745745 func $f0_2 ($a,$i) = if (($i >= $s))
746746 then $a
747747 else throw("List size exceeds 10")
748748
749749 $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)
750750 }
751751
752752 if (!(validPayments(paymentsSize)))
753753 then throw()
754754 else {
755755 let suspicious = checkSuspicious()
756756 if (suspicious._1)
757757 then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.caller, payments))
758758 else {
759759 func parsePayments (acc,assetId) = {
760760 let $t01647416500 = acc
761761 let newBalances = $t01647416500._1
762762 let i = $t01647416500._2
763763 func parsePayment (newBalance,payment) = if ((getStrAssetId(payment.assetId) == assetId))
764764 then (newBalance + payment.amount)
765765 else newBalance
766766
767767 let newBalace = {
768768 let $l = payments
769769 let $s = size($l)
770770 let $acc0 = xp[i]
771771 func $f0_1 ($a,$i) = if (($i >= $s))
772772 then $a
773773 else parsePayment($a, $l[$i])
774774
775775 func $f0_2 ($a,$i) = if (($i >= $s))
776776 then $a
777777 else throw("List size exceeds 10")
778778
779779 $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)
780780 }
781781 $Tuple2((newBalances :+ newBalace), (i + 1))
782782 }
783783
784784 let $t01685016917 = {
785785 let $l = assetIds
786786 let $s = size($l)
787787 let $acc0 = $Tuple2(nil, 0)
788788 func $f0_1 ($a,$i) = if (($i >= $s))
789789 then $a
790790 else parsePayments($a, $l[$i])
791791
792792 func $f0_2 ($a,$i) = if (($i >= $s))
793793 then $a
794794 else throw("List size exceeds 10")
795795
796796 $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)
797797 }
798798 let newBalances = $t01685016917._1
799799 let k = $t01685016917._2
800800 if (checkDAppThreshold(newBalances))
801801 then throw()
802802 else {
803803 let D1 = getDMem(newBalances, amp)
804804 if (assert((D1 > D0)))
805805 then throw("D1 > D0")
806806 else {
807807 let feeDiscount = calculateFeeDiscount(msg.caller)
808808 func calcScriptActions (acc,newBalance) = {
809809 let $t01723717278 = acc
810810 let invBalances = $t01723717278._1
811811 let scriptActions = $t01723717278._2
812812 let i = $t01723717278._3
813813 if ((shareSupply > 0))
814814 then {
815815 let _fee = ((fraction(fee, feeDiscount, feeScale6, CEILING) * nCoins) / (4 * (nCoins - 1)))
816816 let fees = {
817817 let idealBalance = fraction(D1, xp[i], D0)
818818 let difference = if ((idealBalance > newBalance))
819819 then (idealBalance - newBalance)
820820 else (newBalance - idealBalance)
821821 fraction(_fee, difference, feeScale6)
822822 }
823823 let governanceFees = fraction(fees, feeGovernance, feeScale6)
824824 let finalBalance = (newBalance - fees)
825825 let invariantBalance = (newBalance - fees)
826826 let pmt = (newBalance - xp[i])
827827 let lpFees = (fees - governanceFees)
828828 let inv = if ((pmt > 0))
829829 then stake((pmt - fees), assetIds[i])
830830 else unstake(fees, assetIds[i])
831831 if ((inv == inv))
832832 then {
833833 let airdrop = if ((lpFees > 0))
834834 then invoke(lpFarmingAddress, "airDrop", nil, [AttachedPayment(fromBase58String(assetIds[i]), lpFees)])
835835 else 0
836836 if ((airdrop == airdrop))
837837 then $Tuple3((invBalances :+ invariantBalance), (scriptActions ++ [ScriptTransfer(moneyBoxAddress, governanceFees, fromBase58String(assetIds[i])), IntegerEntry((assetIds[i] + kAssetBalance), finalBalance)]), (i + 1))
838838 else throw("Strict value is not equal to itself.")
839839 }
840840 else throw("Strict value is not equal to itself.")
841841 }
842842 else {
843843 let inv = stake(newBalance, assetIds[i])
844844 if ((inv == inv))
845845 then $Tuple3((invBalances :+ newBalance), (scriptActions :+ IntegerEntry((assetIds[i] + kAssetBalance), newBalance)), (i + 1))
846846 else throw("Strict value is not equal to itself.")
847847 }
848848 }
849849
850850 let $t01898319071 = {
851851 let $l = newBalances
852852 let $s = size($l)
853853 let $acc0 = $Tuple3(nil, nil, 0)
854854 func $f1_1 ($a,$i) = if (($i >= $s))
855855 then $a
856856 else calcScriptActions($a, $l[$i])
857857
858858 func $f1_2 ($a,$i) = if (($i >= $s))
859859 then $a
860860 else throw("List size exceeds 10")
861861
862862 $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)
863863 }
864864 let invBalances = $t01898319071._1
865865 let scriptActions = $t01898319071._2
866866 let D2 = getDMem(invBalances, amp)
867867 let mint_amount = if ((shareSupply == 0))
868868 then D1
869869 else fraction(shareSupply, (D2 - D0), D0)
870870 if (assert((mint_amount >= minMintAmount)))
871871 then throw("Slippage screwed you")
872872 else if (stakeFarming)
873873 then {
874874 let re = invoke(this, "reissueShare", [mint_amount], nil)
875875 if ((re == re))
876876 then {
877877 let s = invoke(farmingAddress, "lockShareTokens", [toString(this), lockType], ([AttachedPayment(shareAssetId, mint_amount)] ++ lockFee))
878878 if ((s == s))
879879 then (scriptActions :+ IntegerEntry(kShareAssetSupply, (shareSupply + mint_amount)))
880880 else throw("Strict value is not equal to itself.")
881881 }
882882 else throw("Strict value is not equal to itself.")
883883 }
884884 else (scriptActions ++ [Reissue(shareAssetId, mint_amount, true), ScriptTransfer(msg.caller, mint_amount, shareAssetId), IntegerEntry(kShareAssetSupply, (shareSupply + mint_amount))])
885885 }
886886 }
887887 }
888888 }
889889 })
890890
891891
892892
893893 @Callable(msg)
894894 func calcMintAmount (newBalances,user) = {
895895 let amp = _A()
896896 let xp = _xp()
897897 let D1 = getDMem(newBalances, amp)
898898 if ((shareSupply == 0))
899899 then $Tuple2(nil, D1)
900900 else {
901901 let D0 = getDMem(xp, amp)
902902 let feeDiscount = calculateFeeDiscount(user)
903903 func calcInvBalances (acc,newBalance) = {
904904 let $t02032120347 = acc
905905 let invBalances = $t02032120347._1
906906 let i = $t02032120347._2
907907 let _fee = ((fraction(fee, feeDiscount, feeScale6, CEILING) * nCoins) / (4 * (nCoins - 1)))
908908 let fees = {
909909 let idealBalance = fraction(D1, xp[i], D0)
910910 let difference = if ((idealBalance > newBalance))
911911 then (idealBalance - newBalance)
912912 else (newBalance - idealBalance)
913913 fraction(_fee, difference, feeScale6)
914914 }
915915 let invariantBalance = (newBalance - fees)
916916 $Tuple2((invBalances :+ invariantBalance), (i + 1))
917917 }
918918
919919 let $t02094921019 = {
920920 let $l = newBalances
921921 let $s = size($l)
922922 let $acc0 = $Tuple2(nil, 0)
923923 func $f0_1 ($a,$i) = if (($i >= $s))
924924 then $a
925925 else calcInvBalances($a, $l[$i])
926926
927927 func $f0_2 ($a,$i) = if (($i >= $s))
928928 then $a
929929 else throw("List size exceeds 10")
930930
931931 $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)
932932 }
933933 let invBalances = $t02094921019._1
934934 let k = $t02094921019._2
935935 let D2 = getDMem(invBalances, amp)
936936 let mintAmount = fraction(shareSupply, (D2 - D0), D0)
937937 $Tuple2(nil, mintAmount)
938938 }
939939 }
940940
941941
942942
943943 @Callable(msg)
944944 func reissueShare (amount) = valueOrElse(isSelfCall(msg), [Reissue(shareAssetId, amount, true)])
945945
946946
947947
948948 @Callable(msg)
949949 func getDy (assetFrom,assetTo,dx,userAddress) = {
950950 let xp = _xp()
951951 let fromIndex = valueOrErrorMessage(indexOf(assetIds, assetFrom), "unknown token in")
952952 let toIndex = valueOrErrorMessage(indexOf(assetIds, assetTo), "unknown token out")
953953 let x = (xp[fromIndex] + dx)
954954 let y = getY(fromIndex, toIndex, x, xp)
955955 let dy = ((xp[toIndex] - y) - 1)
956956 let feeDiscount = calculateFeeDiscount(Address(fromBase58String(userAddress)))
957957 let _fee = fraction(fraction(fee, feeDiscount, feeScale6, CEILING), dy, feeScale6)
958958 $Tuple2(nil, $Tuple2((dy - _fee), _fee))
959959 }
960960
961961
962962
963963 @Callable(msg)
964964 func exchange (tokenOut,min_dy) = valueOrElse(isActive(), if ((size(msg.payments) != 1))
965965 then throw("size(payments) != 1")
966966 else {
967967 let suspicious = checkSuspicious()
968968 if (suspicious._1)
969969 then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.caller, msg.payments))
970970 else {
971971 let payment = msg.payments[0]
972972 let tokenIn = getStrAssetId(payment.assetId)
973973 let tokenOutB58 = fromBase58String(tokenOut)
974974 let dx = payment.amount
975975 let fromIndex = valueOrErrorMessage(indexOf(assetIds, tokenIn), "unknown token in")
976976 let toIndex = valueOrErrorMessage(indexOf(assetIds, tokenOut), "unknown token out")
977977 let xp = _xp()
978978 let x = (xp[fromIndex] + dx)
979979 let y = getY(fromIndex, toIndex, x, xp)
980980 let _dy = ((xp[toIndex] - y) - 1)
981981 let feeDiscount = calculateFeeDiscount(msg.originCaller)
982982 let _fee = fraction(_dy, fraction(fee, feeDiscount, feeScale6, CEILING), feeScale6)
983983 let dy = (_dy - _fee)
984984 let governanceFees = fraction(_fee, feeGovernance, feeScale6)
985985 if (assert((dy >= min_dy)))
986986 then throw("Exchange resulted in fewer coins than expected")
987987 else {
988988 func makeNewBalances (acc,tokenBalance) = {
989989 let $t02306023086 = acc
990990 let newBalances = $t02306023086._1
991991 let i = $t02306023086._2
992992 if ((i == fromIndex))
993993 then $Tuple2((newBalances :+ (tokenBalance + dx)), (i + 1))
994994 else if ((i == toIndex))
995995 then $Tuple2((newBalances :+ (tokenBalance - _dy)), (i + 1))
996996 else $Tuple2((newBalances :+ tokenBalance), (i + 1))
997997 }
998998
999999 let $t02333723398 = {
10001000 let $l = xp
10011001 let $s = size($l)
10021002 let $acc0 = $Tuple2(nil, 0)
10031003 func $f0_1 ($a,$i) = if (($i >= $s))
10041004 then $a
10051005 else makeNewBalances($a, $l[$i])
10061006
10071007 func $f0_2 ($a,$i) = if (($i >= $s))
10081008 then $a
10091009 else throw("List size exceeds 10")
10101010
10111011 $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)
10121012 }
10131013 let newBalances = $t02333723398._1
10141014 let i = $t02333723398._2
10151015 if (checkDAppThreshold(newBalances))
10161016 then throw()
10171017 else {
10181018 let s = stake(payment.amount, getStrAssetId(payment.assetId))
10191019 if ((s == s))
10201020 then {
10211021 let us = unstake(_dy, tokenOut)
10221022 if ((us == us))
10231023 then {
10241024 let lpFees = (_fee - governanceFees)
10251025 let airdrop = if ((lpFees > 0))
10261026 then invoke(lpFarmingAddress, "airDrop", nil, [AttachedPayment(tokenOutB58, lpFees)])
10271027 else 0
10281028 if ((airdrop == airdrop))
10291029 then $Tuple2([IntegerEntry((tokenIn + kAssetBalance), x), IntegerEntry((tokenOut + kAssetBalance), (xp[toIndex] - _dy)), ScriptTransfer(msg.caller, dy, tokenOutB58), ScriptTransfer(moneyBoxAddress, governanceFees, tokenOutB58)], [dy, tokenOutB58])
10301030 else throw("Strict value is not equal to itself.")
10311031 }
10321032 else throw("Strict value is not equal to itself.")
10331033 }
10341034 else throw("Strict value is not equal to itself.")
10351035 }
10361036 }
10371037 }
10381038 })
10391039
10401040
10411041
10421042 @Callable(msg)
10431043 func withdraw (minAmounts) = valueOrElse(isActive(), if ((size(msg.payments) != 1))
10441044 then throw("size(payments) != 1")
10451045 else {
10461046 let pmtAmount = msg.payments[0].amount
10471047 let pmtAssetId = msg.payments[0].assetId
10481048 if ((shareAssetId != pmtAssetId))
10491049 then throw("unknown payment token")
10501050 else {
10511051 let suspicious = checkSuspicious()
10521052 if (suspicious._1)
10531053 then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.originCaller, msg.payments))
10541054 else {
10551055 func calcScriptActions (acc,balance) = {
10561056 let $t02468924717 = acc
10571057 let scriptActions = $t02468924717._1
10581058 let i = $t02468924717._2
10591059 let wAmount = fraction(balance, pmtAmount, shareSupply)
10601060 if (assert((wAmount >= minAmounts[i])))
10611061 then throw("Withdrawal resulted in fewer coins than expected")
10621062 else {
10631063 let us = unstake(wAmount, assetIds[i])
10641064 if ((us == us))
10651065 then $Tuple2((scriptActions ++ [IntegerEntry((assetIds[i] + kAssetBalance), (balance - wAmount)), ScriptTransfer(msg.originCaller, wAmount, fromBase58String(assetIds[i]))]), (i + 1))
10661066 else throw("Strict value is not equal to itself.")
10671067 }
10681068 }
10691069
10701070 let $t02520725275 = {
10711071 let $l = _xp()
10721072 let $s = size($l)
10731073 let $acc0 = $Tuple2(nil, 0)
10741074 func $f0_1 ($a,$i) = if (($i >= $s))
10751075 then $a
10761076 else calcScriptActions($a, $l[$i])
10771077
10781078 func $f0_2 ($a,$i) = if (($i >= $s))
10791079 then $a
10801080 else throw("List size exceeds 10")
10811081
10821082 $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)
10831083 }
10841084 let scriptActions = $t02520725275._1
10851085 let i = $t02520725275._2
10861086 (scriptActions ++ [Burn(shareAssetId, pmtAmount), IntegerEntry(kShareAssetSupply, (shareSupply - pmtAmount))])
10871087 }
10881088 }
10891089 })
10901090
10911091
10921092
10931093 @Callable(msg)
10941094 func withdrawWithUnlock (minAmounts,unlockAmount) = valueOrElse(isActive(), if ((0 >= unlockAmount))
10951095 then throw("Unlock amount must be positive")
10961096 else {
10971097 let suspicious = checkSuspicious()
10981098 if (suspicious._1)
10991099 then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.caller, msg.payments))
11001100 else {
11011101 let pmtAmount = if ((size(msg.payments) > 0))
11021102 then if ((size(msg.payments) != 1))
11031103 then throw("size(payments) != 1")
11041104 else {
11051105 let pmtAssetId = msg.payments[0].assetId
11061106 if ((shareAssetId != pmtAssetId))
11071107 then throw("unknown payment token")
11081108 else msg.payments[0].amount
11091109 }
11101110 else 0
11111111 let unlock = invoke(farmingAddress, "withdrawShareTokens", [toString(this), unlockAmount], nil)
11121112 if ((unlock == unlock))
11131113 then {
11141114 let withdrawAmount = (pmtAmount + unlockAmount)
11151115 let inv = invoke(this, "withdraw", [minAmounts], [AttachedPayment(shareAssetId, withdrawAmount)])
11161116 if ((inv == inv))
11171117 then nil
11181118 else throw("Strict value is not equal to itself.")
11191119 }
11201120 else throw("Strict value is not equal to itself.")
11211121 }
11221122 })
11231123
11241124
11251125
11261126 @Callable(msg)
11271127 func calcWithdrawOneCoin (tokenAmount,tokenOut,user) = if ((0 >= tokenAmount))
11281128 then throw("Amount must be positive")
11291129 else {
11301130 let i = valueOrErrorMessage(indexOf(assetIds, tokenOut), "unknown token out")
11311131 $Tuple2(nil, _calcWithdrawOneCoin(_xp(), tokenAmount, i, Address(fromBase58String(user)))._1)
11321132 }
11331133
11341134
11351135
11361136 @Callable(msg)
11371137 func withdrawOneCoin (tokenOut,minAmount) = valueOrElse(isActive(), if ((size(msg.payments) != 1))
11381138 then throw("size(payments) != 1")
11391139 else {
11401140 let suspicious = checkSuspicious()
11411141 if (suspicious._1)
11421142 then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.originCaller, msg.payments))
11431143 else {
11441144 let pmtAmount = msg.payments[0].amount
11451145 let pmtAssetId = msg.payments[0].assetId
11461146 if ((pmtAssetId != shareAssetId))
11471147 then throw("unknown token")
11481148 else {
11491149 let outIndex = valueOrErrorMessage(indexOf(assetIds, tokenOut), "unknown token out")
11501150 let tokenOutB58 = fromBase58String(tokenOut)
11511151 let xp = _xp()
11521152 let $t02730727389 = _calcWithdrawOneCoin(xp, pmtAmount, outIndex, msg.originCaller)
11531153 let dy = $t02730727389._1
11541154 let dy_fee = $t02730727389._2
11551155 if (assert((dy >= minAmount)))
11561156 then throw("Not enough coins removed")
11571157 else {
11581158 let governanceFees = fraction(dy_fee, feeGovernance, feeScale6)
11591159 let dy_and_fee = (dy + dy_fee)
11601160 func makeNewBalances (acc,tokenBalance) = {
11611161 let $t02764727673 = acc
11621162 let newBalances = $t02764727673._1
11631163 let i = $t02764727673._2
11641164 if ((i == outIndex))
11651165 then $Tuple2((newBalances :+ (tokenBalance - dy_and_fee)), (i + 1))
11661166 else $Tuple2((newBalances :+ tokenBalance), (i + 1))
11671167 }
11681168
11691169 let $t02784027901 = {
11701170 let $l = xp
11711171 let $s = size($l)
11721172 let $acc0 = $Tuple2(nil, 0)
11731173 func $f0_1 ($a,$i) = if (($i >= $s))
11741174 then $a
11751175 else makeNewBalances($a, $l[$i])
11761176
11771177 func $f0_2 ($a,$i) = if (($i >= $s))
11781178 then $a
11791179 else throw("List size exceeds 10")
11801180
11811181 $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)
11821182 }
11831183 let newBalances = $t02784027901._1
11841184 let v = $t02784027901._2
11851185 if (checkDAppThreshold(newBalances))
11861186 then throw()
11871187 else {
11881188 let us = unstake(dy_and_fee, tokenOut)
11891189 if ((us == us))
11901190 then {
11911191 let lpFees = (dy_fee - governanceFees)
11921192 let airdrop = if ((lpFees > 0))
11931193 then invoke(lpFarmingAddress, "airDrop", nil, [AttachedPayment(tokenOutB58, lpFees)])
11941194 else 0
11951195 if ((airdrop == airdrop))
11961196 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))]
11971197 else throw("Strict value is not equal to itself.")
11981198 }
11991199 else throw("Strict value is not equal to itself.")
12001200 }
12011201 }
12021202 }
12031203 }
12041204 })
12051205
12061206
12071207
12081208 @Callable(msg)
12091209 func withdrawOneCoinWithUnlock (tokenOut,minAmount,unlockAmount) = valueOrElse(isActive(), if ((0 >= unlockAmount))
12101210 then throw("Unlock amount must be positive")
12111211 else {
12121212 let suspicious = checkSuspicious()
12131213 if (suspicious._1)
12141214 then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.caller, msg.payments))
12151215 else {
12161216 let pmtAmount = if ((size(msg.payments) > 0))
12171217 then if ((size(msg.payments) != 1))
12181218 then throw("size(payments) != 1")
12191219 else {
12201220 let pmtAssetId = msg.payments[0].assetId
12211221 if ((shareAssetId != pmtAssetId))
12221222 then throw("unknown payment token")
12231223 else msg.payments[0].amount
12241224 }
12251225 else 0
12261226 let unlock = invoke(farmingAddress, "withdrawShareTokens", [toString(this), unlockAmount], nil)
12271227 if ((unlock == unlock))
12281228 then {
12291229 let withdrawAmount = (pmtAmount + unlockAmount)
12301230 let inv = invoke(this, "withdrawOneCoin", [tokenOut, minAmount], [AttachedPayment(shareAssetId, withdrawAmount)])
12311231 if ((inv == inv))
12321232 then nil
12331233 else throw("Strict value is not equal to itself.")
12341234 }
12351235 else throw("Strict value is not equal to itself.")
12361236 }
12371237 })
12381238
12391239
12401240
12411241 @Callable(msg)
12421242 func A () = $Tuple2(nil, _A())
12431243
12441244
12451245
12461246 @Callable(msg)
12471247 func getVirtualPrice () = {
12481248 let D = get_D(_xp(), _A())
12491249 $Tuple2(nil, fraction(D, PRECISION, shareSupply))
12501250 }
12511251
12521252
12531253
12541254 @Callable(msg)
12551255 func calcTokenAmount (amounts,deposit) = {
12561256 let amp = _A()
12571257 let balances = _xp()
12581258 let D0 = getDMem(balances, amp)
12591259 func calcNewBalances (acc,balance) = {
12601260 let $t02991829944 = acc
12611261 let newBalances = $t02991829944._1
12621262 let i = $t02991829944._2
12631263 let newBalance = (balance + (if (deposit)
12641264 then amounts[i]
12651265 else -(amounts[i])))
12661266 $Tuple2((newBalances :+ newBalance), (i + 1))
12671267 }
12681268
12691269 let newBalances = ( let $l = balances
12701270 let $s = size($l)
12711271 let $acc0 = $Tuple2(nil, 0)
12721272 func $f0_1 ($a,$i) = if (($i >= $s))
12731273 then $a
12741274 else calcNewBalances($a, $l[$i])
12751275
12761276 func $f0_2 ($a,$i) = if (($i >= $s))
12771277 then $a
12781278 else throw("List size exceeds 10")
12791279
12801280 $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
12811281 let D1 = getDMem(newBalances, amp)
12821282 let diff = if (deposit)
12831283 then (D1 - D0)
12841284 else (D0 - D1)
12851285 $Tuple2(nil, fraction(diff, shareSupply, D0))
12861286 }
12871287
12881288
12891289
12901290 @Callable(msg)
12911291 func rampA (_futureA,_futureTime) = valueOrElse(isActive(), valueOrElse(isAdminCall(msg), if (assert((blockTimestamp >= (initial_A_time + MIN_RAMP_TIME))))
12921292 then throw("too often")
12931293 else if (assert((_futureTime >= (blockTimestamp + MIN_RAMP_TIME))))
12941294 then throw("insufficient time")
12951295 else {
12961296 let _initial_A = _A()
12971297 if (assert(if ((_futureA > 0))
12981298 then (MAX_A > _futureA)
12991299 else false))
13001300 then throw("out of base range")
13011301 else if (assert(if (if ((_futureA >= _initial_A))
13021302 then ((_initial_A * MAX_A_CHANGE) >= _futureA)
13031303 else false)
13041304 then true
13051305 else if ((_initial_A > _futureA))
13061306 then ((_futureA * MAX_A_CHANGE) >= _initial_A)
13071307 else false))
13081308 then throw("out of range")
13091309 else [IntegerEntry("initial_A", _initial_A), IntegerEntry("future_A", _futureA), IntegerEntry("initial_A_time", blockTimestamp), IntegerEntry("future_A_time", _futureTime)]
13101310 }))
13111311
13121312
13131313
13141314 @Callable(msg)
13151315 func stopRampA () = valueOrElse(isActive(), valueOrElse(isAdminCall(msg), {
13161316 let currentA = _A()
13171317 [IntegerEntry("initial_A", currentA), IntegerEntry("future_A", currentA), IntegerEntry("initial_A_time", blockTimestamp), IntegerEntry("future_A_time", blockTimestamp)]
13181318 }))
13191319
13201320
13211321
13221322 @Callable(msg)
13231323 func shutdown () = valueOrElse(isAdminCall(msg), if (!(active))
13241324 then throw(("DApp is already suspended. Cause: " + valueOrElse(getString(this, kCause), "the cause wasn't specified")))
13251325 else suspend("Paused by admin"))
13261326
13271327
13281328
13291329 @Callable(msg)
13301330 func activate () = valueOrElse(isAdminCall(msg), if (active)
13311331 then throwIsActive()
13321332 else [BooleanEntry(kActive, true), DeleteEntry(kCause)])
13331333
13341334
13351335
13361336 @Callable(msg)
13371337 func takeIntoAccountExtraFunds () = valueOrElse(isActive(), if ((msg.caller != moneyBoxAddress))
13381338 then throw("Only the wallet can call this function")
13391339 else {
13401340 let balances = _xp()
13411341 func takeExtraFunds (acc,assetId) = {
13421342 let $t03228632304 = acc
13431343 let sum = $t03228632304._1
13441344 let i = $t03228632304._2
13451345 let tokenB58 = fromBase58String(assetId)
13461346 let rBalance = (assetBalance(this, tokenB58) + stakedAmount(tokenB58))
13471347 let enrollAmount = (rBalance - balances[i])
13481348 if ((0 > enrollAmount))
13491349 then suspend(("Enroll amount negative for asset" + assetId))
13501350 else {
13511351 let airdrop = if ((enrollAmount > 0))
13521352 then invoke(lpFarmingAddress, "airDrop", nil, [AttachedPayment(tokenB58, enrollAmount)])
13531353 else 0
13541354 if ((airdrop == airdrop))
13551355 then $Tuple2((sum + enrollAmount), (i + 1))
13561356 else throw("Strict value is not equal to itself.")
13571357 }
13581358 }
13591359
13601360 let k = {
13611361 let $l = assetIds
13621362 let $s = size($l)
13631363 let $acc0 = $Tuple2(0, 0)
13641364 func $f0_1 ($a,$i) = if (($i >= $s))
13651365 then $a
13661366 else takeExtraFunds($a, $l[$i])
13671367
13681368 func $f0_2 ($a,$i) = if (($i >= $s))
13691369 then $a
13701370 else throw("List size exceeds 10")
13711371
13721372 $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)
13731373 }
13741374 if ((k._1 == 0))
13751375 then throw("No money to take")
13761376 else nil
13771377 })
13781378
13791379
13801380 @Verifier(tx)
13811381 func verify () = {
13821382 let multiSignedByAdmins = {
13831383 let adminPubKey1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
13841384 then 1
13851385 else 0
13861386 let adminPubKey2Signed = if (sigVerify(tx.bodyBytes, tx.proofs[1], adminPubKey2))
13871387 then 1
13881388 else 0
13891389 let adminPubKey3Signed = if (sigVerify(tx.bodyBytes, tx.proofs[2], adminPubKey3))
13901390 then 1
13911391 else 0
13921392 (((adminPubKey1Signed + adminPubKey2Signed) + adminPubKey3Signed) >= 2)
13931393 }
13941394 match tx {
13951395 case inv: InvokeScriptTransaction =>
13961396 let callTakeIntoAccount = if ((inv.dApp == this))
13971397 then (inv.function == "takeIntoAccountExtraFunds")
13981398 else false
13991399 let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
14001400 then true
14011401 else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey2))
14021402 then true
14031403 else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey3))
14041404 then true
14051405 else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKeyInvoke)
14061406 if (if (callTakeIntoAccount)
14071407 then signedByAdmin
14081408 else false)
14091409 then true
14101410 else multiSignedByAdmins
14111411 case _ =>
14121412 multiSignedByAdmins
14131413 }
14141414 }
14151415

github/deemru/w8io/026f985 
113.68 ms