tx · 5URz3rJ5QufQvyiZQKoRFhgyyBdtv2KNmW9N7WYrzVtx

3MsXpzisJAwnzUr7XrEoW1BZo4U6rw4tsYK:  -0.07000000 Waves

2022.10.25 18:20 [2288093] smart account 3MsXpzisJAwnzUr7XrEoW1BZo4U6rw4tsYK > SELF 0.00000000 Waves

{ "type": 13, "id": "5URz3rJ5QufQvyiZQKoRFhgyyBdtv2KNmW9N7WYrzVtx", "fee": 7000000, "feeAssetId": null, "timestamp": 1666711167473, "version": 2, "chainId": 84, "sender": "3MsXpzisJAwnzUr7XrEoW1BZo4U6rw4tsYK", "senderPublicKey": "FFdBua5rzzMkZebvsvmN7sAdU7XhFK8QNJ3hiwwxAYRA", "proofs": [ "yYaFtBUXFkWo618E7MnT5JoFRW6yukvwTuM2bUHAFYnDZMFwWXctJ42nMw7CgQM3CGaeCQhyjxKsyWEExxcbvT9", "5Y7SovjERUzweo4SXrAEKyWkgqayJtBPBubCz2N4ZfzZyopj5kGLwLFni1j4ZnAKPZNhRSNThfBSNmBrxvebFDmj" ], "script": "base64:BgJICAISAwoBCBIDCgEIEgMKAQgSBAoCCAESBQoDCAEBEgQKAggIEgQKAggBEgMKAQgSAwoBCBIDCgEYEgMKARgSBAoCCAgSABIAWwAHa0FjdGl2ZQIGYWN0aXZlAAtrQWN0aXZlR2xvYgIUYWN0aXZlX2FsbF9jb250cmFjdHMABmtDYXVzZQIOc2h1dGRvd25fY2F1c2UAGmtSZXdhcmRQb29sRnJhY3Rpb25DdXJyZW50Ah1fY3VycmVudF9wb29sX2ZyYWN0aW9uX3Jld2FyZAAba1Jld2FyZFBvb2xGcmFjdGlvblByZXZpb3VzAh5fcHJldmlvdXNfcG9vbF9mcmFjdGlvbl9yZXdhcmQAE2tIZWlnaHRQb29sRnJhY3Rpb24CGl9wb29sX3Jld2FyZF91cGRhdGVfaGVpZ2h0ABtrVG90YWxSZXdhcmRQZXJCbG9ja0N1cnJlbnQCHnRvdGFsX3Jld2FyZF9wZXJfYmxvY2tfY3VycmVudAAca1RvdGFsUmV3YXJkUGVyQmxvY2tQcmV2aW91cwIfdG90YWxfcmV3YXJkX3Blcl9ibG9ja19wcmV2aW91cwATa1Jld2FyZFVwZGF0ZUhlaWdodAIUcmV3YXJkX3VwZGF0ZV9oZWlnaHQAFmtVc2VyU2hhcmVUb2tlbnNTdGFrZWQCFF9zaGFyZV90b2tlbnNfbG9ja2VkABZrVXNlclNoYXJlVG9rZW5zTG9ja2VkAhVfc2hhcmVfdG9rZW5zX2Jsb2NrZWQAGmtVc2VyU2hhcmVUb2tlbnNMb2NrZWRUeXBlAhpfc2hhcmVfdG9rZW5zX2Jsb2NrZWRfdHlwZQAca1VzZXJTaGFyZVRva2Vuc0xvY2tlZEhlaWdodAIcX3NoYXJlX3Rva2Vuc19ibG9ja2VkX2hlaWdodAAXa1VzZXJTaGFyZVRva2Vuc1ZpcnR1YWwCFV9zaGFyZV90b2tlbnNfdmlydHVhbAAWa1NoYXJlVG90YWxTaGFyZVRva2VucwIaX3RvdGFsX3NoYXJlX3Rva2Vuc19sb2NrZWQAE2tTaGFyZVRva2Vuc1ZpcnR1YWwCG190b3RhbF9zaGFyZV90b2tlbnNfdmlydHVhbAALa0xvY2tQYXJhbXMCDF9sb2NrX3BhcmFtcwANa0xvY2tXYXZlc0ZlZQIObG9ja193YXZlc19mZWUADmtQb29sQm9vc3RDb2VmAgtfYm9vc3RfY29lZgARa0Zhcm1MYXN0SW50ZXJlc3QCDl9sYXN0X2ludGVyZXN0ABVrRmFybVVzZXJMYXN0SW50ZXJlc3QCDl9sYXN0X2ludGVyZXN0ABJrQm9vc3RMYXN0SW50ZXJlc3QCEF9sYXN0X2ludGVyZXN0X2IAFmtCb29zdFVzZXJMYXN0SW50ZXJlc3QCEl9sYXN0X2ludGVyZXN0X3VfYgAUa0Jvb3N0TFBMYXN0SW50ZXJlc3QCEl9sYXN0X2ludGVyZXN0X2xwYgAYa0Jvb3N0TFBVc2VyTGFzdEludGVyZXN0AhRfbGFzdF9pbnRlcmVzdF91X2xwYgATa0xhc3RJbnRlcmVzdEhlaWdodAIVX2xhc3RfaW50ZXJlc3RfaGVpZ2h0AAdrU1dPUGlkAgdTV09QX2lkAA5rQXZhaWxhYmxlU1dPUAIPX2F2YWlsYWJsZV9TV09QABFrU3dvcFllYXJFbWlzc2lvbgISc3dvcF95ZWFyX2VtaXNzaW9uABBrSGFydmVzdFBvb2xWb3RlAhhfaGFydmVzdF9wb29sX3ZvdGVfZ1NXT1AACWtQb29sVm90ZQIQX3Bvb2xfdm90ZV9nU1dPUAANa1VzZXJQb29sVm90ZQIQX3VzZXJfdm90ZV9nU1dPUAAUa0hhcnZlc3RVc2VyUG9vbFZvdGUCHV9oYXJ2ZXN0X3VzZXJfcG9vbF92b3RlX2dTV09QAAtrQmFzZVBlcmlvZAILYmFzZV9wZXJpb2QADWtQZXJpb2RMZW5ndGgCDXBlcmlvZF9sZW5ndGgADGtTdGFydEhlaWdodAIMc3RhcnRfaGVpZ2h0ABNrRmlyc3RIYXJ2ZXN0SGVpZ2h0AhRmaXJzdF9oYXJ2ZXN0X2hlaWdodAANa1NoYXJlTGltaXRGSAIcc2hhcmVfbGltaXRfb25fZmlyc3RfaGFydmVzdAANa0FkbWluUHViS2V5MQILYWRtaW5fcHViXzEADWtBZG1pblB1YktleTICC2FkbWluX3B1Yl8yAA1rQWRtaW5QdWJLZXkzAgthZG1pbl9wdWJfMwASa0FkbWluSW52b2tlUHViS2V5AhBhZG1pbl9pbnZva2VfcHViABBrTW9uZXlCb3hBZGRyZXNzAhFtb25leV9ib3hfYWRkcmVzcwAOa1ZvdGluZ0FkZHJlc3MCDnZvdGluZ19hZGRyZXNzAAtrR292QWRkcmVzcwISZ292ZXJuYW5jZV9hZGRyZXNzABFrTFBGYXJtaW5nQWRkcmVzcwIKbHBfZmFybWluZwAUa0Zhcm1pbmdUcmVhc3VyZUFkZHICEGZhcm1pbmdfdHJlYXN1cmUABm9yYWNsZQkBB0FkZHJlc3MBARoBVEgTlwzA0zPMJTKAtin3p2RogKvjzHtLmQAOdG90YWxWb3RlU2hhcmUAgMivoCUAC3NjYWxlVmFsdWU4AIDC1y8AEmxvY2tCb29zdENvZWZTY2FsZQDoBwAQZGVmUG9vbEJvb3N0Q29lZgD0AwETZ2V0QmFzZTU4RnJvbU9yYWNsZQEDa2V5BAckbWF0Y2gwCQCdCAIFBm9yYWNsZQUDa2V5AwkAAQIFByRtYXRjaDACBlN0cmluZwQGc3RyaW5nBQckbWF0Y2gwCQDZBAEFBnN0cmluZwQHbm90aGluZwUHJG1hdGNoMAkAAgEJAKwCAgUDa2V5AghpcyBlbXB0eQAMYWRtaW5QdWJLZXkxCQETZ2V0QmFzZTU4RnJvbU9yYWNsZQEFDWtBZG1pblB1YktleTEADGFkbWluUHViS2V5MgkBE2dldEJhc2U1OEZyb21PcmFjbGUBBQ1rQWRtaW5QdWJLZXkyAAxhZG1pblB1YktleTMJARNnZXRCYXNlNThGcm9tT3JhY2xlAQUNa0FkbWluUHViS2V5MwAPbW9uZXlCb3hBZGRyZXNzCQEHQWRkcmVzcwEJARNnZXRCYXNlNThGcm9tT3JhY2xlAQUQa01vbmV5Qm94QWRkcmVzcwANdm90aW5nQWRkcmVzcwkBB0FkZHJlc3MBCQETZ2V0QmFzZTU4RnJvbU9yYWNsZQEFDmtWb3RpbmdBZGRyZXNzAApnb3ZBZGRyZXNzCQEHQWRkcmVzcwEJARNnZXRCYXNlNThGcm9tT3JhY2xlAQULa0dvdkFkZHJlc3MAEWFkbWluSW52b2tlUHViS2V5CQETZ2V0QmFzZTU4RnJvbU9yYWNsZQEFEmtBZG1pbkludm9rZVB1YktleQAQbHBGYXJtaW5nQWRkcmVzcwkBB0FkZHJlc3MBCQETZ2V0QmFzZTU4RnJvbU9yYWNsZQEFEWtMUEZhcm1pbmdBZGRyZXNzABNmYXJtaW5nVHJlYXN1cmVBZGRyCQEHQWRkcmVzcwEJARNnZXRCYXNlNThGcm9tT3JhY2xlAQUUa0Zhcm1pbmdUcmVhc3VyZUFkZHIACmJhc2VQZXJpb2QJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQ12b3RpbmdBZGRyZXNzBQtrQmFzZVBlcmlvZAIRRW1wdHkga0Jhc2VQZXJpb2QAC3N0YXJ0SGVpZ2h0CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUNdm90aW5nQWRkcmVzcwUMa1N0YXJ0SGVpZ2h0AhJFbXB0eSBrU3RhcnRIZWlnaHQADHBlcmlvZExlbmd0aAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFDXZvdGluZ0FkZHJlc3MFDWtQZXJpb2RMZW5ndGgCE0VtcHR5IGtQZXJpb2RMZW5ndGgACmN1cnJQZXJpb2QJAGQCBQpiYXNlUGVyaW9kCQBpAgkAZQIFBmhlaWdodAULc3RhcnRIZWlnaHQFDHBlcmlvZExlbmd0aAAGYWN0aXZlCQERQGV4dHJOYXRpdmUoMTA1MSkCBQR0aGlzBQdrQWN0aXZlAAphY3RpdmVHbG9iCQELdmFsdWVPckVsc2UCCQCbCAIFBm9yYWNsZQULa0FjdGl2ZUdsb2IGABBTd29wWWVhckVtaXNzaW9uCQERQGV4dHJOYXRpdmUoMTA1MCkCBQR0aGlzBRFrU3dvcFllYXJFbWlzc2lvbgAEU1dPUAkA2QQBCQERQGV4dHJOYXRpdmUoMTA1MykCBQR0aGlzBQdrU1dPUGlkARVnZXRIZWlnaHRGaXJzdEhhcnZlc3QBBHBvb2wJAQt2YWx1ZU9yRWxzZQIJAJoIAgkBB0FkZHJlc3MBCQDZBAEFBHBvb2wFE2tGaXJzdEhhcnZlc3RIZWlnaHQAAAEUZ2V0RkhTaGFyZUxpbWl0VG9rZW4BBHBvb2wJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQRwb29sBQ1rU2hhcmVMaW1pdEZICQCsAgICFE5vIGRhdGEgb24gdGhlIGtleTogBQ1rU2hhcmVMaW1pdEZIARJnZXRUb3RhbFNoYXJlVG9rZW4BBHBvb2wJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQR0aGlzCQCsAgIFBHBvb2wFFmtTaGFyZVRvdGFsU2hhcmVUb2tlbnMJAKwCAgkArAICAhRObyBkYXRhIG9uIHRoZSBrZXk6IAUEcG9vbAUWa1NoYXJlVG90YWxTaGFyZVRva2VucwEMZ2V0UG9vbFZvdGVkAQRwb29sCQELdmFsdWVPckVsc2UCCQCaCAIFDXZvdGluZ0FkZHJlc3MJAKwCAgUEcG9vbAUJa1Bvb2xWb3RlAAABEGdldFVzZXJQb29sVm90ZWQCBHBvb2wEdXNlcgkBC3ZhbHVlT3JFbHNlAgkAmggCBQ12b3RpbmdBZGRyZXNzCQCsAgIJAKwCAgkArAICBQR1c2VyAgFfBQRwb29sBQlrUG9vbFZvdGUAAAEPZ2V0U2hhcmVBc3NldElkAQRwb29sCQDZBAEJARFAZXh0ck5hdGl2ZSgxMDUzKQIJAQV2YWx1ZQEJAKYIAQUEcG9vbAIOc2hhcmVfYXNzZXRfaWQBDmFjY291bnRCYWxhbmNlAQdhc3NldElkBAckbWF0Y2gwBQdhc3NldElkAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAmlkBQckbWF0Y2gwCQDwBwIFBHRoaXMFAmlkAwkAAQIFByRtYXRjaDACBFVuaXQEBXdhdmVzBQckbWF0Y2gwCAkA7wcBBQR0aGlzCWF2YWlsYWJsZQkAAgECC01hdGNoIGVycm9yAQxnZXRBc3NldEluZm8BB2Fzc2V0SWQEByRtYXRjaDAFB2Fzc2V0SWQDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQCaWQFByRtYXRjaDAECHN0cmluZ0lkCQDYBAEFAmlkBARpbmZvCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCaWQJAKwCAgkArAICAgZBc3NldCAFCHN0cmluZ0lkAg4gZG9lc24ndCBleGlzdAkAlQoDBQhzdHJpbmdJZAgFBGluZm8EbmFtZQgFBGluZm8IZGVjaW1hbHMDCQABAgUHJG1hdGNoMAIEVW5pdAQFd2F2ZXMFByRtYXRjaDAJAJUKAwIFV0FWRVMCBVdBVkVTAAgJAAIBAgtNYXRjaCBlcnJvcgEOY2FsY1NjYWxlVmFsdWUCCGFzc2V0SWQxCGFzc2V0SWQyBBBhc3NldElkMURlY2ltYWxzCAkBBXZhbHVlAQkA7AcBBQhhc3NldElkMQhkZWNpbWFscwQQYXNzZXRJZDJEZWNpbWFscwgJAQV2YWx1ZQEJAOwHAQUIYXNzZXRJZDIIZGVjaW1hbHMEC3NjYWxlRGlnaXRzCQBkAgkAZQIFEGFzc2V0SWQyRGVjaW1hbHMFEGFzc2V0SWQxRGVjaW1hbHMACAkAbAYACgAABQtzY2FsZURpZ2l0cwAAAAAFBERPV04BEXVzZXJBdmFpbGFibGVTV09QAgRwb29sBHVzZXIJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwkApQgBBQR1c2VyBQ5rQXZhaWxhYmxlU1dPUAAAAQpyZXdhcmRJbmZvAQRwb29sBBp0b3RhbFJld2FyZFBlckJsb2NrQ3VycmVudAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFCmdvdkFkZHJlc3MFG2tUb3RhbFJld2FyZFBlckJsb2NrQ3VycmVudAkArAICCQCsAgIJAKwCAgIUTm8gZGF0YSBvbiB0aGUga2V5OiAFG2tUb3RhbFJld2FyZFBlckJsb2NrQ3VycmVudAIMIGF0IGFkZHJlc3MgCQClCAEFCmdvdkFkZHJlc3MEG3RvdGFsUmV3YXJkUGVyQmxvY2tQcmV2aW91cwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFCmdvdkFkZHJlc3MFHGtUb3RhbFJld2FyZFBlckJsb2NrUHJldmlvdXMJAKwCAgkArAICCQCsAgICFE5vIGRhdGEgb24gdGhlIGtleTogBRxrVG90YWxSZXdhcmRQZXJCbG9ja1ByZXZpb3VzAgwgYXQgYWRkcmVzcyAJAKUIAQUKZ292QWRkcmVzcwQZcmV3YXJkUG9vbEZyYWN0aW9uQ3VycmVudAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFCmdvdkFkZHJlc3MJAKwCAgUEcG9vbAUaa1Jld2FyZFBvb2xGcmFjdGlvbkN1cnJlbnQJAKwCAgkArAICCQCsAgIJAKwCAgIUTm8gZGF0YSBvbiB0aGUga2V5OiAFBHBvb2wFGmtSZXdhcmRQb29sRnJhY3Rpb25DdXJyZW50AgwgYXQgYWRkcmVzcyAJAKUIAQUKZ292QWRkcmVzcwQScmV3YXJkVXBkYXRlSGVpZ2h0CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUKZ292QWRkcmVzcwUTa1Jld2FyZFVwZGF0ZUhlaWdodAkArAICCQCsAgIJAKwCAgIUTm8gZGF0YSBvbiB0aGUga2V5OiAFE2tSZXdhcmRVcGRhdGVIZWlnaHQCDCBhdCBhZGRyZXNzIAkApQgBBQpnb3ZBZGRyZXNzBBZwb29sUmV3YXJkVXBkYXRlSGVpZ2h0CQELdmFsdWVPckVsc2UCCQCaCAIFCmdvdkFkZHJlc3MJAKwCAgUEcG9vbAUTa0hlaWdodFBvb2xGcmFjdGlvbgUScmV3YXJkVXBkYXRlSGVpZ2h0BBpyZXdhcmRQb29sRnJhY3Rpb25QcmV2aW91cwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFCmdvdkFkZHJlc3MJAKwCAgUEcG9vbAUba1Jld2FyZFBvb2xGcmFjdGlvblByZXZpb3VzCQCsAgIJAKwCAgkArAICCQCsAgICFE5vIGRhdGEgb24gdGhlIGtleTogBQRwb29sBRtrUmV3YXJkUG9vbEZyYWN0aW9uUHJldmlvdXMCDCBhdCBhZGRyZXNzIAkApQgBBQpnb3ZBZGRyZXNzBBFyZXdhcmRQb29sQ3VycmVudAkAawMFGnRvdGFsUmV3YXJkUGVyQmxvY2tDdXJyZW50BRlyZXdhcmRQb29sRnJhY3Rpb25DdXJyZW50BQ50b3RhbFZvdGVTaGFyZQQScmV3YXJkUG9vbFByZXZpb3VzCQBrAwUadG90YWxSZXdhcmRQZXJCbG9ja0N1cnJlbnQFGnJld2FyZFBvb2xGcmFjdGlvblByZXZpb3VzBQ50b3RhbFZvdGVTaGFyZQMDCQBmAgURcmV3YXJkUG9vbEN1cnJlbnQFGnRvdGFsUmV3YXJkUGVyQmxvY2tDdXJyZW50BgkAZgIFEnJld2FyZFBvb2xQcmV2aW91cwUbdG90YWxSZXdhcmRQZXJCbG9ja1ByZXZpb3VzCQACAQJicmV3YXJkUG9vbEN1cnJlbnQgPiB0b3RhbFJld2FyZFBlckJsb2NrQ3VycmVudCBvciByZXdhcmRQb29sUHJldmlvdXMgPiB0b3RhbFJld2FyZFBlckJsb2NrUHJldmlvdXMJAJYKBAURcmV3YXJkUG9vbEN1cnJlbnQFEnJld2FyZFVwZGF0ZUhlaWdodAUScmV3YXJkUG9vbFByZXZpb3VzBRZwb29sUmV3YXJkVXBkYXRlSGVpZ2h0ARNnZXRMYXN0SW50ZXJlc3RJbmZvAQRwb29sBAxmYXJtSW50ZXJlc3QJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQR0aGlzCQCsAgIFBHBvb2wFEWtGYXJtTGFzdEludGVyZXN0CQCsAgIJAKwCAgIUTm8gZGF0YSBvbiB0aGUga2V5OiAFBHBvb2wFEWtGYXJtTGFzdEludGVyZXN0BA1ib29zdEludGVyZXN0CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUEdGhpcwkArAICBQRwb29sBRFrRmFybUxhc3RJbnRlcmVzdAkArAICCQCsAgICFE5vIGRhdGEgb24gdGhlIGtleTogBQRwb29sBRJrQm9vc3RMYXN0SW50ZXJlc3QED2Jvb3N0TFBJbnRlcmVzdAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFBHRoaXMJAKwCAgUEcG9vbAURa0Zhcm1MYXN0SW50ZXJlc3QJAKwCAgkArAICAhRObyBkYXRhIG9uIHRoZSBrZXk6IAUEcG9vbAUUa0Jvb3N0TFBMYXN0SW50ZXJlc3QEEmxhc3RJbnRlcmVzdEhlaWdodAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQCsAgIFBHBvb2wFE2tMYXN0SW50ZXJlc3RIZWlnaHQFBmhlaWdodAkAlgoEBRJsYXN0SW50ZXJlc3RIZWlnaHQFDGZhcm1JbnRlcmVzdAUNYm9vc3RJbnRlcmVzdAUPYm9vc3RMUEludGVyZXN0AQtjYWxjRmFybVJ3ZAIEcG9vbA5jdXJUb3RhbFJld2FyZAQNcG9vbEJvb3N0Q29lZgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQCsAgIFBHBvb2wFDmtQb29sQm9vc3RDb2VmBRBkZWZQb29sQm9vc3RDb2VmCQBpAgkAaQIFDmN1clRvdGFsUmV3YXJkCQBkAgUNcG9vbEJvb3N0Q29lZgDoBwUSbG9ja0Jvb3N0Q29lZlNjYWxlAQxjYWxjQm9vc3RSd2QCBHBvb2wOY3VyVG90YWxSZXdhcmQEDXBvb2xCb29zdENvZWYJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkArAICBQRwb29sBQ5rUG9vbEJvb3N0Q29lZgUQZGVmUG9vbEJvb3N0Q29lZgkAaQIJAGsDBQ5jdXJUb3RhbFJld2FyZAUNcG9vbEJvb3N0Q29lZgkAZAIFDXBvb2xCb29zdENvZWYA6AcFEmxvY2tCb29zdENvZWZTY2FsZQEMY2FsY0ludGVyZXN0DARwb29sEmxhc3RJbnRlcmVzdEhlaWdodBJyZXdhcmRVcGRhdGVIZWlnaHQWcG9vbFJld2FyZFVwZGF0ZUhlaWdodAxmYXJtSW50ZXJlc3QNYm9vc3RJbnRlcmVzdAlwb29sVm90ZWQPYm9vc3RMcEludGVyZXN0FWN1cnJlbnRSZXdhcmRQZXJCbG9jaxBzaGFyZVRva2VuTG9ja2VkFnByZXZpb3VzUmV3YXJkUGVyQmxvY2sKc2NhbGVWYWx1ZQMJAAACBRBzaGFyZVRva2VuTG9ja2VkAAAJAJUKAwAAAAAAAAMDCQBmAgUScmV3YXJkVXBkYXRlSGVpZ2h0BQZoZWlnaHQJAAACBRJyZXdhcmRVcGRhdGVIZWlnaHQFFnBvb2xSZXdhcmRVcGRhdGVIZWlnaHQHBAZyZXdhcmQJAGgCBRZwcmV2aW91c1Jld2FyZFBlckJsb2NrCQBlAgUGaGVpZ2h0BRJsYXN0SW50ZXJlc3RIZWlnaHQED25ld0Zhcm1JbnRlcmVzdAkAZAIFDGZhcm1JbnRlcmVzdAkAawMJAQtjYWxjRmFybVJ3ZAIFBHBvb2wFBnJld2FyZAUKc2NhbGVWYWx1ZQUQc2hhcmVUb2tlbkxvY2tlZAQQbmV3Qm9vc3RJbnRlcmVzdAkAZAIFDWJvb3N0SW50ZXJlc3QDCQBmAgUJcG9vbFZvdGVkAAAJAGsDCQEMY2FsY0Jvb3N0UndkAgUEcG9vbAUGcmV3YXJkBQtzY2FsZVZhbHVlOAUJcG9vbFZvdGVkAAAEEm5ld0Jvb3N0TFBJbnRlcmVzdAkAZAIFD2Jvb3N0THBJbnRlcmVzdAMDCQBmAgUJcG9vbFZvdGVkAAAJAGYCBRBzaGFyZVRva2VuTG9ja2VkAAAHCQBrAwkAawMJAQxjYWxjQm9vc3RSd2QCBQRwb29sBQZyZXdhcmQFC3NjYWxlVmFsdWU4BRBzaGFyZVRva2VuTG9ja2VkBQtzY2FsZVZhbHVlOAUJcG9vbFZvdGVkAAAJAJUKAwUPbmV3RmFybUludGVyZXN0BRBuZXdCb29zdEludGVyZXN0BRJuZXdCb29zdExQSW50ZXJlc3QDAwkAZgIFBmhlaWdodAUScmV3YXJkVXBkYXRlSGVpZ2h0CQECIT0CBRJyZXdhcmRVcGRhdGVIZWlnaHQFFnBvb2xSZXdhcmRVcGRhdGVIZWlnaHQHBAZyZXdhcmQJAGgCBRZwcmV2aW91c1Jld2FyZFBlckJsb2NrCQBlAgUGaGVpZ2h0BRJsYXN0SW50ZXJlc3RIZWlnaHQED25ld0Zhcm1JbnRlcmVzdAkAZAIFDGZhcm1JbnRlcmVzdAkAawMJAQtjYWxjRmFybVJ3ZAIFBHBvb2wFBnJld2FyZAUKc2NhbGVWYWx1ZQUQc2hhcmVUb2tlbkxvY2tlZAQQbmV3Qm9vc3RJbnRlcmVzdAkAZAIFDWJvb3N0SW50ZXJlc3QDCQBmAgUJcG9vbFZvdGVkAAAJAGsDCQEMY2FsY0Jvb3N0UndkAgUEcG9vbAUGcmV3YXJkBQtzY2FsZVZhbHVlOAUJcG9vbFZvdGVkAAAEEm5ld0Jvb3N0TFBJbnRlcmVzdAkAZAIFD2Jvb3N0THBJbnRlcmVzdAMDCQBmAgUJcG9vbFZvdGVkAAAJAGYCBRBzaGFyZVRva2VuTG9ja2VkAAAHCQBrAwkAawMJAQxjYWxjQm9vc3RSd2QCBQRwb29sBQZyZXdhcmQFC3NjYWxlVmFsdWU4BRBzaGFyZVRva2VuTG9ja2VkBQtzY2FsZVZhbHVlOAUJcG9vbFZvdGVkAAAJAJUKAwUPbmV3RmFybUludGVyZXN0BRBuZXdCb29zdEludGVyZXN0BRJuZXdCb29zdExQSW50ZXJlc3QDAwMJAGYCBQZoZWlnaHQFEnJld2FyZFVwZGF0ZUhlaWdodAkAAAIFEnJld2FyZFVwZGF0ZUhlaWdodAUWcG9vbFJld2FyZFVwZGF0ZUhlaWdodAcJAGYCBRJsYXN0SW50ZXJlc3RIZWlnaHQFEnJld2FyZFVwZGF0ZUhlaWdodAcEBnJld2FyZAkAaAIFFWN1cnJlbnRSZXdhcmRQZXJCbG9jawkAZQIFBmhlaWdodAUSbGFzdEludGVyZXN0SGVpZ2h0BA9uZXdGYXJtSW50ZXJlc3QJAGQCBQxmYXJtSW50ZXJlc3QJAGsDCQELY2FsY0Zhcm1Sd2QCBQRwb29sBQZyZXdhcmQFCnNjYWxlVmFsdWUFEHNoYXJlVG9rZW5Mb2NrZWQEEG5ld0Jvb3N0SW50ZXJlc3QJAGQCBQ1ib29zdEludGVyZXN0AwkAZgIFCXBvb2xWb3RlZAAACQBrAwkBDGNhbGNCb29zdFJ3ZAIFBHBvb2wFBnJld2FyZAULc2NhbGVWYWx1ZTgFCXBvb2xWb3RlZAAABBJuZXdCb29zdExQSW50ZXJlc3QJAGQCBQ9ib29zdExwSW50ZXJlc3QDAwkAZgIFCXBvb2xWb3RlZAAACQBmAgUQc2hhcmVUb2tlbkxvY2tlZAAABwkAawMJAGsDCQEMY2FsY0Jvb3N0UndkAgUEcG9vbAUGcmV3YXJkBQtzY2FsZVZhbHVlOAUQc2hhcmVUb2tlbkxvY2tlZAULc2NhbGVWYWx1ZTgFCXBvb2xWb3RlZAAACQCVCgMFD25ld0Zhcm1JbnRlcmVzdAUQbmV3Qm9vc3RJbnRlcmVzdAUSbmV3Qm9vc3RMUEludGVyZXN0BAlyd2RCZnJVcGQJAGgCBRZwcmV2aW91c1Jld2FyZFBlckJsb2NrCQBlAgUScmV3YXJkVXBkYXRlSGVpZ2h0BRJsYXN0SW50ZXJlc3RIZWlnaHQEDmZyYW1JbnRyQWZ0clVwCQBkAgUMZmFybUludGVyZXN0CQBrAwkBC2NhbGNGYXJtUndkAgUEcG9vbAUJcndkQmZyVXBkBQpzY2FsZVZhbHVlBRBzaGFyZVRva2VuTG9ja2VkBA9ib29zdEludHJBZnRyVXAJAGQCBQ1ib29zdEludGVyZXN0AwkAZgIFCXBvb2xWb3RlZAAACQBrAwkBDGNhbGNCb29zdFJ3ZAIFBHBvb2wFCXJ3ZEJmclVwZAUKc2NhbGVWYWx1ZQUJcG9vbFZvdGVkAAAEEGJvc3RMUEludHJBZnRyVXAJAGQCBQxmYXJtSW50ZXJlc3QDAwkAZgIFCXBvb2xWb3RlZAAACQBmAgUQc2hhcmVUb2tlbkxvY2tlZAAABwkAawMJAQxjYWxjQm9vc3RSd2QCBQRwb29sBQlyd2RCZnJVcGQFCnNjYWxlVmFsdWUFCXBvb2xWb3RlZAAABAZyZXdhcmQJAGgCBRVjdXJyZW50UmV3YXJkUGVyQmxvY2sJAGUCBQZoZWlnaHQFEnJld2FyZFVwZGF0ZUhlaWdodAQPbmV3RmFybUludGVyZXN0CQBkAgUOZnJhbUludHJBZnRyVXAJAGsDCQELY2FsY0Zhcm1Sd2QCBQRwb29sBQZyZXdhcmQFCnNjYWxlVmFsdWUFEHNoYXJlVG9rZW5Mb2NrZWQEEG5ld0Jvb3N0SW50ZXJlc3QJAGQCBQ9ib29zdEludHJBZnRyVXADCQBmAgUJcG9vbFZvdGVkAAAJAGsDCQEMY2FsY0Jvb3N0UndkAgUEcG9vbAUGcmV3YXJkBQtzY2FsZVZhbHVlOAUJcG9vbFZvdGVkAAAEEm5ld0Jvb3N0TFBJbnRlcmVzdAkAZAIFEGJvc3RMUEludHJBZnRyVXADAwkAZgIFCXBvb2xWb3RlZAAACQBmAgUQc2hhcmVUb2tlbkxvY2tlZAAABwkAawMJAGsDCQEMY2FsY0Jvb3N0UndkAgUEcG9vbAUGcmV3YXJkBQtzY2FsZVZhbHVlOAUQc2hhcmVUb2tlbkxvY2tlZAULc2NhbGVWYWx1ZTgFCXBvb2xWb3RlZAAACQCVCgMFD25ld0Zhcm1JbnRlcmVzdAUQbmV3Qm9vc3RJbnRlcmVzdAUSbmV3Qm9vc3RMUEludGVyZXN0AQljbGFpbUNhbGMCBHBvb2wEdXNlcgQKc2NhbGVWYWx1ZQkBDmNhbGNTY2FsZVZhbHVlAgUEU1dPUAkBD2dldFNoYXJlQXNzZXRJZAEFBHBvb2wECXBvb2xWb3RlZAkBDGdldFBvb2xWb3RlZAEFBHBvb2wECnVQb29sVm90ZWQJARBnZXRVc2VyUG9vbFZvdGVkAgUEcG9vbAUEdXNlcgQKc2hhcmVUb2tlbgkBEmdldFRvdGFsU2hhcmVUb2tlbgEFBHBvb2wEEXRvdGFsU2hhcmVWaXJ0dWFsCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAKwCAgUEcG9vbAUTa1NoYXJlVG9rZW5zVmlydHVhbAUKc2hhcmVUb2tlbgQNJHQwMTQ0MDYxNDUwNAkBE2dldExhc3RJbnRlcmVzdEluZm8BBQRwb29sBBJsYXN0SW50ZXJlc3RIZWlnaHQIBQ0kdDAxNDQwNjE0NTA0Al8xBAxmYXJtSW50ZXJlc3QIBQ0kdDAxNDQwNjE0NTA0Al8yBA1ib29zdEludGVyZXN0CAUNJHQwMTQ0MDYxNDUwNAJfMwQPYm9vc3RMUEludGVyZXN0CAUNJHQwMTQ0MDYxNDUwNAJfNAQNJHQwMTQ1MDkxNDYyMwkBCnJld2FyZEluZm8BBQRwb29sBBVjdXJyZW50UmV3YXJkUGVyQmxvY2sIBQ0kdDAxNDUwOTE0NjIzAl8xBBJyZXdhcmRVcGRhdGVIZWlnaHQIBQ0kdDAxNDUwOTE0NjIzAl8yBBZwcmV2aW91c1Jld2FyZFBlckJsb2NrCAUNJHQwMTQ1MDkxNDYyMwJfMwQWcG9vbFJld2FyZFVwZGF0ZUhlaWdodAgFDSR0MDE0NTA5MTQ2MjMCXzQEDXVGYXJtSW50ZXJlc3QJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgUVa0Zhcm1Vc2VyTGFzdEludGVyZXN0BQxmYXJtSW50ZXJlc3QEDnVCb29zdEludGVyZXN0CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXIFFmtCb29zdFVzZXJMYXN0SW50ZXJlc3QFDWJvb3N0SW50ZXJlc3QEEHVCb29zdExQSW50ZXJlc3QJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgUYa0Jvb3N0TFBVc2VyTGFzdEludGVyZXN0BQ9ib29zdExQSW50ZXJlc3QEEnVTaGFyZVRva2Vuc1N0YWtlZAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyBRZrVXNlclNoYXJlVG9rZW5zU3Rha2VkAAAEEHVTaGFyZVRva2Vuc1ZpcnQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgUXa1VzZXJTaGFyZVRva2Vuc1ZpcnR1YWwFEnVTaGFyZVRva2Vuc1N0YWtlZAQNJHQwMTUxOTExNTU4NAkBDGNhbGNJbnRlcmVzdAwFBHBvb2wFEmxhc3RJbnRlcmVzdEhlaWdodAUScmV3YXJkVXBkYXRlSGVpZ2h0BRZwb29sUmV3YXJkVXBkYXRlSGVpZ2h0BQxmYXJtSW50ZXJlc3QFDWJvb3N0SW50ZXJlc3QFCXBvb2xWb3RlZAUPYm9vc3RMUEludGVyZXN0BRVjdXJyZW50UmV3YXJkUGVyQmxvY2sFEXRvdGFsU2hhcmVWaXJ0dWFsBRZwcmV2aW91c1Jld2FyZFBlckJsb2NrBQpzY2FsZVZhbHVlBA9uZXdGYXJtSW50ZXJlc3QIBQ0kdDAxNTE5MTE1NTg0Al8xBBBuZXdCb29zdEludGVyZXN0CAUNJHQwMTUxOTExNTU4NAJfMgQSbmV3Qm9vc3RMUEludGVyZXN0CAUNJHQwMTUxOTExNTU4NAJfMwQMY2xhaW1GYXJtaW5nCQBrAwUQdVNoYXJlVG9rZW5zVmlydAkAZQIFD25ld0Zhcm1JbnRlcmVzdAUNdUZhcm1JbnRlcmVzdAUKc2NhbGVWYWx1ZQQQY2xhaW1Cb29zdGluZ01heAkAawMFCnVQb29sVm90ZWQJAGUCBRBuZXdCb29zdEludGVyZXN0BQ51Qm9vc3RJbnRlcmVzdAULc2NhbGVWYWx1ZTgEDWNsYWltQm9vc3RpbmcJAGkCCQBrAwkAaAIFEHVTaGFyZVRva2Vuc1ZpcnQFCnVQb29sVm90ZWQJAGUCBRJuZXdCb29zdExQSW50ZXJlc3QFEHVCb29zdExQSW50ZXJlc3QFC3NjYWxlVmFsdWU4BQtzY2FsZVZhbHVlOAQKdG9UcmVhc3VyeQkAZQIFEGNsYWltQm9vc3RpbmdNYXgFDWNsYWltQm9vc3RpbmcJAJcKBQUPbmV3RmFybUludGVyZXN0BRBuZXdCb29zdEludGVyZXN0BRJuZXdCb29zdExQSW50ZXJlc3QJAGQCBQxjbGFpbUZhcm1pbmcFDWNsYWltQm9vc3RpbmcFCnRvVHJlYXN1cnkBFWNhbkxvY2tJbkZpcnN0SGFydmVzdAUEcG9vbAR1c2VyFXVzZXJTaGFyZVRva2Vuc1N0YWtlZAlwbXRBbW91bnQIbG9ja1R5cGUDCQBmAgkBFWdldEhlaWdodEZpcnN0SGFydmVzdAEFBHBvb2wFBmhlaWdodAQPdG90YWxWb3RlQW1vdW50CQELdmFsdWVPckVsc2UCCQCaCAIFDXZvdGluZ0FkZHJlc3MJAKwCAgUEcG9vbAUQa0hhcnZlc3RQb29sVm90ZQAABA51c2VyVm90ZUFtb3VudAkBC3ZhbHVlT3JFbHNlAgkAmggCBQ12b3RpbmdBZGRyZXNzCQCsAgIJAKwCAgkArAICBQR1c2VyAgFfBQRwb29sBRBrSGFydmVzdFBvb2xWb3RlAAAEEUZIU2hhcmVUb2tlbkxpbWl0CQEUZ2V0RkhTaGFyZUxpbWl0VG9rZW4BCQERQGV4dHJOYXRpdmUoMTA2MikBBQRwb29sBBVGSFNoYXJlVG9rZW5Vc2VyTGltaXQJAGUCCQBrAwURRkhTaGFyZVRva2VuTGltaXQFDnVzZXJWb3RlQW1vdW50BQ90b3RhbFZvdGVBbW91bnQFFXVzZXJTaGFyZVRva2Vuc1N0YWtlZAMJAGYCBQhsb2NrVHlwZQAACQACAQIyWW91IGNhbid0IGxvY2sgc2hhcmVUb2tlbnMgdGlsbCBmaXJzdCBoYXJ2ZXN0IGVuZC4DCQAAAgUOdXNlclZvdGVBbW91bnQAAAAAAwkAZwIFCXBtdEFtb3VudAUVRkhTaGFyZVRva2VuVXNlckxpbWl0CQBlAgUJcG10QW1vdW50BRVGSFNoYXJlVG9rZW5Vc2VyTGltaXQAAAAAAQ1nZXRMb2NrUGFyYW1zAQR0eXBlBApsb2NrUGFyYW1zCQC1CQIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQR0aGlzCQCsAgIJAKQDAQUEdHlwZQULa0xvY2tQYXJhbXMJAKwCAgIeVGhlcmUgYXJlIG5vIGtleSBmb3IgbG9jayB0eXBlCQCkAwEFBHR5cGUCAV8JAJQKAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCmxvY2tQYXJhbXMAAAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCmxvY2tQYXJhbXMAAQEHc3VzcGVuZAEFY2F1c2UJAMwIAgkBDEJvb2xlYW5FbnRyeQIFB2tBY3RpdmUHCQDMCAIJAQtTdHJpbmdFbnRyeQIFBmtDYXVzZQUFY2F1c2UFA25pbAEIaXNBY3RpdmUAAwMFBmFjdGl2ZQUKYWN0aXZlR2xvYgcFBHVuaXQJAAIBAh9EQXBwIGlzIGluYWN0aXZlIGF0IHRoaXMgbW9tZW50AQtpc0FkbWluQ2FsbAEBaQMJAQ9jb250YWluc0VsZW1lbnQCCQDMCAIFDGFkbWluUHViS2V5MQkAzAgCBQxhZG1pblB1YktleTIJAMwIAgUMYWRtaW5QdWJLZXkzBQNuaWwIBQFpD2NhbGxlclB1YmxpY0tleQUEdW5pdAkAAgECIU9ubHkgYWRtaW4gY2FuIGNhbGwgdGhpcyBmdW5jdGlvbg4BaQEEaW5pdAEHZWFybHlMUAMJAQlpc0RlZmluZWQBCQCdCAIFBHRoaXMFB2tTV09QaWQJAAIBAhhTV09QIGFscmVhZHkgaW5pdGlhbGl6ZWQECmluaXRBbW91bnQAgIDpg7HeFgQJU1dPUGlzc3VlCQDCCAUCBFNXT1ACE1NXT1AgcHJvdG9jb2wgdG9rZW4FCmluaXRBbW91bnQACAYEBlNXT1BpZAkAuAgBBQlTV09QaXNzdWUJAMwIAgkBDEJvb2xlYW5FbnRyeQIFB2tBY3RpdmUGCQDMCAIJAMIIBQIEU1dPUAITU1dPUCBwcm90b2NvbCB0b2tlbgUKaW5pdEFtb3VudAAIBgkAzAgCCQELU3RyaW5nRW50cnkCBQdrU1dPUGlkCQDYBAEFBlNXT1BpZAUDbmlsAWkBFGluaXRQb29sU2hhcmVGYXJtaW5nAQRwb29sCQELdmFsdWVPckVsc2UCCQELaXNBZG1pbkNhbGwBBQFpCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBHBvb2wFFmtTaGFyZVRvdGFsU2hhcmVUb2tlbnMAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQRwb29sBRFrRmFybUxhc3RJbnRlcmVzdAAACQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBHBvb2wFEmtCb29zdExhc3RJbnRlcmVzdAAACQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBHBvb2wFFGtCb29zdExQTGFzdEludGVyZXN0AAAJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUEcG9vbAUTa0xhc3RJbnRlcmVzdEhlaWdodAUGaGVpZ2h0BQNuaWwBaQESdXBkYXRlUG9vbEludGVyZXN0AQRwb29sCQELdmFsdWVPckVsc2UCCQEIaXNBY3RpdmUAAwkBAiE9AggFAWkGY2FsbGVyBQpnb3ZBZGRyZXNzCQACAQImT25seSBHb3Zlcm5hbmNlIGNhbiBjYWxsIHRoaXMgZnVuY3Rpb24EBHVzZXIJAKUIAQkApwgBBRFhZG1pbkludm9rZVB1YktleQQNJHQwMTg2MTcxODY5MQkBCWNsYWltQ2FsYwIFBHBvb2wFBHVzZXIEDGZhcm1JbnRlcmVzdAgFDSR0MDE4NjE3MTg2OTECXzEEDWJvb3N0SW50ZXJlc3QIBQ0kdDAxODYxNzE4NjkxAl8yBA9ib29zdExQaW50ZXJlc3QIBQ0kdDAxODYxNzE4NjkxAl8zCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBHBvb2wFEWtGYXJtTGFzdEludGVyZXN0BQxmYXJtSW50ZXJlc3QJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUEcG9vbAUSa0Jvb3N0TGFzdEludGVyZXN0BQ1ib29zdEludGVyZXN0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBHBvb2wFFGtCb29zdExQTGFzdEludGVyZXN0BQ9ib29zdExQaW50ZXJlc3QJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUEcG9vbAUTa0xhc3RJbnRlcmVzdEhlaWdodAUGaGVpZ2h0BQNuaWwBaQEPbG9ja1NoYXJlVG9rZW5zAgRwb29sCGxvY2tUeXBlCQELdmFsdWVPckVsc2UCCQEIaXNBY3RpdmUABAxzaGFyZUFzc2V0SWQJAQ9nZXRTaGFyZUFzc2V0SWQBBQRwb29sBAR1c2VyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQKdG90YWxTaGFyZQkBEmdldFRvdGFsU2hhcmVUb2tlbgEFBHBvb2wEEXRvdGFsU2hhcmVWaXJ0dWFsCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAKwCAgUEcG9vbAUTa1NoYXJlVG9rZW5zVmlydHVhbAUKdG90YWxTaGFyZQQQdXNlclN0YWtlZEFtb3VudAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyBRZrVXNlclNoYXJlVG9rZW5zU3Rha2VkAAAED3VzZXJMb2NrZWRIZWlndAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyBRxrVXNlclNoYXJlVG9rZW5zTG9ja2VkSGVpZ2h0AAAEEHVzZXJMb2NrZWRBbW91bnQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgUWa1VzZXJTaGFyZVRva2Vuc0xvY2tlZAAABBF1c2VyQW1vdW50VmlydHVhbAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyBRdrVXNlclNoYXJlVG9rZW5zVmlydHVhbAUQdXNlclN0YWtlZEFtb3VudAQUdG90YWxVc2VyU2hhcmVUb2tlbnMJAGQCCQBkAgUQdXNlclN0YWtlZEFtb3VudAUQdXNlckxvY2tlZEFtb3VudAgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQEDSR0MDE5ODAwMTk4NTIJAQ1nZXRMb2NrUGFyYW1zAQUIbG9ja1R5cGUECmxvY2tQZXJpb2QIBQ0kdDAxOTgwMDE5ODUyAl8xBAhsb2NrQ29lZggFDSR0MDE5ODAwMTk4NTICXzIEDGxvY2tXYXZlc0ZlZQkBEUBleHRyTmF0aXZlKDEwNTApAgUEdGhpcwUNa0xvY2tXYXZlc0ZlZQMJAQIhPQIICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAUMc2hhcmVBc3NldElkCQACAQIbV3Jvbmcgc2hhcmV0b2tlbiBpbiBwYXltZW50AwkAZwIAAAgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQJAAIBAiVQYXltZW50IGFtb3VudCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwAwkAZgIAAAUIbG9ja1R5cGUJAAIBAhVsb2NrVHlwZSBtdXN0IGJlID49IDAEFXNoYXJlVG9rZW5zQ2hhbmdlT25GSAkBFWNhbkxvY2tJbkZpcnN0SGFydmVzdAUFBHBvb2wFBHVzZXIFEHVzZXJTdGFrZWRBbW91bnQICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50BQhsb2NrVHlwZQMJAAACBRVzaGFyZVRva2Vuc0NoYW5nZU9uRkgFFXNoYXJlVG9rZW5zQ2hhbmdlT25GSAQNJHQwMjAyNzkyMjEyNAMJAAACBQhsb2NrVHlwZQAABBR1c2VyQW1vdW50VmlydHVhbE5ldwkAZQIJAGQCBRF1c2VyQW1vdW50VmlydHVhbAgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQFFXNoYXJlVG9rZW5zQ2hhbmdlT25GSAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyBRZrVXNlclNoYXJlVG9rZW5zU3Rha2VkCQBlAgkAZAIFEHVzZXJTdGFrZWRBbW91bnQICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50BRVzaGFyZVRva2Vuc0NoYW5nZU9uRkgJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUEcG9vbAUTa1NoYXJlVG9rZW5zVmlydHVhbAkAZQIJAGQCBRF0b3RhbFNoYXJlVmlydHVhbAgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQFFXNoYXJlVG9rZW5zQ2hhbmdlT25GSAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQxvcmlnaW5DYWxsZXIFFXNoYXJlVG9rZW5zQ2hhbmdlT25GSAgJAJEDAggFAWkIcGF5bWVudHMAAAdhc3NldElkBQNuaWwJAGUCCQBkAgUKdG90YWxTaGFyZQgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQFFXNoYXJlVG9rZW5zQ2hhbmdlT25GSAMDCQAAAgUPdXNlckxvY2tlZEhlaWd0AAADAwkAZgIAAgkAkAMBCAUBaQhwYXltZW50cwYJAQIhPQIICQCRAwIIBQFpCHBheW1lbnRzAAEHYXNzZXRJZAUEdW5pdAYJAGYCBQxsb2NrV2F2ZXNGZWUICQCRAwIIBQFpCHBheW1lbnRzAAEGYW1vdW50BwkAAgEJAKwCAgkArAICAitZb3UgbmVlZCB0byBwYXkgYWRkaXRpb25hbCB3YXZlcyBjb21pc3Npb24gCQCkAwEFDGxvY2tXYXZlc0ZlZQIFV0FWRVMDCQBmAgUPdXNlckxvY2tlZEhlaWd0CQBkAgUGaGVpZ2h0BQpsb2NrUGVyaW9kCQACAQJPWW91IGNhbm5vdCBsb2NrIHNoYXJldG9rZW5zIGZvciBhIHBlcmlvZCBsZXNzIHRoYW4gd2hhdCB5b3UgaGF2ZSBhbHJlYWR5IGxvY2tlZAQTdXNlckxvY2tlZEFtb3VudE5ldwkAZAIFEHVzZXJMb2NrZWRBbW91bnQICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50BBJ1c2VyTG9ja2VkSGVpZ3ROZXcJAGQCBQZoZWlnaHQFCmxvY2tQZXJpb2QEFHVzZXJBbW91bnRWaXJ0dWFsTmV3CQBkAgkAawMFE3VzZXJMb2NrZWRBbW91bnROZXcFCGxvY2tDb2VmBRJsb2NrQm9vc3RDb2VmU2NhbGUFEHVzZXJTdGFrZWRBbW91bnQJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgUWa1VzZXJTaGFyZVRva2Vuc0xvY2tlZAUTdXNlckxvY2tlZEFtb3VudE5ldwkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgUca1VzZXJTaGFyZVRva2Vuc0xvY2tlZEhlaWdodAUSdXNlckxvY2tlZEhlaWd0TmV3CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyBRprVXNlclNoYXJlVG9rZW5zTG9ja2VkVHlwZQUIbG9ja1R5cGUJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXIFF2tVc2VyU2hhcmVUb2tlbnNWaXJ0dWFsBRR1c2VyQW1vdW50VmlydHVhbE5ldwkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQRwb29sBRNrU2hhcmVUb2tlbnNWaXJ0dWFsCQBkAgkAZQIFEXRvdGFsU2hhcmVWaXJ0dWFsBRF1c2VyQW1vdW50VmlydHVhbAUUdXNlckFtb3VudFZpcnR1YWxOZXcFA25pbAkAZAIFCnRvdGFsU2hhcmUICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50BAtsb2NrRW50cmllcwgFDSR0MDIwMjc5MjIxMjQCXzEEDXRvdGFsU2hhcmVOZXcIBQ0kdDAyMDI3OTIyMTI0Al8yAwkAZgIJAQ5hY2NvdW50QmFsYW5jZQEFDHNoYXJlQXNzZXRJZAUNdG90YWxTaGFyZU5ldwkAAgECMEJhbGFuY2Ugb2Ygc2hhcmUtdG9rZW4gaXMgbG93ZXIgdGhhbiB0b3RhbEFtb3VudAQNJHQwMjIyNDkyMjM0OAkBCWNsYWltQ2FsYwIFBHBvb2wFBHVzZXIEDGZhcm1JbnRlcmVzdAgFDSR0MDIyMjQ5MjIzNDgCXzEEDWJvb3N0SW50ZXJlc3QIBQ0kdDAyMjI0OTIyMzQ4Al8yBA9ib29zdExQaW50ZXJlc3QIBQ0kdDAyMjI0OTIyMzQ4Al8zBAtjbGFpbUFtb3VudAgFDSR0MDIyMjQ5MjIzNDgCXzQECnRvVHJlYXN1cmUIBQ0kdDAyMjI0OTIyMzQ4Al81BBFhdmFpbGFibGVGdW5kc05ldwkAZAIJARF1c2VyQXZhaWxhYmxlU1dPUAIFBHBvb2wIBQFpDG9yaWdpbkNhbGxlcgULY2xhaW1BbW91bnQEBHVwbHADCQAAAgkAnQgCCQEHQWRkcmVzcwEJANkEAQUEcG9vbAIHdmVyc2lvbgIFMy4wLjAJAPwHBAUQbHBGYXJtaW5nQWRkcmVzcwISdXBkYXRlVXNlckludGVyZXN0CQDMCAIFBHBvb2wJAMwIAgUUdG90YWxVc2VyU2hhcmVUb2tlbnMFA25pbAUDbmlsAAADCQAAAgUEdXBscAUEdXBscAkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyBRVrRmFybVVzZXJMYXN0SW50ZXJlc3QFDGZhcm1JbnRlcmVzdAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgUWa0Jvb3N0VXNlckxhc3RJbnRlcmVzdAUNYm9vc3RJbnRlcmVzdAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgUUa0Jvb3N0TFBMYXN0SW50ZXJlc3QFD2Jvb3N0TFBpbnRlcmVzdAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQRwb29sBRFrRmFybUxhc3RJbnRlcmVzdAUMZmFybUludGVyZXN0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBHBvb2wFEmtCb29zdExhc3RJbnRlcmVzdAUNYm9vc3RJbnRlcmVzdAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQRwb29sBRRrQm9vc3RMUExhc3RJbnRlcmVzdAUPYm9vc3RMUGludGVyZXN0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBHBvb2wFE2tMYXN0SW50ZXJlc3RIZWlnaHQFBmhlaWdodAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQRwb29sBRZrU2hhcmVUb3RhbFNoYXJlVG9rZW5zBQ10b3RhbFNoYXJlTmV3CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyBQ5rQXZhaWxhYmxlU1dPUAURYXZhaWxhYmxlRnVuZHNOZXcJAMwIAgkBB1JlaXNzdWUDBQRTV09QBQp0b1RyZWFzdXJlBgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBRNmYXJtaW5nVHJlYXN1cmVBZGRyBQp0b1RyZWFzdXJlBQRTV09QBQNuaWwFC2xvY2tFbnRyaWVzCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBFWxvY2tTdGFrZWRTaGFyZVRva2VucwMEcG9vbAhsb2NrVHlwZQpsb2NrQW1vdW50CQELdmFsdWVPckVsc2UCCQEIaXNBY3RpdmUABAxzaGFyZUFzc2V0SWQJAQ9nZXRTaGFyZUFzc2V0SWQBBQRwb29sBAR1c2VyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQKdG90YWxTaGFyZQkBEmdldFRvdGFsU2hhcmVUb2tlbgEFBHBvb2wEEXRvdGFsU2hhcmVWaXJ0dWFsCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAKwCAgUEcG9vbAUTa1NoYXJlVG9rZW5zVmlydHVhbAUKdG90YWxTaGFyZQQQdXNlclN0YWtlZEFtb3VudAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyBRZrVXNlclNoYXJlVG9rZW5zU3Rha2VkAAAED3VzZXJMb2NrZWRIZWlndAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyBRxrVXNlclNoYXJlVG9rZW5zTG9ja2VkSGVpZ2h0AAAEEHVzZXJMb2NrZWRBbW91bnQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgUWa1VzZXJTaGFyZVRva2Vuc0xvY2tlZAAABBF1c2VyQW1vdW50VmlydHVhbAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyBRdrVXNlclNoYXJlVG9rZW5zVmlydHVhbAUQdXNlclN0YWtlZEFtb3VudAQUdG90YWxVc2VyU2hhcmVUb2tlbnMJAGQCBRB1c2VyU3Rha2VkQW1vdW50BRB1c2VyTG9ja2VkQW1vdW50BA0kdDAyNDI1NjI0MzA4CQENZ2V0TG9ja1BhcmFtcwEFCGxvY2tUeXBlBApsb2NrUGVyaW9kCAUNJHQwMjQyNTYyNDMwOAJfMQQIbG9ja0NvZWYIBQ0kdDAyNDI1NjI0MzA4Al8yBAxsb2NrV2F2ZXNGZWUJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMFDWtMb2NrV2F2ZXNGZWUDCQBmAgkBFWdldEhlaWdodEZpcnN0SGFydmVzdAEFBHBvb2wFBmhlaWdodAkAAgECMllvdSBjYW4ndCBsb2NrIHNoYXJlVG9rZW5zIHRpbGwgZmlyc3QgaGFydmVzdCBlbmQuAwkAZwIAAAUIbG9ja1R5cGUJAAIBAhRsb2NrVHlwZSBtdXN0IGJlID4gMAMJAGYCBQpsb2NrQW1vdW50BRB1c2VyU3Rha2VkQW1vdW50CQACAQkArAICAhlZb3UgY2FuJ3QgbG9jayBtb3JlIHRoYW4gCQCkAwEFEHVzZXJTdGFrZWRBbW91bnQDCQBmAgkBDmFjY291bnRCYWxhbmNlAQUMc2hhcmVBc3NldElkBQp0b3RhbFNoYXJlCQACAQIwQmFsYW5jZSBvZiBzaGFyZS10b2tlbiBpcyBsb3dlciB0aGFuIHRvdGFsQW1vdW50AwMJAAACBQ91c2VyTG9ja2VkSGVpZ3QAAAMDCQBmAgABCQCQAwEIBQFpCHBheW1lbnRzBgkBAiE9AggJAJEDAggFAWkIcGF5bWVudHMAAAdhc3NldElkBQR1bml0BgkAZgIFDGxvY2tXYXZlc0ZlZQgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQHCQACAQkArAICCQCsAgICK1lvdSBuZWVkIHRvIHBheSBhZGRpdGlvbmFsIHdhdmVzIGNvbWlzc2lvbiAJAKQDAQUMbG9ja1dhdmVzRmVlAgVXQVZFUwMDCQAAAgUPdXNlckxvY2tlZEhlaWd0AAAJAGcCAAAFCmxvY2tBbW91bnQHCQACAQIhbG9ja0Ftb3VudCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwAwkAZgIAAAUKbG9ja0Ftb3VudAkAAgECG2xvY2tBbW91bnQgbXVzdCBiZSBwb3NpdGl2ZQMJAGYCBQ91c2VyTG9ja2VkSGVpZ3QJAGQCBQZoZWlnaHQFCmxvY2tQZXJpb2QJAAIBAk9Zb3UgY2Fubm90IGxvY2sgc2hhcmV0b2tlbnMgZm9yIGEgcGVyaW9kIGxlc3MgdGhhbiB3aGF0IHlvdSBoYXZlIGFscmVhZHkgbG9ja2VkBBN1c2VyTG9ja2VkQW1vdW50TmV3CQBkAgUQdXNlckxvY2tlZEFtb3VudAUKbG9ja0Ftb3VudAQTdXNlclN0YWtlZEFtb3VudE5ldwkAZQIFEHVzZXJTdGFrZWRBbW91bnQFCmxvY2tBbW91bnQEEnVzZXJMb2NrZWRIZWlndE5ldwkAZAIFBmhlaWdodAUKbG9ja1BlcmlvZAQUdXNlckFtb3VudFZpcnR1YWxOZXcJAGQCCQBrAwUTdXNlckxvY2tlZEFtb3VudE5ldwUIbG9ja0NvZWYFEmxvY2tCb29zdENvZWZTY2FsZQUQdXNlclN0YWtlZEFtb3VudAQNJHQwMjU1OTUyNTY5NAkBCWNsYWltQ2FsYwIFBHBvb2wFBHVzZXIEDGZhcm1JbnRlcmVzdAgFDSR0MDI1NTk1MjU2OTQCXzEEDWJvb3N0SW50ZXJlc3QIBQ0kdDAyNTU5NTI1Njk0Al8yBA9ib29zdExQaW50ZXJlc3QIBQ0kdDAyNTU5NTI1Njk0Al8zBAtjbGFpbUFtb3VudAgFDSR0MDI1NTk1MjU2OTQCXzQECnRvVHJlYXN1cmUIBQ0kdDAyNTU5NTI1Njk0Al81BBFhdmFpbGFibGVGdW5kc05ldwkAZAIJARF1c2VyQXZhaWxhYmxlU1dPUAIFBHBvb2wIBQFpDG9yaWdpbkNhbGxlcgULY2xhaW1BbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXIFFmtVc2VyU2hhcmVUb2tlbnNTdGFrZWQFE3VzZXJTdGFrZWRBbW91bnROZXcJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXIFFmtVc2VyU2hhcmVUb2tlbnNMb2NrZWQFE3VzZXJMb2NrZWRBbW91bnROZXcJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXIFHGtVc2VyU2hhcmVUb2tlbnNMb2NrZWRIZWlnaHQFEnVzZXJMb2NrZWRIZWlndE5ldwkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgUaa1VzZXJTaGFyZVRva2Vuc0xvY2tlZFR5cGUFCGxvY2tUeXBlCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyBRdrVXNlclNoYXJlVG9rZW5zVmlydHVhbAUUdXNlckFtb3VudFZpcnR1YWxOZXcJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUEcG9vbAUTa1NoYXJlVG9rZW5zVmlydHVhbAkAZAIJAGUCBRF0b3RhbFNoYXJlVmlydHVhbAURdXNlckFtb3VudFZpcnR1YWwFFHVzZXJBbW91bnRWaXJ0dWFsTmV3CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyBRVrRmFybVVzZXJMYXN0SW50ZXJlc3QFDGZhcm1JbnRlcmVzdAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgUWa0Jvb3N0VXNlckxhc3RJbnRlcmVzdAUNYm9vc3RJbnRlcmVzdAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgUUa0Jvb3N0TFBMYXN0SW50ZXJlc3QFD2Jvb3N0TFBpbnRlcmVzdAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQRwb29sBRFrRmFybUxhc3RJbnRlcmVzdAUMZmFybUludGVyZXN0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBHBvb2wFEmtCb29zdExhc3RJbnRlcmVzdAUNYm9vc3RJbnRlcmVzdAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQRwb29sBRRrQm9vc3RMUExhc3RJbnRlcmVzdAUPYm9vc3RMUGludGVyZXN0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBHBvb2wFE2tMYXN0SW50ZXJlc3RIZWlnaHQFBmhlaWdodAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgUOa0F2YWlsYWJsZVNXT1AFEWF2YWlsYWJsZUZ1bmRzTmV3CQDMCAIJAQdSZWlzc3VlAwUEU1dPUAUKdG9UcmVhc3VyZQYJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUTZmFybWluZ1RyZWFzdXJlQWRkcgUKdG9UcmVhc3VyZQUEU1dPUAUDbmlsAWkBDnVubG9ja1VzZXJMb2NrAgRwb29sBHVzZXIJAQt2YWx1ZU9yRWxzZQIJAQhpc0FjdGl2ZQAEDGxvY2tXYXZlc0ZlZQkBEUBleHRyTmF0aXZlKDEwNTApAgUEdGhpcwUNa0xvY2tXYXZlc0ZlZQQPdXNlckxvY2tlZEhlaWd0CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUEdGhpcwkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgUca1VzZXJTaGFyZVRva2Vuc0xvY2tlZEhlaWdodAkArAICCQCsAgIJAKwCAgkArAICAhFUaGVyZSBpcyBubyBwb29sIAUEcG9vbAIJIG9yIHVzZXIgBQR1c2VyAgl3aXRoIGxvY2sEEXRvdGFsU2hhcmVWaXJ0dWFsCQERQGV4dHJOYXRpdmUoMTA1MCkCBQR0aGlzCQCsAgIFBHBvb2wFE2tTaGFyZVRva2Vuc1ZpcnR1YWwEEHVzZXJTdGFrZWRBbW91bnQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgUWa1VzZXJTaGFyZVRva2Vuc1N0YWtlZAAABBB1c2VyTG9ja2VkQW1vdW50CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXIFFmtVc2VyU2hhcmVUb2tlbnNMb2NrZWQAAAQRdXNlckFtb3VudFZpcnR1YWwJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgUXa1VzZXJTaGFyZVRva2Vuc1ZpcnR1YWwFEHVzZXJTdGFrZWRBbW91bnQDCQBmAgUPdXNlckxvY2tlZEhlaWd0BQZoZWlnaHQJAAIBCQCsAgICIllvdSBjYW4ndCB1bmxvY2sgc2hhcmV0b2tlbnMgdGlsbCAJAKQDAQUPdXNlckxvY2tlZEhlaWd0BBN1c2VyU3Rha2VkQW1vdW50TmV3CQBkAgUQdXNlclN0YWtlZEFtb3VudAUQdXNlckxvY2tlZEFtb3VudAQNJHQwMjc5MzAyODAyOQkBCWNsYWltQ2FsYwIFBHBvb2wFBHVzZXIEDGZhcm1JbnRlcmVzdAgFDSR0MDI3OTMwMjgwMjkCXzEEDWJvb3N0SW50ZXJlc3QIBQ0kdDAyNzkzMDI4MDI5Al8yBA9ib29zdExQaW50ZXJlc3QIBQ0kdDAyNzkzMDI4MDI5Al8zBAtjbGFpbUFtb3VudAgFDSR0MDI3OTMwMjgwMjkCXzQECnRvVHJlYXN1cmUIBQ0kdDAyNzkzMDI4MDI5Al81BBFhdmFpbGFibGVGdW5kc05ldwkAZAIJARF1c2VyQXZhaWxhYmxlU1dPUAIFBHBvb2wIBQFpDG9yaWdpbkNhbGxlcgULY2xhaW1BbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXIFFWtGYXJtVXNlckxhc3RJbnRlcmVzdAUMZmFybUludGVyZXN0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyBRZrQm9vc3RVc2VyTGFzdEludGVyZXN0BQ1ib29zdEludGVyZXN0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyBRRrQm9vc3RMUExhc3RJbnRlcmVzdAUPYm9vc3RMUGludGVyZXN0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBHBvb2wFEWtGYXJtTGFzdEludGVyZXN0BQxmYXJtSW50ZXJlc3QJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUEcG9vbAUSa0Jvb3N0TGFzdEludGVyZXN0BQ1ib29zdEludGVyZXN0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBHBvb2wFFGtCb29zdExQTGFzdEludGVyZXN0BQ9ib29zdExQaW50ZXJlc3QJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUEcG9vbAUTa0xhc3RJbnRlcmVzdEhlaWdodAUGaGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyBRZrVXNlclNoYXJlVG9rZW5zU3Rha2VkBRN1c2VyU3Rha2VkQW1vdW50TmV3CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyBRdrVXNlclNoYXJlVG9rZW5zVmlydHVhbAUTdXNlclN0YWtlZEFtb3VudE5ldwkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQRwb29sBRNrU2hhcmVUb2tlbnNWaXJ0dWFsCQBkAgkAZQIFEXRvdGFsU2hhcmVWaXJ0dWFsBRF1c2VyQW1vdW50VmlydHVhbAUTdXNlclN0YWtlZEFtb3VudE5ldwkAzAgCCQELRGVsZXRlRW50cnkBCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyBRZrVXNlclNoYXJlVG9rZW5zTG9ja2VkCQDMCAIJAQtEZWxldGVFbnRyeQEJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXIFHGtVc2VyU2hhcmVUb2tlbnNMb2NrZWRIZWlnaHQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgUaa1VzZXJTaGFyZVRva2Vuc0xvY2tlZFR5cGUJAMwIAgkBB1JlaXNzdWUDBQRTV09QBQp0b1RyZWFzdXJlBgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBRNmYXJtaW5nVHJlYXN1cmVBZGRyBQp0b1RyZWFzdXJlBQRTV09QCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgUMbG9ja1dhdmVzRmVlBQR1bml0BQNuaWwBaQETd2l0aGRyYXdTaGFyZVRva2VucwIEcG9vbBlzaGFyZVRva2Vuc1dpdGhkcmF3QW1vdW50CQELdmFsdWVPckVsc2UCCQEIaXNBY3RpdmUABA1zaGFyZVRva2Vuc0lkCQDZBAEJARFAZXh0ck5hdGl2ZSgxMDUzKQIJAQV2YWx1ZQEJAKYIAQUEcG9vbAIOc2hhcmVfYXNzZXRfaWQEBHVzZXIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBA0kdDAyOTUzMzI5NjMyCQEJY2xhaW1DYWxjAgUEcG9vbAUEdXNlcgQMZmFybUludGVyZXN0CAUNJHQwMjk1MzMyOTYzMgJfMQQNYm9vc3RJbnRlcmVzdAgFDSR0MDI5NTMzMjk2MzICXzIED2Jvb3N0TFBpbnRlcmVzdAgFDSR0MDI5NTMzMjk2MzICXzMEC2NsYWltQW1vdW50CAUNJHQwMjk1MzMyOTYzMgJfNAQKdG9UcmVhc3VyZQgFDSR0MDI5NTMzMjk2MzICXzUEEHVzZXJTdGFrZWRBbW91bnQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgUWa1VzZXJTaGFyZVRva2Vuc1N0YWtlZAAABBB1c2VyTG9ja2VkQW1vdW50CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXIFFmtVc2VyU2hhcmVUb2tlbnNMb2NrZWQAAAQRdXNlckFtb3VudFZpcnR1YWwJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgUXa1VzZXJTaGFyZVRva2Vuc1ZpcnR1YWwFEHVzZXJTdGFrZWRBbW91bnQEE3VzZXJTdGFrZWRBbW91bnROZXcJAGUCBRB1c2VyU3Rha2VkQW1vdW50BRlzaGFyZVRva2Vuc1dpdGhkcmF3QW1vdW50BBFhdmFpbGFibGVGdW5kc05ldwkAZAIJARF1c2VyQXZhaWxhYmxlU1dPUAIFBHBvb2wIBQFpDG9yaWdpbkNhbGxlcgULY2xhaW1BbW91bnQEEHRvdGFsU2hhcmVBbW91bnQJARJnZXRUb3RhbFNoYXJlVG9rZW4BBQRwb29sBBF0b3RhbFNoYXJlVmlydHVhbAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQCsAgIFBHBvb2wFE2tTaGFyZVRva2Vuc1ZpcnR1YWwFEHRvdGFsU2hhcmVBbW91bnQEE3RvdGFsU2hhcmVBbW91bnROZXcJAGUCBRB0b3RhbFNoYXJlQW1vdW50BRlzaGFyZVRva2Vuc1dpdGhkcmF3QW1vdW50BBR0b3RhbFNoYXJlVmlydHVhbE5ldwkAZQIFEXRvdGFsU2hhcmVWaXJ0dWFsBRlzaGFyZVRva2Vuc1dpdGhkcmF3QW1vdW50BBR1c2VyQW1vdW50VmlydHVhbE5ldwkAZQIFEXVzZXJBbW91bnRWaXJ0dWFsBRlzaGFyZVRva2Vuc1dpdGhkcmF3QW1vdW50AwkAZgIFGXNoYXJlVG9rZW5zV2l0aGRyYXdBbW91bnQFEHVzZXJTdGFrZWRBbW91bnQJAAIBAixXaXRoZHJhdyBhbW91bnQgbW9yZSB0aGVuIHVzZXIgbG9ja2VkIGFtb3VudAMJAGYCCQEOYWNjb3VudEJhbGFuY2UBBQ1zaGFyZVRva2Vuc0lkBRB0b3RhbFNoYXJlQW1vdW50CQACAQIwQmFsYW5jZSBvZiBzaGFyZS10b2tlbiBpcyBsb3dlciB0aGFuIHRvdGFsQW1vdW50BAR1cGxwAwkAAAIJAJ0IAgkBB0FkZHJlc3MBCQDZBAEFBHBvb2wCB3ZlcnNpb24CBTMuMC4wCQD8BwQFEGxwRmFybWluZ0FkZHJlc3MCEnVwZGF0ZVVzZXJJbnRlcmVzdAkAzAgCBQRwb29sCQDMCAIJAGQCBRB1c2VyU3Rha2VkQW1vdW50BRB1c2VyTG9ja2VkQW1vdW50BQNuaWwFA25pbAAAAwkAAAIFBHVwbHAFBHVwbHAJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXIFFWtGYXJtVXNlckxhc3RJbnRlcmVzdAUMZmFybUludGVyZXN0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyBRZrQm9vc3RVc2VyTGFzdEludGVyZXN0BQ1ib29zdEludGVyZXN0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyBRRrQm9vc3RMUExhc3RJbnRlcmVzdAUPYm9vc3RMUGludGVyZXN0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBHBvb2wFEWtGYXJtTGFzdEludGVyZXN0BQxmYXJtSW50ZXJlc3QJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUEcG9vbAUSa0Jvb3N0TGFzdEludGVyZXN0BQ1ib29zdEludGVyZXN0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBHBvb2wFFGtCb29zdExQTGFzdEludGVyZXN0BQ9ib29zdExQaW50ZXJlc3QJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUEcG9vbAUTa0xhc3RJbnRlcmVzdEhlaWdodAUGaGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyBRZrVXNlclNoYXJlVG9rZW5zU3Rha2VkBRN1c2VyU3Rha2VkQW1vdW50TmV3CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyBRdrVXNlclNoYXJlVG9rZW5zVmlydHVhbAUUdXNlckFtb3VudFZpcnR1YWxOZXcJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUEcG9vbAUWa1NoYXJlVG90YWxTaGFyZVRva2VucwUTdG90YWxTaGFyZUFtb3VudE5ldwkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQRwb29sBRNrU2hhcmVUb2tlbnNWaXJ0dWFsBRR0b3RhbFNoYXJlVmlydHVhbE5ldwkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgUOa0F2YWlsYWJsZVNXT1AFEWF2YWlsYWJsZUZ1bmRzTmV3CQDMCAIJAQdSZWlzc3VlAwUEU1dPUAUKdG9UcmVhc3VyZQYJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUTZmFybWluZ1RyZWFzdXJlQWRkcgUKdG9UcmVhc3VyZQUEU1dPUAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFGXNoYXJlVG9rZW5zV2l0aGRyYXdBbW91bnQFDXNoYXJlVG9rZW5zSWQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQVjbGFpbQEEcG9vbAkBC3ZhbHVlT3JFbHNlAgkBCGlzQWN0aXZlAAQNc2hhcmVUb2tlbnNJZAkA2QQBCQERQGV4dHJOYXRpdmUoMTA1MykCCQEFdmFsdWUBCQCmCAEFBHBvb2wCDnNoYXJlX2Fzc2V0X2lkBAR1c2VyCQClCAEIBQFpBmNhbGxlcgQQc2hhcmVUb2tlbkxvY2tlZAkBEmdldFRvdGFsU2hhcmVUb2tlbgEFBHBvb2wEDSR0MDMyMzAxMzI0MDAJAQljbGFpbUNhbGMCBQRwb29sBQR1c2VyBAxmYXJtSW50ZXJlc3QIBQ0kdDAzMjMwMTMyNDAwAl8xBA1ib29zdEludGVyZXN0CAUNJHQwMzIzMDEzMjQwMAJfMgQPYm9vc3RMUGludGVyZXN0CAUNJHQwMzIzMDEzMjQwMAJfMwQLY2xhaW1BbW91bnQIBQ0kdDAzMjMwMTMyNDAwAl80BAp0b1RyZWFzdXJlCAUNJHQwMzIzMDEzMjQwMAJfNQQNYXZhaWxhYmxlRnVuZAkAZAIJARF1c2VyQXZhaWxhYmxlU1dPUAIFBHBvb2wIBQFpBmNhbGxlcgULY2xhaW1BbW91bnQDCQAAAgUNYXZhaWxhYmxlRnVuZAAACQACAQIZWW91IGhhdmUgMCBhdmFpbGFibGUgU1dPUAMJAGYCCQEOYWNjb3VudEJhbGFuY2UBBQ1zaGFyZVRva2Vuc0lkBRBzaGFyZVRva2VuTG9ja2VkCQACAQIwQmFsYW5jZSBvZiBzaGFyZS10b2tlbiBpcyBsb3dlciB0aGFuIHRvdGFsQW1vdW50CQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXIFFWtGYXJtVXNlckxhc3RJbnRlcmVzdAUMZmFybUludGVyZXN0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyBRZrQm9vc3RVc2VyTGFzdEludGVyZXN0BQ1ib29zdEludGVyZXN0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyBRRrQm9vc3RMUExhc3RJbnRlcmVzdAUPYm9vc3RMUGludGVyZXN0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBHBvb2wFEWtGYXJtTGFzdEludGVyZXN0BQxmYXJtSW50ZXJlc3QJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUEcG9vbAUSa0Jvb3N0TGFzdEludGVyZXN0BQ1ib29zdEludGVyZXN0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBHBvb2wFFGtCb29zdExQTGFzdEludGVyZXN0BQ9ib29zdExQaW50ZXJlc3QJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUEcG9vbAUTa0xhc3RJbnRlcmVzdEhlaWdodAUGaGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyBQ5rQXZhaWxhYmxlU1dPUAAACQDMCAIJAQdSZWlzc3VlAwUEU1dPUAkAZAIFCnRvVHJlYXN1cmUFDWF2YWlsYWJsZUZ1bmQGCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFE2Zhcm1pbmdUcmVhc3VyZUFkZHIFCnRvVHJlYXN1cmUFBFNXT1AJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQ1hdmFpbGFibGVGdW5kBQRTV09QBQNuaWwFDWF2YWlsYWJsZUZ1bmQBaQENY2xhaW1BbmRTdGFrZQEEcG9vbAkBC3ZhbHVlT3JFbHNlAgkBCGlzQWN0aXZlAAQLY2xhaW1BbW91bnQKAAFACQD8BwQFBHRoaXMCBWNsYWltCQDMCAIFBHBvb2wFA25pbAUDbmlsAwkAAQIFAUACA0ludAUBQAkAAgEJAKwCAgkAAwEFAUACGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAMJAAACBQtjbGFpbUFtb3VudAULY2xhaW1BbW91bnQECnN0YWtlVG9Hb3YJAPwHBAUKZ292QWRkcmVzcwITbG9ja1NXT1BGcm9tRmFybWluZwUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQRTV09QBQtjbGFpbUFtb3VudAUDbmlsAwkAAAIFCnN0YWtlVG9Hb3YFCnN0YWtlVG9Hb3YFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQhjbGFpbUFsbAEFcG9vbHMJAQt2YWx1ZU9yRWxzZQIJAQhpc0FjdGl2ZQAKAQhjbGFpbUludgIKY2xhaW1Ub3RhbARwb29sBAtjbGFpbUFtb3VudAoAAUAJAPwHBAUEdGhpcwIFY2xhaW0JAMwIAgUEcG9vbAUDbmlsBQNuaWwDCQABAgUBQAIDSW50BQFACQACAQkArAICCQADAQUBQAIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50AwkAAAIFC2NsYWltQW1vdW50BQtjbGFpbUFtb3VudAkAZAIFCmNsYWltVG90YWwFC2NsYWltQW1vdW50CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBApjbGFpbVRvdGFsCgACJGwFBXBvb2xzCgACJHMJAJADAQUCJGwKAAUkYWNjMAAACgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQhjbGFpbUludgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgNjAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyADMANAA1ADYANwA4ADkAOgA7ADwDCQAAAgUKY2xhaW1Ub3RhbAAACQACAQIZWW91IGhhdmUgMCBhdmFpbGFibGUgU1dPUAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFCmNsYWltVG90YWwFBFNXT1AFA25pbAFpARBjbGFpbUFsbEFuZFN0YWtlAQVwb29scwkBC3ZhbHVlT3JFbHNlAgkBCGlzQWN0aXZlAAoBCGNsYWltSW52AgpjbGFpbVRvdGFsBHBvb2wEC2NsYWltQW1vdW50CgABQAkA/AcEBQR0aGlzAgVjbGFpbQkAzAgCBQRwb29sBQNuaWwFA25pbAMJAAECBQFAAgNJbnQFAUAJAAIBCQCsAgIJAAMBBQFAAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQDCQAAAgULY2xhaW1BbW91bnQFC2NsYWltQW1vdW50CQBkAgUKY2xhaW1Ub3RhbAULY2xhaW1BbW91bnQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4ECmNsYWltVG90YWwKAAIkbAUFcG9vbHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCGNsYWltSW52AgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyA2MAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAAxADIAMwA0ADUANgA3ADgAOQA6ADsAPAMJAAACBQpjbGFpbVRvdGFsAAAJAAIBAhlZb3UgaGF2ZSAwIGF2YWlsYWJsZSBTV09QBApzdGFrZVRvR292CQD8BwQFCmdvdkFkZHJlc3MCE2xvY2tTV09QRnJvbUZhcm1pbmcFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUEU1dPUAUKY2xhaW1Ub3RhbAUDbmlsAwkAAAIFCnN0YWtlVG9Hb3YFCnN0YWtlVG9Hb3YFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARd1cGRhdGVVc2VyQm9vc3RJbnRlcmVzdAIEcG9vbAR1c2VyCQELdmFsdWVPckVsc2UCCQEIaXNBY3RpdmUAAwkBAiE9AggFAWkGY2FsbGVyBQ12b3RpbmdBZGRyZXNzCQACAQIjT25seSB2b2l0aW5nIGNhbiBjYWxsIHRoaXMgZnVuY3Rpb24EDSR0MDM0NzgwMzQ4NzkJAQljbGFpbUNhbGMCBQRwb29sBQR1c2VyBAxmYXJtSW50ZXJlc3QIBQ0kdDAzNDc4MDM0ODc5Al8xBA1ib29zdEludGVyZXN0CAUNJHQwMzQ3ODAzNDg3OQJfMgQPYm9vc3RMUGludGVyZXN0CAUNJHQwMzQ3ODAzNDg3OQJfMwQLY2xhaW1BbW91bnQIBQ0kdDAzNDc4MDM0ODc5Al80BAp0b1RyZWFzdXJlCAUNJHQwMzQ3ODAzNDg3OQJfNQQRYXZhaWxhYmxlRnVuZHNOZXcJAGQCCQERdXNlckF2YWlsYWJsZVNXT1ACBQRwb29sCAUBaQxvcmlnaW5DYWxsZXIFC2NsYWltQW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyBRVrRmFybVVzZXJMYXN0SW50ZXJlc3QFDGZhcm1JbnRlcmVzdAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgUWa0Jvb3N0VXNlckxhc3RJbnRlcmVzdAUNYm9vc3RJbnRlcmVzdAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgUUa0Jvb3N0TFBMYXN0SW50ZXJlc3QFD2Jvb3N0TFBpbnRlcmVzdAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQRwb29sBRFrRmFybUxhc3RJbnRlcmVzdAUMZmFybUludGVyZXN0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBHBvb2wFEmtCb29zdExhc3RJbnRlcmVzdAUNYm9vc3RJbnRlcmVzdAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQRwb29sBRRrQm9vc3RMUExhc3RJbnRlcmVzdAUPYm9vc3RMUGludGVyZXN0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBHBvb2wFE2tMYXN0SW50ZXJlc3RIZWlnaHQFBmhlaWdodAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgUOa0F2YWlsYWJsZVNXT1AFEWF2YWlsYWJsZUZ1bmRzTmV3CQDMCAIJAQdSZWlzc3VlAwUEU1dPUAUKdG9UcmVhc3VyZQYJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUTZmFybWluZ1RyZWFzdXJlQWRkcgUKdG9UcmVhc3VyZQUEU1dPUAUDbmlsAWkBCHNodXRkb3duAAkBC3ZhbHVlT3JFbHNlAgkBC2lzQWRtaW5DYWxsAQUBaQMJAQEhAQUGYWN0aXZlCQACAQkArAICAiJEQXBwIGlzIGFscmVhZHkgc3VzcGVuZGVkLiBDYXVzZTogCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFBmtDYXVzZQIadGhlIGNhdXNlIHdhc24ndCBzcGVjaWZpZWQJAQdzdXNwZW5kAQIPUGF1c2VkIGJ5IGFkbWluAWkBCGFjdGl2YXRlAAkBC3ZhbHVlT3JFbHNlAgkBC2lzQWRtaW5DYWxsAQUBaQMFBmFjdGl2ZQkAAgECFkRBcHAgaXMgYWxyZWFkeSBhY3RpdmUJAMwIAgkBDEJvb2xlYW5FbnRyeQIFB2tBY3RpdmUGCQDMCAIJAQtEZWxldGVFbnRyeQEFBmtDYXVzZQUDbmlsAQJ0eAEGdmVyaWZ5AAQHJG1hdGNoMAUCdHgEEmFkbWluUHViS2V5MVNpZ25lZAMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAFDGFkbWluUHViS2V5MQABAAAEEmFkbWluUHViS2V5MlNpZ25lZAMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAEFDGFkbWluUHViS2V5MgABAAAEEmFkbWluUHViS2V5M1NpZ25lZAMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAIFDGFkbWluUHViS2V5MwABAAAJAGcCCQBkAgkAZAIFEmFkbWluUHViS2V5MVNpZ25lZAUSYWRtaW5QdWJLZXkyU2lnbmVkBRJhZG1pblB1YktleTNTaWduZWQAAvMAMV8=", "height": 2288093, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: Gs9RGRoENsG9EAY85ErKQ4cG5LnaPz33754fHbqqCp1J Next: DoRqnDUm9uxSbGH4GV8J8XcZcTNu7VBLNVAnrAXZBmn7 Diff:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let PRECISION = 1000000
4+let kActive = "active"
55
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"
6+let kActiveGlob = "active_all_contracts"
237
248 let kCause = "shutdown_cause"
259
26-let kShareAssetId = "share_asset_id"
10+let kRewardPoolFractionCurrent = "_current_pool_fraction_reward"
2711
28-let kShareAssetSupply = "share_asset_supply"
12+let kRewardPoolFractionPrevious = "_previous_pool_fraction_reward"
2913
30-let kFee = "commission"
14+let kHeightPoolFraction = "_pool_reward_update_height"
3115
32-let kDAppThresholdCoef = "dAppThresholdCoef"
16+let kTotalRewardPerBlockCurrent = "total_reward_per_block_current"
3317
34-let kUSDNAddress = "staking_usdnnsbt_address"
18+let kTotalRewardPerBlockPrevious = "total_reward_per_block_previous"
3519
36-let kDiscounts = "discounts"
20+let kRewardUpdateHeight = "reward_update_height"
3721
38-let kDiscountValues = "discount_values"
22+let kUserShareTokensStaked = "_share_tokens_locked"
3923
40-let kUserSwopInGov = "_SWOP_amount"
24+let kUserShareTokensLocked = "_share_tokens_blocked"
4125
42-let kUserGSwopInGov = "_GSwop_amount"
26+let kUserShareTokensLockedType = "_share_tokens_blocked_type"
27+
28+let kUserShareTokensLockedHeight = "_share_tokens_blocked_height"
29+
30+let kUserShareTokensVirtual = "_share_tokens_virtual"
31+
32+let kShareTotalShareTokens = "_total_share_tokens_locked"
33+
34+let kShareTokensVirtual = "_total_share_tokens_virtual"
35+
36+let kLockParams = "_lock_params"
37+
38+let kLockWavesFee = "lock_waves_fee"
39+
40+let kPoolBoostCoef = "_boost_coef"
41+
42+let kFarmLastInterest = "_last_interest"
43+
44+let kFarmUserLastInterest = "_last_interest"
45+
46+let kBoostLastInterest = "_last_interest_b"
47+
48+let kBoostUserLastInterest = "_last_interest_u_b"
49+
50+let kBoostLPLastInterest = "_last_interest_lpb"
51+
52+let kBoostLPUserLastInterest = "_last_interest_u_lpb"
53+
54+let kLastInterestHeight = "_last_interest_height"
55+
56+let kSWOPid = "SWOP_id"
57+
58+let kAvailableSWOP = "_available_SWOP"
59+
60+let kSwopYearEmission = "swop_year_emission"
61+
62+let kHarvestPoolVote = "_harvest_pool_vote_gSWOP"
63+
64+let kPoolVote = "_pool_vote_gSWOP"
65+
66+let kUserPoolVote = "_user_vote_gSWOP"
67+
68+let kHarvestUserPoolVote = "_harvest_user_pool_vote_gSWOP"
69+
70+let kBasePeriod = "base_period"
71+
72+let kPeriodLength = "period_length"
73+
74+let kStartHeight = "start_height"
75+
76+let kFirstHarvestHeight = "first_harvest_height"
77+
78+let kShareLimitFH = "share_limit_on_first_harvest"
4379
4480 let kAdminPubKey1 = "admin_pub_1"
4581
5187
5288 let kMoneyBoxAddress = "money_box_address"
5389
54-let kGovAddress = "governance_address"
55-
5690 let kVotingAddress = "voting_address"
5791
58-let kFarmingAddress = "farming_address"
92+let kGovAddress = "governance_address"
5993
6094 let kLPFarmingAddress = "lp_farming"
6195
96+let kFarmingTreasureAddr = "farming_treasure"
97+
6298 let oracle = Address(base58'3MvVBtsXroQpy1tsPw21TU2ET9A8WfmrNjz')
99+
100+let totalVoteShare = 10000000000
101+
102+let scaleValue8 = 100000000
103+
104+let lockBoostCoefScale = 1000
105+
106+let defPoolBoostCoef = 500
63107
64108 func getBase58FromOracle (key) = match getString(oracle, key) {
65109 case string: String =>
75119
76120 let adminPubKey3 = getBase58FromOracle(kAdminPubKey3)
77121
78-let adminPubKeyInvoke = getBase58FromOracle(kAdminInvokePubKey)
122+let moneyBoxAddress = Address(getBase58FromOracle(kMoneyBoxAddress))
79123
80-let moneyBoxAddress = Address(getBase58FromOracle(kMoneyBoxAddress))
124+let votingAddress = Address(getBase58FromOracle(kVotingAddress))
81125
82126 let govAddress = Address(getBase58FromOracle(kGovAddress))
83127
84-let stakingUSDNAddress = Address(getBase58FromOracle(kUSDNAddress))
85-
86-let votingAddress = Address(getBase58FromOracle(kVotingAddress))
87-
88-let farmingAddress = Address(getBase58FromOracle(kFarmingAddress))
128+let adminInvokePubKey = getBase58FromOracle(kAdminInvokePubKey)
89129
90130 let lpFarmingAddress = Address(getBase58FromOracle(kLPFarmingAddress))
91131
92-let USDN = base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p'
132+let farmingTreasureAddr = Address(getBase58FromOracle(kFarmingTreasureAddr))
93133
94-let stakingAssets = [toBase58String(USDN)]
134+let basePeriod = valueOrErrorMessage(getInteger(votingAddress, kBasePeriod), "Empty kBasePeriod")
135+
136+let startHeight = valueOrErrorMessage(getInteger(votingAddress, kStartHeight), "Empty kStartHeight")
137+
138+let periodLength = valueOrErrorMessage(getInteger(votingAddress, kPeriodLength), "Empty kPeriodLength")
139+
140+let currPeriod = (basePeriod + ((height - startHeight) / periodLength))
95141
96142 let active = getBooleanValue(this, kActive)
97143
98-let shareAssetId = fromBase58String(getStringValue(this, kShareAssetId))
144+let activeGlob = valueOrElse(getBoolean(oracle, kActiveGlob), true)
99145
100-let shareSupply = getIntegerValue(this, kShareAssetSupply)
146+let SwopYearEmission = getIntegerValue(this, kSwopYearEmission)
101147
102-let feeScale6 = 1000000
148+let SWOP = fromBase58String(getStringValue(this, kSWOPid))
103149
104-let fee = getIntegerValue(this, kFee)
150+func getHeightFirstHarvest (pool) = valueOrElse(getInteger(Address(fromBase58String(pool)), kFirstHarvestHeight), 0)
105151
106-let feeGovernance = fraction(40, feeScale6, 100)
107152
108-let initial_A = getIntegerValue(this, "initial_A")
153+func getFHShareLimitToken (pool) = valueOrErrorMessage(getInteger(pool, kShareLimitFH), ("No data on the key: " + kShareLimitFH))
109154
110-let future_A = getIntegerValue(this, "future_A")
111155
112-let initial_A_time = valueOrElse(getInteger(this, "initial_A_time"), 0)
156+func getTotalShareToken (pool) = valueOrErrorMessage(getInteger(this, (pool + kShareTotalShareTokens)), (("No data on the key: " + pool) + kShareTotalShareTokens))
113157
114-let future_A_time = valueOrElse(getInteger(this, "future_A_time"), 0)
115158
116-let assetIds = split(getStringValue(this, kAssets), ",")
159+func getPoolVoted (pool) = valueOrElse(getInteger(votingAddress, (pool + kPoolVote)), 0)
117160
118-let nCoins = size(assetIds)
161+
162+func getUserPoolVoted (pool,user) = valueOrElse(getInteger(votingAddress, (((user + "_") + pool) + kPoolVote)), 0)
163+
164+
165+func getShareAssetId (pool) = fromBase58String(getStringValue(value(addressFromString(pool)), "share_asset_id"))
166+
167+
168+func accountBalance (assetId) = match assetId {
169+ case id: ByteVector =>
170+ assetBalance(this, id)
171+ case waves: Unit =>
172+ wavesBalance(this).available
173+ case _ =>
174+ throw("Match error")
175+}
176+
177+
178+func getAssetInfo (assetId) = match assetId {
179+ case id: ByteVector =>
180+ let stringId = toBase58String(id)
181+ let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
182+ $Tuple3(stringId, info.name, info.decimals)
183+ case waves: Unit =>
184+ $Tuple3("WAVES", "WAVES", 8)
185+ case _ =>
186+ throw("Match error")
187+}
188+
189+
190+func calcScaleValue (assetId1,assetId2) = {
191+ let assetId1Decimals = value(assetInfo(assetId1)).decimals
192+ let assetId2Decimals = value(assetInfo(assetId2)).decimals
193+ let scaleDigits = ((assetId2Decimals - assetId1Decimals) + 8)
194+ pow(10, 0, scaleDigits, 0, 0, DOWN)
195+ }
196+
197+
198+func userAvailableSWOP (pool,user) = valueOrElse(getInteger(this, (((pool + "_") + toString(user)) + kAvailableSWOP)), 0)
199+
200+
201+func rewardInfo (pool) = {
202+ let totalRewardPerBlockCurrent = valueOrErrorMessage(getInteger(govAddress, kTotalRewardPerBlockCurrent), ((("No data on the key: " + kTotalRewardPerBlockCurrent) + " at address ") + toString(govAddress)))
203+ let totalRewardPerBlockPrevious = valueOrErrorMessage(getInteger(govAddress, kTotalRewardPerBlockPrevious), ((("No data on the key: " + kTotalRewardPerBlockPrevious) + " at address ") + toString(govAddress)))
204+ let rewardPoolFractionCurrent = valueOrErrorMessage(getInteger(govAddress, (pool + kRewardPoolFractionCurrent)), (((("No data on the key: " + pool) + kRewardPoolFractionCurrent) + " at address ") + toString(govAddress)))
205+ let rewardUpdateHeight = valueOrErrorMessage(getInteger(govAddress, kRewardUpdateHeight), ((("No data on the key: " + kRewardUpdateHeight) + " at address ") + toString(govAddress)))
206+ let poolRewardUpdateHeight = valueOrElse(getInteger(govAddress, (pool + kHeightPoolFraction)), rewardUpdateHeight)
207+ let rewardPoolFractionPrevious = valueOrErrorMessage(getInteger(govAddress, (pool + kRewardPoolFractionPrevious)), (((("No data on the key: " + pool) + kRewardPoolFractionPrevious) + " at address ") + toString(govAddress)))
208+ let rewardPoolCurrent = fraction(totalRewardPerBlockCurrent, rewardPoolFractionCurrent, totalVoteShare)
209+ let rewardPoolPrevious = fraction(totalRewardPerBlockCurrent, rewardPoolFractionPrevious, totalVoteShare)
210+ if (if ((rewardPoolCurrent > totalRewardPerBlockCurrent))
211+ then true
212+ else (rewardPoolPrevious > totalRewardPerBlockPrevious))
213+ then throw("rewardPoolCurrent > totalRewardPerBlockCurrent or rewardPoolPrevious > totalRewardPerBlockPrevious")
214+ else $Tuple4(rewardPoolCurrent, rewardUpdateHeight, rewardPoolPrevious, poolRewardUpdateHeight)
215+ }
216+
217+
218+func getLastInterestInfo (pool) = {
219+ let farmInterest = valueOrErrorMessage(getInteger(this, (pool + kFarmLastInterest)), (("No data on the key: " + pool) + kFarmLastInterest))
220+ let boostInterest = valueOrErrorMessage(getInteger(this, (pool + kFarmLastInterest)), (("No data on the key: " + pool) + kBoostLastInterest))
221+ let boostLPInterest = valueOrErrorMessage(getInteger(this, (pool + kFarmLastInterest)), (("No data on the key: " + pool) + kBoostLPLastInterest))
222+ let lastInterestHeight = valueOrElse(getInteger(this, (pool + kLastInterestHeight)), height)
223+ $Tuple4(lastInterestHeight, farmInterest, boostInterest, boostLPInterest)
224+ }
225+
226+
227+func calcFarmRwd (pool,curTotalReward) = {
228+ let poolBoostCoef = valueOrElse(getInteger(this, (pool + kPoolBoostCoef)), defPoolBoostCoef)
229+ ((curTotalReward / (poolBoostCoef + 1000)) / lockBoostCoefScale)
230+ }
231+
232+
233+func calcBoostRwd (pool,curTotalReward) = {
234+ let poolBoostCoef = valueOrElse(getInteger(this, (pool + kPoolBoostCoef)), defPoolBoostCoef)
235+ (fraction(curTotalReward, poolBoostCoef, (poolBoostCoef + 1000)) / lockBoostCoefScale)
236+ }
237+
238+
239+func calcInterest (pool,lastInterestHeight,rewardUpdateHeight,poolRewardUpdateHeight,farmInterest,boostInterest,poolVoted,boostLpInterest,currentRewardPerBlock,shareTokenLocked,previousRewardPerBlock,scaleValue) = if ((shareTokenLocked == 0))
240+ then $Tuple3(0, 0, 0)
241+ else if (if ((rewardUpdateHeight > height))
242+ then (rewardUpdateHeight == poolRewardUpdateHeight)
243+ else false)
244+ then {
245+ let reward = (previousRewardPerBlock * (height - lastInterestHeight))
246+ let newFarmInterest = (farmInterest + fraction(calcFarmRwd(pool, reward), scaleValue, shareTokenLocked))
247+ let newBoostInterest = (boostInterest + (if ((poolVoted > 0))
248+ then fraction(calcBoostRwd(pool, reward), scaleValue8, poolVoted)
249+ else 0))
250+ let newBoostLPInterest = (boostLpInterest + (if (if ((poolVoted > 0))
251+ then (shareTokenLocked > 0)
252+ else false)
253+ then fraction(fraction(calcBoostRwd(pool, reward), scaleValue8, shareTokenLocked), scaleValue8, poolVoted)
254+ else 0))
255+ $Tuple3(newFarmInterest, newBoostInterest, newBoostLPInterest)
256+ }
257+ else if (if ((height > rewardUpdateHeight))
258+ then (rewardUpdateHeight != poolRewardUpdateHeight)
259+ else false)
260+ then {
261+ let reward = (previousRewardPerBlock * (height - lastInterestHeight))
262+ let newFarmInterest = (farmInterest + fraction(calcFarmRwd(pool, reward), scaleValue, shareTokenLocked))
263+ let newBoostInterest = (boostInterest + (if ((poolVoted > 0))
264+ then fraction(calcBoostRwd(pool, reward), scaleValue8, poolVoted)
265+ else 0))
266+ let newBoostLPInterest = (boostLpInterest + (if (if ((poolVoted > 0))
267+ then (shareTokenLocked > 0)
268+ else false)
269+ then fraction(fraction(calcBoostRwd(pool, reward), scaleValue8, shareTokenLocked), scaleValue8, poolVoted)
270+ else 0))
271+ $Tuple3(newFarmInterest, newBoostInterest, newBoostLPInterest)
272+ }
273+ else if (if (if ((height > rewardUpdateHeight))
274+ then (rewardUpdateHeight == poolRewardUpdateHeight)
275+ else false)
276+ then (lastInterestHeight > rewardUpdateHeight)
277+ else false)
278+ then {
279+ let reward = (currentRewardPerBlock * (height - lastInterestHeight))
280+ let newFarmInterest = (farmInterest + fraction(calcFarmRwd(pool, reward), scaleValue, shareTokenLocked))
281+ let newBoostInterest = (boostInterest + (if ((poolVoted > 0))
282+ then fraction(calcBoostRwd(pool, reward), scaleValue8, poolVoted)
283+ else 0))
284+ let newBoostLPInterest = (boostLpInterest + (if (if ((poolVoted > 0))
285+ then (shareTokenLocked > 0)
286+ else false)
287+ then fraction(fraction(calcBoostRwd(pool, reward), scaleValue8, shareTokenLocked), scaleValue8, poolVoted)
288+ else 0))
289+ $Tuple3(newFarmInterest, newBoostInterest, newBoostLPInterest)
290+ }
291+ else {
292+ let rwdBfrUpd = (previousRewardPerBlock * (rewardUpdateHeight - lastInterestHeight))
293+ let framIntrAftrUp = (farmInterest + fraction(calcFarmRwd(pool, rwdBfrUpd), scaleValue, shareTokenLocked))
294+ let boostIntrAftrUp = (boostInterest + (if ((poolVoted > 0))
295+ then fraction(calcBoostRwd(pool, rwdBfrUpd), scaleValue, poolVoted)
296+ else 0))
297+ let bostLPIntrAftrUp = (farmInterest + (if (if ((poolVoted > 0))
298+ then (shareTokenLocked > 0)
299+ else false)
300+ then fraction(calcBoostRwd(pool, rwdBfrUpd), scaleValue, poolVoted)
301+ else 0))
302+ let reward = (currentRewardPerBlock * (height - rewardUpdateHeight))
303+ let newFarmInterest = (framIntrAftrUp + fraction(calcFarmRwd(pool, reward), scaleValue, shareTokenLocked))
304+ let newBoostInterest = (boostIntrAftrUp + (if ((poolVoted > 0))
305+ then fraction(calcBoostRwd(pool, reward), scaleValue8, poolVoted)
306+ else 0))
307+ let newBoostLPInterest = (bostLPIntrAftrUp + (if (if ((poolVoted > 0))
308+ then (shareTokenLocked > 0)
309+ else false)
310+ then fraction(fraction(calcBoostRwd(pool, reward), scaleValue8, shareTokenLocked), scaleValue8, poolVoted)
311+ else 0))
312+ $Tuple3(newFarmInterest, newBoostInterest, newBoostLPInterest)
313+ }
314+
315+
316+func claimCalc (pool,user) = {
317+ let scaleValue = calcScaleValue(SWOP, getShareAssetId(pool))
318+ let poolVoted = getPoolVoted(pool)
319+ let uPoolVoted = getUserPoolVoted(pool, user)
320+ let shareToken = getTotalShareToken(pool)
321+ let totalShareVirtual = valueOrElse(getInteger(this, (pool + kShareTokensVirtual)), shareToken)
322+ let $t01440614504 = getLastInterestInfo(pool)
323+ let lastInterestHeight = $t01440614504._1
324+ let farmInterest = $t01440614504._2
325+ let boostInterest = $t01440614504._3
326+ let boostLPInterest = $t01440614504._4
327+ let $t01450914623 = rewardInfo(pool)
328+ let currentRewardPerBlock = $t01450914623._1
329+ let rewardUpdateHeight = $t01450914623._2
330+ let previousRewardPerBlock = $t01450914623._3
331+ let poolRewardUpdateHeight = $t01450914623._4
332+ let uFarmInterest = valueOrElse(getInteger(this, (((pool + "_") + user) + kFarmUserLastInterest)), farmInterest)
333+ let uBoostInterest = valueOrElse(getInteger(this, (((pool + "_") + user) + kBoostUserLastInterest)), boostInterest)
334+ let uBoostLPInterest = valueOrElse(getInteger(this, (((pool + "_") + user) + kBoostLPUserLastInterest)), boostLPInterest)
335+ let uShareTokensStaked = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensStaked)), 0)
336+ let uShareTokensVirt = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensVirtual)), uShareTokensStaked)
337+ let $t01519115584 = calcInterest(pool, lastInterestHeight, rewardUpdateHeight, poolRewardUpdateHeight, farmInterest, boostInterest, poolVoted, boostLPInterest, currentRewardPerBlock, totalShareVirtual, previousRewardPerBlock, scaleValue)
338+ let newFarmInterest = $t01519115584._1
339+ let newBoostInterest = $t01519115584._2
340+ let newBoostLPInterest = $t01519115584._3
341+ let claimFarming = fraction(uShareTokensVirt, (newFarmInterest - uFarmInterest), scaleValue)
342+ let claimBoostingMax = fraction(uPoolVoted, (newBoostInterest - uBoostInterest), scaleValue8)
343+ let claimBoosting = (fraction((uShareTokensVirt * uPoolVoted), (newBoostLPInterest - uBoostLPInterest), scaleValue8) / scaleValue8)
344+ let toTreasury = (claimBoostingMax - claimBoosting)
345+ $Tuple5(newFarmInterest, newBoostInterest, newBoostLPInterest, (claimFarming + claimBoosting), toTreasury)
346+ }
347+
348+
349+func canLockInFirstHarvest (pool,user,userShareTokensStaked,pmtAmount,lockType) = if ((getHeightFirstHarvest(pool) > height))
350+ then {
351+ let totalVoteAmount = valueOrElse(getInteger(votingAddress, (pool + kHarvestPoolVote)), 0)
352+ let userVoteAmount = valueOrElse(getInteger(votingAddress, (((user + "_") + pool) + kHarvestPoolVote)), 0)
353+ let FHShareTokenLimit = getFHShareLimitToken(addressFromStringValue(pool))
354+ let FHShareTokenUserLimit = (fraction(FHShareTokenLimit, userVoteAmount, totalVoteAmount) - userShareTokensStaked)
355+ if ((lockType > 0))
356+ then throw("You can't lock shareTokens till first harvest end.")
357+ else if ((userVoteAmount == 0))
358+ then 0
359+ else if ((pmtAmount >= FHShareTokenUserLimit))
360+ then (pmtAmount - FHShareTokenUserLimit)
361+ else 0
362+ }
363+ else 0
364+
365+
366+func getLockParams (type) = {
367+ let lockParams = split(valueOrErrorMessage(getString(this, (toString(type) + kLockParams)), ("There are no key for lock type" + toString(type))), "_")
368+ $Tuple2(parseIntValue(lockParams[0]), parseIntValue(lockParams[1]))
369+ }
370+
119371
120372 func suspend (cause) = [BooleanEntry(kActive, false), StringEntry(kCause, cause)]
121373
122374
123-func throwIsActive () = throw("DApp is already active")
124-
125-
126-func isActive () = if (active)
375+func isActive () = if (if (active)
376+ then activeGlob
377+ else false)
127378 then unit
128379 else throw("DApp is inactive at this moment")
129380
133384 else throw("Only admin can call this function")
134385
135386
136-func isSelfCall (i) = if ((this == i.caller))
137- then unit
138- else throw("Only contract itself can call this function")
139-
140-
141-let big2 = toBigInt(2)
142-
143-let iter10 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
144-
145-let iter15 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
146-
147-let iter16 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
148-
149-let blockTimestamp = height
150-
151-func assert (a) = if (a)
152- then false
153- else true
154-
155-
156-func calculateFeeDiscount (userAddr) = {
157- let user = match userAddr {
158- case u: Address =>
159- toString(u)
160- case u: String =>
161- u
162- case _ =>
163- throw("Unknow type of user Addr")
164- }
165- let swopAmount = valueOrElse(getInteger(govAddress, (user + kUserGSwopInGov)), 0)
166- let gSwopAmount = valueOrElse(getInteger(govAddress, (user + kUserGSwopInGov)), swopAmount)
167- let discountValues = split(getStringValue(oracle, kDiscountValues), ",")
168- let discounts = split(getStringValue(oracle, kDiscounts), ",")
169- if (if ((gSwopAmount >= parseIntValue(discountValues[0])))
170- then (parseIntValue(discountValues[1]) > gSwopAmount)
171- else false)
172- then (feeScale6 - parseIntValue(discounts[0]))
173- else if (if ((gSwopAmount >= parseIntValue(discountValues[1])))
174- then (parseIntValue(discountValues[2]) > gSwopAmount)
175- else false)
176- then (feeScale6 - parseIntValue(discounts[1]))
177- else if (if ((gSwopAmount >= parseIntValue(discountValues[2])))
178- then (parseIntValue(discountValues[3]) > gSwopAmount)
179- else false)
180- then (feeScale6 - parseIntValue(discounts[2]))
181- else if (if ((gSwopAmount >= parseIntValue(discountValues[3])))
182- then (parseIntValue(discountValues[4]) > gSwopAmount)
183- else false)
184- then (feeScale6 - parseIntValue(discounts[3]))
185- else if ((gSwopAmount >= parseIntValue(discountValues[4])))
186- then (feeScale6 - parseIntValue(discounts[4]))
187- else feeScale6
188- }
189-
190-
191-func _A () = {
192- let t1 = future_A_time
193- let A1 = future_A
194- if ((t1 > blockTimestamp))
195- then {
196- let A0 = initial_A
197- let t0 = initial_A_time
198- if ((A1 > A0))
199- then (A0 + (((A1 - A0) * (blockTimestamp - t0)) / (t1 - t0)))
200- else (A0 - (((A0 - A1) * (blockTimestamp - t0)) / (t1 - t0)))
201- }
202- else A1
203- }
204-
205-
206-func _xp () = {
207- func assetBalances (acc,assetId) = (acc :+ valueOrElse(getInteger(this, (assetId + kAssetBalance)), 0))
208-
209- let $l = assetIds
210- let $s = size($l)
211- let $acc0 = nil
212- func $f0_1 ($a,$i) = if (($i >= $s))
213- then $a
214- else assetBalances($a, $l[$i])
215-
216- func $f0_2 ($a,$i) = if (($i >= $s))
217- then $a
218- else throw("List size exceeds 10")
219-
220- $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)
221- }
222-
223-
224-func _xp_mem (xp) = xp
225-
226-
227-func sumList (acc,element) = (acc + element)
228-
229-
230-func get_D (xp,amp) = {
231- let @ = invoke(this, "D", [xp, amp], nil)
232- if ($isInstanceOf(@, "Int"))
233- then @
234- else throw(($getType(@) + " couldn't be cast to Int"))
235- }
236-
237-
238-func get_D_internal (xp,amp) = {
239- let S = {
240- let $l = xp
241- let $s = size($l)
242- let $acc0 = 0
243- func $f0_1 ($a,$i) = if (($i >= $s))
244- then $a
245- else sumList($a, $l[$i])
246-
247- func $f0_2 ($a,$i) = if (($i >= $s))
248- then $a
249- else throw("List size exceeds 10")
250-
251- $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)
252- }
253- if ((S == 0))
254- then 0
255- else {
256- let Ann = (amp * nCoins)
257- let AnnS = (toBigInt(Ann) * toBigInt(S))
258- let Ann1 = toBigInt((Ann - 1))
259- func Dproc (acc,i) = if ((acc._2 == true))
260- then acc
261- else {
262- let Dprev = acc._1
263- func D_PProc (D_P,i) = if ((nCoins > i))
264- then ((D_P * Dprev) / (toBigInt(xp[i]) * toBigInt(nCoins)))
265- else D_P
266-
267- let D_P = {
268- let $l = iter10
269- let $s = size($l)
270- let $acc0 = Dprev
271- func $f1_1 ($a,$i) = if (($i >= $s))
272- then $a
273- else D_PProc($a, $l[$i])
274-
275- func $f1_2 ($a,$i) = if (($i >= $s))
276- then $a
277- else throw("List size exceeds 10")
278-
279- $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)
280- }
281- let D = fraction((AnnS + (toBigInt(nCoins) * D_P)), Dprev, ((Ann1 * Dprev) + (toBigInt((nCoins + 1)) * D_P)))
282- if ((D > Dprev))
283- then if ((1 >= toInt((D - Dprev))))
284- then $Tuple2(D, true)
285- else $Tuple2(D, false)
286- else if ((1 >= toInt((Dprev - D))))
287- then $Tuple2(D, true)
288- else $Tuple2(D, false)
289- }
290-
291- let $t064616527 = {
292- let $l = iter15
293- let $s = size($l)
294- let $acc0 = $Tuple2(toBigInt(S), false)
295- func $f1_1 ($a,$i) = if (($i >= $s))
296- then $a
297- else Dproc($a, $l[$i])
298-
299- func $f1_2 ($a,$i) = if (($i >= $s))
300- then $a
301- else throw("List size exceeds 15")
302-
303- $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)
304- }
305- let D = $t064616527._1
306- let finished = $t064616527._2
307- if ((finished == false))
308- then throw(("get_D() not finished with " + toString(D)))
309- else toInt(D)
310- }
311- }
312-
313-
314-func getDMem (xp,amp) = get_D(_xp_mem(xp), amp)
315-
316-
317-func getY (in,out,x,xp_) = if (assert((in != out)))
318- then throw("same coin")
319- else if (assert(if ((out >= 0))
320- then (in >= 0)
321- else false))
322- then throw("below zero")
323- else if (assert(if ((nCoins > out))
324- then (nCoins > in)
325- else false))
326- then throw("above N_COINS")
327- else {
328- let amp = _A()
329- let D = get_D(xp_, amp)
330- let Ann = (amp * nCoins)
331- func S_c (acc,i) = {
332- let $t070987115 = acc
333- let S_ = $t070987115._1
334- let c = $t070987115._2
335- let x_ = if ((in == i))
336- then x
337- else xp_[i]
338- if (if ((i != out))
339- then (nCoins > i)
340- else false)
341- then $Tuple2((S_ + x_), fraction(c, toBigInt(D), toBigInt((x_ * nCoins))))
342- else $Tuple2(S_, c)
343- }
344-
345- let $t073237378 = {
346- let $l = iter10
347- let $s = size($l)
348- let $acc0 = $Tuple2(0, toBigInt(D))
349- func $f0_1 ($a,$i) = if (($i >= $s))
350- then $a
351- else S_c($a, $l[$i])
352-
353- func $f0_2 ($a,$i) = if (($i >= $s))
354- then $a
355- else throw("List size exceeds 10")
356-
357- $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)
358- }
359- let S_ = $t073237378._1
360- let c_ = $t073237378._2
361- let c = fraction(c_, toBigInt(D), toBigInt((Ann * nCoins)))
362- let bD = toBigInt(((S_ + (D / Ann)) - D))
363- func y_proc (acc,_i) = if ((acc._2 == true))
364- then acc
365- else {
366- let y_prev = acc._1
367- let y = (((y_prev * y_prev) + c) / ((big2 * y_prev) + bD))
368- if ((y > y_prev))
369- then if ((1 >= toInt((y - y_prev))))
370- then $Tuple2(y, true)
371- else $Tuple2(y, false)
372- else if ((1 >= toInt((y_prev - y))))
373- then $Tuple2(y, true)
374- else $Tuple2(y, false)
375- }
376-
377- let $t078607927 = {
378- let $l = iter16
379- let $s = size($l)
380- let $acc0 = $Tuple2(toBigInt(D), false)
381- func $f1_1 ($a,$i) = if (($i >= $s))
382- then $a
383- else y_proc($a, $l[$i])
384-
385- func $f1_2 ($a,$i) = if (($i >= $s))
386- then $a
387- else throw("List size exceeds 16")
388-
389- $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)
390- }
391- let y = $t078607927._1
392- let finished = $t078607927._2
393- if ((finished == false))
394- then throw(("getY() not finished with " + toString(y)))
395- else toInt(y)
396- }
397-
398-
399-func get_y_D (A_,in,xp,D) = if (assert((in >= 0)))
400- then throw("i below zero")
401- else if (assert((nCoins > in)))
402- then throw("i above N_COINS")
403- else {
404- let Ann = (A_ * nCoins)
405- func S_c (acc,i) = {
406- let $t083068323 = acc
407- let S_ = $t083068323._1
408- let c = $t083068323._2
409- let x_ = if (if ((in != i))
410- then (nCoins > i)
411- else false)
412- then xp[i]
413- else 0
414- if (if ((nCoins > i))
415- then (in != i)
416- else false)
417- then $Tuple2((S_ + x_), fraction(c, toBigInt(D), toBigInt((x_ * nCoins))))
418- else $Tuple2(S_, c)
419- }
420-
421- let $t085438598 = {
422- let $l = iter10
423- let $s = size($l)
424- let $acc0 = $Tuple2(0, toBigInt(D))
425- func $f0_1 ($a,$i) = if (($i >= $s))
426- then $a
427- else S_c($a, $l[$i])
428-
429- func $f0_2 ($a,$i) = if (($i >= $s))
430- then $a
431- else throw("List size exceeds 10")
432-
433- $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)
434- }
435- let S_ = $t085438598._1
436- let c_ = $t085438598._2
437- let c = fraction(c_, toBigInt(D), toBigInt((Ann * nCoins)))
438- let bD = toBigInt(((S_ + (D / Ann)) - D))
439- func y_D_proc (acc,i) = if ((acc._2 == true))
440- then acc
441- else {
442- let y_prev = acc._1
443- let y = (((y_prev * y_prev) + c) / ((big2 * y_prev) + bD))
444- if ((y > y_prev))
445- then if ((1 >= toInt((y - y_prev))))
446- then $Tuple2(y, true)
447- else $Tuple2(y, false)
448- else if ((1 >= toInt((y_prev - y))))
449- then $Tuple2(y, true)
450- else $Tuple2(y, false)
451- }
452-
453- let $t090819150 = {
454- let $l = iter16
455- let $s = size($l)
456- let $acc0 = $Tuple2(toBigInt(D), false)
457- func $f1_1 ($a,$i) = if (($i >= $s))
458- then $a
459- else y_D_proc($a, $l[$i])
460-
461- func $f1_2 ($a,$i) = if (($i >= $s))
462- then $a
463- else throw("List size exceeds 16")
464-
465- $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)
466- }
467- let y = $t090819150._1
468- let finished = $t090819150._2
469- if ((finished == false))
470- then throw(("get_y_D() not finished with " + toString(y)))
471- else toInt(y)
472- }
473-
474-
475-func _calcWithdrawOneCoin (xp,_token_amount,i,caller) = {
476- let feeDiscount = calculateFeeDiscount(caller)
477- let amp = _A()
478- let _fee = ((fraction(fee, feeDiscount, feeScale6, CEILING) * nCoins) / (4 * (nCoins - 1)))
479- let total_supply = shareSupply
480- let D0 = get_D(xp, amp)
481- let D1 = (D0 - fraction(_token_amount, D0, total_supply))
482- let new_y = get_y_D(amp, i, xp, D1)
483- let dy_0 = (xp[i] - new_y)
484- func xp_reduced_proc (acc,xp_j) = {
485- let $t097919820 = acc
486- let xp_reduced = $t097919820._1
487- let index = $t097919820._2
488- let dx_expected = if ((index == i))
489- then (fraction(xp_j, D1, D0) - new_y)
490- else (xp_j - fraction(xp_j, D1, D0))
491- $Tuple2((xp_reduced :+ (xp_j - fraction(_fee, dx_expected, feeScale6))), (index + 1))
492- }
493-
494- let $t01008210146 = {
495- let $l = xp
496- let $s = size($l)
497- let $acc0 = $Tuple2(nil, 0)
498- func $f0_1 ($a,$i) = if (($i >= $s))
499- then $a
500- else xp_reduced_proc($a, $l[$i])
501-
502- func $f0_2 ($a,$i) = if (($i >= $s))
503- then $a
504- else throw("List size exceeds 10")
505-
506- $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)
507- }
508- let xp_reduced = $t01008210146._1
509- let index = $t01008210146._2
510- let xp_reduced_i = xp_reduced[i]
511- let dy = ((xp_reduced_i - get_y_D(amp, i, xp_reduced, D1)) - 1)
512- $Tuple2(dy, (dy_0 - dy))
513- }
514-
515-
516-func getStrAssetId (assetId) = match assetId {
517- case id: ByteVector =>
518- toBase58String(id)
519- case waves: Unit =>
520- "WAVES"
521- case _ =>
522- throw("Match error")
523-}
524-
525-
526-func calcStakingFuncAndAddres (stake,assetId) = if (stake)
527- then $Tuple2("lockNeutrino", stakingUSDNAddress)
528- else $Tuple2("unlockNeutrino", stakingUSDNAddress)
529-
530-
531-func calcStakingParams (stake,amount,assetId) = if (stake)
532- then {
533- let $t01071010776 = calcStakingFuncAndAddres(stake, assetId)
534- let call = $t01071010776._1
535- let stakingAddr = $t01071010776._2
536- $Tuple4(call, stakingAddr, nil, [AttachedPayment(assetId, amount)])
537- }
387+@Callable(i)
388+func init (earlyLP) = if (isDefined(getString(this, kSWOPid)))
389+ then throw("SWOP already initialized")
538390 else {
539- let $t01086210928 = calcStakingFuncAndAddres(stake, assetId)
540- let call = $t01086210928._1
541- let stakingAddr = $t01086210928._2
542- $Tuple4(call, stakingAddr, [amount, toBase58String(assetId)], nil)
391+ let initAmount = 100000000000000
392+ let SWOPissue = Issue("SWOP", "SWOP protocol token", initAmount, 8, true)
393+ let SWOPid = calculateAssetId(SWOPissue)
394+[BooleanEntry(kActive, true), Issue("SWOP", "SWOP protocol token", initAmount, 8, true), StringEntry(kSWOPid, toBase58String(SWOPid))]
543395 }
544396
545397
546-func stake (amount,assetIdString) = if (containsElement(stakingAssets, assetIdString))
547- then {
548- let $t01111511217 = calcStakingParams(true, amount, fromBase58String(assetIdString))
549- let call = $t01111511217._1
550- let addr = $t01111511217._2
551- let params = $t01111511217._3
552- let payments = $t01111511217._4
553- invoke(addr, call, params, payments)
554- }
555- else 0
556398
557-
558-func unstake (amount,assetIdString) = if (containsElement(stakingAssets, assetIdString))
559- then {
560- let $t01140211505 = calcStakingParams(false, amount, fromBase58String(assetIdString))
561- let call = $t01140211505._1
562- let addr = $t01140211505._2
563- let params = $t01140211505._3
564- let payments = $t01140211505._4
565- invoke(addr, call, params, payments)
566- }
567- else 0
568-
569-
570-func stakedAmount (assetId) = {
571- let stakedAmountCalculated = match assetId {
572- case aId: ByteVector =>
573- if ((aId == USDN))
574- then getInteger(stakingUSDNAddress, ((("rpd_balance_" + toBase58String(aId)) + "_") + toString(this)))
575- else 0
576- case _: Unit =>
577- 0
578- case _ =>
579- throw("Match error")
580- }
581- match stakedAmountCalculated {
582- case i: Int =>
583- i
584- case _ =>
585- 0
586- }
587- }
588-
589-
590-func checkSuspicious () = {
591- let contractBalances = _xp()
592- func checkBalance (acc,assetId) = {
593- let $t01211612141 = acc
594- let suspicious = $t01211612141._1
595- let i = $t01211612141._2
596- if (suspicious)
597- then $Tuple2(suspicious, i)
598- else {
599- let aBalance = (assetBalance(this, fromBase58String(assetId)) + stakedAmount(fromBase58String(assetId)))
600- if ((contractBalances[i] > aBalance))
601- then $Tuple2(true, i)
602- else $Tuple2(false, (i + 1))
603- }
604- }
605-
606- let $l = assetIds
607- let $s = size($l)
608- let $acc0 = $Tuple2(false, 0)
609- func $f0_1 ($a,$i) = if (($i >= $s))
610- then $a
611- else checkBalance($a, $l[$i])
612-
613- func $f0_2 ($a,$i) = if (($i >= $s))
614- then $a
615- else throw("List size exceeds 10")
616-
617- $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)
618- }
619-
620-
621-func suspendSuspicious (i) = suspend(("Suspicious state with asset: " + assetIds[i]))
622-
623-
624-func returnPayments (caller,payments) = {
625- func parsePayments (acc,payment) = (acc :+ ScriptTransfer(caller, payment.amount, payment.assetId))
626-
627- let $l = payments
628- let $s = size($l)
629- let $acc0 = nil
630- func $f0_1 ($a,$i) = if (($i >= $s))
631- then $a
632- else parsePayments($a, $l[$i])
633-
634- func $f0_2 ($a,$i) = if (($i >= $s))
635- then $a
636- else throw("List size exceeds 10")
637-
638- $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)
639- }
640-
641-
642-func checkDAppThreshold (newBalances) = {
643- let dAppThresholdCoef = valueOrErrorMessage(getInteger(this, kDAppThresholdCoef), "No dAppThresholdCoef key")
644- let thresholdScale = 10000
645- let maxBalance = max(newBalances)
646- let minBalance = min(newBalances)
647- let ratio = fraction(maxBalance, thresholdScale, minBalance)
648- if ((ratio > (dAppThresholdCoef * thresholdScale)))
649- then throw("New balance in assets of the DApp is less than threshold")
650- else false
651- }
652-
653-
654-func checkCoins (assetIds) = {
655- let coins = split(assetIds, ",")
656- if ((size(coins) > 10))
657- then throw("To many coins, max coins size 10")
658- else {
659- func checkCoin (error,assetId) = {
660- let asset = valueOrErrorMessage(fromBase58String(assetId), ("fromBase58String: " + assetId))
661- let decimals = valueOrErrorMessage(assetInfo(asset), ("assetInfo: " + assetId)).decimals
662- if ((decimals != DECIMALS))
663- then throw("wrong decimals")
664- else false
665- }
666-
667- let $l = coins
668- let $s = size($l)
669- let $acc0 = false
670- func $f0_1 ($a,$i) = if (($i >= $s))
671- then $a
672- else checkCoin($a, $l[$i])
673-
674- func $f0_2 ($a,$i) = if (($i >= $s))
675- then $a
676- else throw("List size exceeds 10")
677-
678- $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)
679- }
680- }
681-
682-
683-@Callable(msg)
684-func D (xp,amp) = {
685- let D = get_D_internal(xp, amp)
686- $Tuple2([IntegerEntry("D", D)], D)
687- }
399+@Callable(i)
400+func initPoolShareFarming (pool) = valueOrElse(isAdminCall(i), [IntegerEntry((pool + kShareTotalShareTokens), 0), IntegerEntry((pool + kFarmLastInterest), 0), IntegerEntry((pool + kBoostLastInterest), 0), IntegerEntry((pool + kBoostLPLastInterest), 0), IntegerEntry((pool + kLastInterestHeight), height)])
688401
689402
690403
691-@Callable(msg)
692-func init (assetIds,_A,_dAppThresholdCoef) = if (!(isDataStorageUntouched(this)))
693- then throw("Already initialized")
694- else if ((0 >= _A))
695- then throw("Amp must be must > 0")
696- else if ((0 >= _dAppThresholdCoef))
697- then throw("dApp Threshold Coef must be > 0")
698- else {
699- let shareName = "s_Multi_USD"
700- let shareDescription = ("ShareToken of SwopFi protocol for MultiStable USD pool at address " + toString(this))
701- let issueToken = Issue(shareName, shareDescription, 0, 6, true)
702- let tokenId = calculateAssetId(issueToken)
703- if (checkCoins(assetIds))
704- then throw()
705- 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]
706- }
404+@Callable(i)
405+func updatePoolInterest (pool) = valueOrElse(isActive(), if ((i.caller != govAddress))
406+ then throw("Only Governance can call this function")
407+ else {
408+ let user = toString(addressFromPublicKey(adminInvokePubKey))
409+ let $t01861718691 = claimCalc(pool, user)
410+ let farmInterest = $t01861718691._1
411+ let boostInterest = $t01861718691._2
412+ let boostLPinterest = $t01861718691._3
413+[IntegerEntry((pool + kFarmLastInterest), farmInterest), IntegerEntry((pool + kBoostLastInterest), boostInterest), IntegerEntry((pool + kBoostLPLastInterest), boostLPinterest), IntegerEntry((pool + kLastInterestHeight), height)]
414+ })
707415
708416
709417
710-@Callable(msg)
711-func addLiquidity (minMintAmount,stakeFarming,lockType) = valueOrElse(isActive(), {
712- let amp = _A()
713- let xp = _xp()
714- let D0 = if ((shareSupply == 0))
715- then 0
716- else getDMem(xp, amp)
717- let $t01534915604 = if (if ((lockType > 0))
718- then (msg.payments[(size(msg.payments) - 1)].assetId == unit)
719- else false)
720- then $Tuple2(removeByIndex(msg.payments, (size(msg.payments) - 1)), [msg.payments[(size(msg.payments) - 1)]])
721- else $Tuple2(msg.payments, nil)
722- let payments = $t01534915604._1
723- let lockFee = $t01534915604._2
724- let paymentsSize = size(payments)
725- func validPayments (n) = if ((paymentsSize > nCoins))
726- then throw(("payments size > " + toString(nCoins)))
727- else if ((1 > paymentsSize))
728- then throw("payments size < 1")
729- else if (if ((shareSupply == 0))
730- then (nCoins != paymentsSize)
731- else false)
732- then throw("initial deposit requires all coins")
418+@Callable(i)
419+func lockShareTokens (pool,lockType) = valueOrElse(isActive(), {
420+ let shareAssetId = getShareAssetId(pool)
421+ let user = toString(i.originCaller)
422+ let totalShare = getTotalShareToken(pool)
423+ let totalShareVirtual = valueOrElse(getInteger(this, (pool + kShareTokensVirtual)), totalShare)
424+ let userStakedAmount = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensStaked)), 0)
425+ let userLockedHeigt = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensLockedHeight)), 0)
426+ let userLockedAmount = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensLocked)), 0)
427+ let userAmountVirtual = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensVirtual)), userStakedAmount)
428+ let totalUserShareTokens = ((userStakedAmount + userLockedAmount) + i.payments[0].amount)
429+ let $t01980019852 = getLockParams(lockType)
430+ let lockPeriod = $t01980019852._1
431+ let lockCoef = $t01980019852._2
432+ let lockWavesFee = getIntegerValue(this, kLockWavesFee)
433+ if ((i.payments[0].assetId != shareAssetId))
434+ then throw("Wrong sharetoken in payment")
435+ else if ((0 >= i.payments[0].amount))
436+ then throw("Payment amount must be greater than 0")
437+ else if ((0 > lockType))
438+ then throw("lockType must be >= 0")
733439 else {
734- func paymantValid (acc,payment) = if (containsElement(assetIds, getStrAssetId(payment.assetId)))
735- then true
736- else throw("Invalid asset in payment")
737-
738- let $l = payments
739- let $s = size($l)
740- let $acc0 = false
741- func $f0_1 ($a,$i) = if (($i >= $s))
742- then $a
743- else paymantValid($a, $l[$i])
744-
745- func $f0_2 ($a,$i) = if (($i >= $s))
746- then $a
747- else throw("List size exceeds 10")
748-
749- $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)
750- }
751-
752- if (!(validPayments(paymentsSize)))
753- then throw()
754- else {
755- let suspicious = checkSuspicious()
756- if (suspicious._1)
757- then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.caller, payments))
758- else {
759- func parsePayments (acc,assetId) = {
760- let $t01647416500 = acc
761- let newBalances = $t01647416500._1
762- let i = $t01647416500._2
763- func parsePayment (newBalance,payment) = if ((getStrAssetId(payment.assetId) == assetId))
764- then (newBalance + payment.amount)
765- else newBalance
766-
767- let newBalace = {
768- let $l = payments
769- let $s = size($l)
770- let $acc0 = xp[i]
771- func $f0_1 ($a,$i) = if (($i >= $s))
772- then $a
773- else parsePayment($a, $l[$i])
774-
775- func $f0_2 ($a,$i) = if (($i >= $s))
776- then $a
777- else throw("List size exceeds 10")
778-
779- $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)
780- }
781- $Tuple2((newBalances :+ newBalace), (i + 1))
782- }
783-
784- let $t01685016917 = {
785- let $l = assetIds
786- let $s = size($l)
787- let $acc0 = $Tuple2(nil, 0)
788- func $f0_1 ($a,$i) = if (($i >= $s))
789- then $a
790- else parsePayments($a, $l[$i])
791-
792- func $f0_2 ($a,$i) = if (($i >= $s))
793- then $a
794- else throw("List size exceeds 10")
795-
796- $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)
797- }
798- let newBalances = $t01685016917._1
799- let k = $t01685016917._2
800- if (checkDAppThreshold(newBalances))
801- then throw()
802- else {
803- let D1 = getDMem(newBalances, amp)
804- if (assert((D1 > D0)))
805- then throw("D1 > D0")
440+ let shareTokensChangeOnFH = canLockInFirstHarvest(pool, user, userStakedAmount, i.payments[0].amount, lockType)
441+ if ((shareTokensChangeOnFH == shareTokensChangeOnFH))
442+ then {
443+ let $t02027922124 = if ((lockType == 0))
444+ then {
445+ let userAmountVirtualNew = ((userAmountVirtual + i.payments[0].amount) - shareTokensChangeOnFH)
446+ $Tuple2([IntegerEntry((((pool + "_") + user) + kUserShareTokensStaked), ((userStakedAmount + i.payments[0].amount) - shareTokensChangeOnFH)), IntegerEntry((pool + kShareTokensVirtual), ((totalShareVirtual + i.payments[0].amount) - shareTokensChangeOnFH)), ScriptTransfer(i.originCaller, shareTokensChangeOnFH, i.payments[0].assetId)], ((totalShare + i.payments[0].amount) - shareTokensChangeOnFH))
447+ }
448+ else if (if ((userLockedHeigt == 0))
449+ then if (if ((2 > size(i.payments)))
450+ then true
451+ else (i.payments[1].assetId != unit))
452+ then true
453+ else (lockWavesFee > i.payments[1].amount)
454+ else false)
455+ then throw((("You need to pay additional waves comission " + toString(lockWavesFee)) + "WAVES"))
456+ else if ((userLockedHeigt > (height + lockPeriod)))
457+ then throw("You cannot lock sharetokens for a period less than what you have already locked")
458+ else {
459+ let userLockedAmountNew = (userLockedAmount + i.payments[0].amount)
460+ let userLockedHeigtNew = (height + lockPeriod)
461+ let userAmountVirtualNew = (fraction(userLockedAmountNew, lockCoef, lockBoostCoefScale) + userStakedAmount)
462+ $Tuple2([IntegerEntry((((pool + "_") + user) + kUserShareTokensLocked), userLockedAmountNew), IntegerEntry((((pool + "_") + user) + kUserShareTokensLockedHeight), userLockedHeigtNew), IntegerEntry((((pool + "_") + user) + kUserShareTokensLockedType), lockType), IntegerEntry((((pool + "_") + user) + kUserShareTokensVirtual), userAmountVirtualNew), IntegerEntry((pool + kShareTokensVirtual), ((totalShareVirtual - userAmountVirtual) + userAmountVirtualNew))], (totalShare + i.payments[0].amount))
463+ }
464+ let lockEntries = $t02027922124._1
465+ let totalShareNew = $t02027922124._2
466+ if ((accountBalance(shareAssetId) > totalShareNew))
467+ then throw("Balance of share-token is lower than totalAmount")
806468 else {
807- let feeDiscount = calculateFeeDiscount(msg.caller)
808- func calcScriptActions (acc,newBalance) = {
809- let $t01723717278 = acc
810- let invBalances = $t01723717278._1
811- let scriptActions = $t01723717278._2
812- let i = $t01723717278._3
813- if ((shareSupply > 0))
814- then {
815- let _fee = ((fraction(fee, feeDiscount, feeScale6, CEILING) * nCoins) / (4 * (nCoins - 1)))
816- let fees = {
817- let idealBalance = fraction(D1, xp[i], D0)
818- let difference = if ((idealBalance > newBalance))
819- then (idealBalance - newBalance)
820- else (newBalance - idealBalance)
821- fraction(_fee, difference, feeScale6)
822- }
823- let governanceFees = fraction(fees, feeGovernance, feeScale6)
824- let finalBalance = (newBalance - fees)
825- let invariantBalance = (newBalance - fees)
826- let pmt = (newBalance - xp[i])
827- let lpFees = (fees - governanceFees)
828- let inv = if ((pmt > 0))
829- then stake((pmt - fees), assetIds[i])
830- else unstake(fees, assetIds[i])
831- if ((inv == inv))
832- then {
833- let airdrop = if ((lpFees > 0))
834- then invoke(lpFarmingAddress, "airDrop", nil, [AttachedPayment(fromBase58String(assetIds[i]), lpFees)])
835- else 0
836- if ((airdrop == airdrop))
837- then $Tuple3((invBalances :+ invariantBalance), (scriptActions ++ [ScriptTransfer(moneyBoxAddress, governanceFees, fromBase58String(assetIds[i])), IntegerEntry((assetIds[i] + kAssetBalance), finalBalance)]), (i + 1))
838- else throw("Strict value is not equal to itself.")
839- }
840- else throw("Strict value is not equal to itself.")
841- }
842- else {
843- let inv = stake(newBalance, assetIds[i])
844- if ((inv == inv))
845- then $Tuple3((invBalances :+ newBalance), (scriptActions :+ IntegerEntry((assetIds[i] + kAssetBalance), newBalance)), (i + 1))
846- else throw("Strict value is not equal to itself.")
847- }
848- }
849-
850- let $t01898319071 = {
851- let $l = newBalances
852- let $s = size($l)
853- let $acc0 = $Tuple3(nil, nil, 0)
854- func $f1_1 ($a,$i) = if (($i >= $s))
855- then $a
856- else calcScriptActions($a, $l[$i])
857-
858- func $f1_2 ($a,$i) = if (($i >= $s))
859- then $a
860- else throw("List size exceeds 10")
861-
862- $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)
863- }
864- let invBalances = $t01898319071._1
865- let scriptActions = $t01898319071._2
866- let D2 = getDMem(invBalances, amp)
867- let mint_amount = if ((shareSupply == 0))
868- then D1
869- else fraction(shareSupply, (D2 - D0), D0)
870- if (assert((mint_amount >= minMintAmount)))
871- then throw("Slippage screwed you")
872- else if (stakeFarming)
873- then {
874- let re = invoke(this, "reissueShare", [mint_amount], nil)
875- if ((re == re))
876- then {
877- let s = invoke(farmingAddress, "lockShareTokens", [toString(this), lockType], ([AttachedPayment(shareAssetId, mint_amount)] ++ lockFee))
878- if ((s == s))
879- then (scriptActions :+ IntegerEntry(kShareAssetSupply, (shareSupply + mint_amount)))
880- else throw("Strict value is not equal to itself.")
881- }
882- else throw("Strict value is not equal to itself.")
883- }
884- else (scriptActions ++ [Reissue(shareAssetId, mint_amount, true), ScriptTransfer(msg.caller, mint_amount, shareAssetId), IntegerEntry(kShareAssetSupply, (shareSupply + mint_amount))])
469+ let $t02224922348 = claimCalc(pool, user)
470+ let farmInterest = $t02224922348._1
471+ let boostInterest = $t02224922348._2
472+ let boostLPinterest = $t02224922348._3
473+ let claimAmount = $t02224922348._4
474+ let toTreasure = $t02224922348._5
475+ let availableFundsNew = (userAvailableSWOP(pool, i.originCaller) + claimAmount)
476+ let uplp = if ((getString(Address(fromBase58String(pool)), "version") == "3.0.0"))
477+ then invoke(lpFarmingAddress, "updateUserInterest", [pool, totalUserShareTokens], nil)
478+ else 0
479+ if ((uplp == uplp))
480+ then ([IntegerEntry((((pool + "_") + user) + kFarmUserLastInterest), farmInterest), IntegerEntry((((pool + "_") + user) + kBoostUserLastInterest), boostInterest), IntegerEntry((((pool + "_") + user) + kBoostLPLastInterest), boostLPinterest), IntegerEntry((pool + kFarmLastInterest), farmInterest), IntegerEntry((pool + kBoostLastInterest), boostInterest), IntegerEntry((pool + kBoostLPLastInterest), boostLPinterest), IntegerEntry((pool + kLastInterestHeight), height), IntegerEntry((pool + kShareTotalShareTokens), totalShareNew), IntegerEntry((((pool + "_") + user) + kAvailableSWOP), availableFundsNew), Reissue(SWOP, toTreasure, true), ScriptTransfer(farmingTreasureAddr, toTreasure, SWOP)] ++ lockEntries)
481+ else throw("Strict value is not equal to itself.")
885482 }
886483 }
484+ else throw("Strict value is not equal to itself.")
887485 }
486+ })
487+
488+
489+
490+@Callable(i)
491+func lockStakedShareTokens (pool,lockType,lockAmount) = valueOrElse(isActive(), {
492+ let shareAssetId = getShareAssetId(pool)
493+ let user = toString(i.originCaller)
494+ let totalShare = getTotalShareToken(pool)
495+ let totalShareVirtual = valueOrElse(getInteger(this, (pool + kShareTokensVirtual)), totalShare)
496+ let userStakedAmount = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensStaked)), 0)
497+ let userLockedHeigt = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensLockedHeight)), 0)
498+ let userLockedAmount = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensLocked)), 0)
499+ let userAmountVirtual = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensVirtual)), userStakedAmount)
500+ let totalUserShareTokens = (userStakedAmount + userLockedAmount)
501+ let $t02425624308 = getLockParams(lockType)
502+ let lockPeriod = $t02425624308._1
503+ let lockCoef = $t02425624308._2
504+ let lockWavesFee = getIntegerValue(this, kLockWavesFee)
505+ if ((getHeightFirstHarvest(pool) > height))
506+ then throw("You can't lock shareTokens till first harvest end.")
507+ else if ((0 >= lockType))
508+ then throw("lockType must be > 0")
509+ else if ((lockAmount > userStakedAmount))
510+ then throw(("You can't lock more than " + toString(userStakedAmount)))
511+ else if ((accountBalance(shareAssetId) > totalShare))
512+ then throw("Balance of share-token is lower than totalAmount")
513+ else if (if ((userLockedHeigt == 0))
514+ then if (if ((1 > size(i.payments)))
515+ then true
516+ else (i.payments[0].assetId != unit))
517+ then true
518+ else (lockWavesFee > i.payments[0].amount)
519+ else false)
520+ then throw((("You need to pay additional waves comission " + toString(lockWavesFee)) + "WAVES"))
521+ else if (if ((userLockedHeigt == 0))
522+ then (0 >= lockAmount)
523+ else false)
524+ then throw("lockAmount must be greater than 0")
525+ else if ((0 > lockAmount))
526+ then throw("lockAmount must be positive")
527+ else if ((userLockedHeigt > (height + lockPeriod)))
528+ then throw("You cannot lock sharetokens for a period less than what you have already locked")
529+ else {
530+ let userLockedAmountNew = (userLockedAmount + lockAmount)
531+ let userStakedAmountNew = (userStakedAmount - lockAmount)
532+ let userLockedHeigtNew = (height + lockPeriod)
533+ let userAmountVirtualNew = (fraction(userLockedAmountNew, lockCoef, lockBoostCoefScale) + userStakedAmount)
534+ let $t02559525694 = claimCalc(pool, user)
535+ let farmInterest = $t02559525694._1
536+ let boostInterest = $t02559525694._2
537+ let boostLPinterest = $t02559525694._3
538+ let claimAmount = $t02559525694._4
539+ let toTreasure = $t02559525694._5
540+ let availableFundsNew = (userAvailableSWOP(pool, i.originCaller) + claimAmount)
541+[IntegerEntry((((pool + "_") + user) + kUserShareTokensStaked), userStakedAmountNew), IntegerEntry((((pool + "_") + user) + kUserShareTokensLocked), userLockedAmountNew), IntegerEntry((((pool + "_") + user) + kUserShareTokensLockedHeight), userLockedHeigtNew), IntegerEntry((((pool + "_") + user) + kUserShareTokensLockedType), lockType), IntegerEntry((((pool + "_") + user) + kUserShareTokensVirtual), userAmountVirtualNew), IntegerEntry((pool + kShareTokensVirtual), ((totalShareVirtual - userAmountVirtual) + userAmountVirtualNew)), IntegerEntry((((pool + "_") + user) + kFarmUserLastInterest), farmInterest), IntegerEntry((((pool + "_") + user) + kBoostUserLastInterest), boostInterest), IntegerEntry((((pool + "_") + user) + kBoostLPLastInterest), boostLPinterest), IntegerEntry((pool + kFarmLastInterest), farmInterest), IntegerEntry((pool + kBoostLastInterest), boostInterest), IntegerEntry((pool + kBoostLPLastInterest), boostLPinterest), IntegerEntry((pool + kLastInterestHeight), height), IntegerEntry((((pool + "_") + user) + kAvailableSWOP), availableFundsNew), Reissue(SWOP, toTreasure, true), ScriptTransfer(farmingTreasureAddr, toTreasure, SWOP)]
542+ }
543+ })
544+
545+
546+
547+@Callable(i)
548+func unlockUserLock (pool,user) = valueOrElse(isActive(), {
549+ let lockWavesFee = getIntegerValue(this, kLockWavesFee)
550+ let userLockedHeigt = valueOrErrorMessage(getInteger(this, (((pool + "_") + user) + kUserShareTokensLockedHeight)), (((("There is no pool " + pool) + " or user ") + user) + "with lock"))
551+ let totalShareVirtual = getIntegerValue(this, (pool + kShareTokensVirtual))
552+ let userStakedAmount = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensStaked)), 0)
553+ let userLockedAmount = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensLocked)), 0)
554+ let userAmountVirtual = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensVirtual)), userStakedAmount)
555+ if ((userLockedHeigt > height))
556+ then throw(("You can't unlock sharetokens till " + toString(userLockedHeigt)))
557+ else {
558+ let userStakedAmountNew = (userStakedAmount + userLockedAmount)
559+ let $t02793028029 = claimCalc(pool, user)
560+ let farmInterest = $t02793028029._1
561+ let boostInterest = $t02793028029._2
562+ let boostLPinterest = $t02793028029._3
563+ let claimAmount = $t02793028029._4
564+ let toTreasure = $t02793028029._5
565+ let availableFundsNew = (userAvailableSWOP(pool, i.originCaller) + claimAmount)
566+[IntegerEntry((((pool + "_") + user) + kFarmUserLastInterest), farmInterest), IntegerEntry((((pool + "_") + user) + kBoostUserLastInterest), boostInterest), IntegerEntry((((pool + "_") + user) + kBoostLPLastInterest), boostLPinterest), IntegerEntry((pool + kFarmLastInterest), farmInterest), IntegerEntry((pool + kBoostLastInterest), boostInterest), IntegerEntry((pool + kBoostLPLastInterest), boostLPinterest), IntegerEntry((pool + kLastInterestHeight), height), IntegerEntry((((pool + "_") + user) + kUserShareTokensStaked), userStakedAmountNew), IntegerEntry((((pool + "_") + user) + kUserShareTokensVirtual), userStakedAmountNew), IntegerEntry((pool + kShareTokensVirtual), ((totalShareVirtual - userAmountVirtual) + userStakedAmountNew)), DeleteEntry((((pool + "_") + user) + kUserShareTokensLocked)), DeleteEntry((((pool + "_") + user) + kUserShareTokensLockedHeight)), DeleteEntry((((pool + "_") + user) + kUserShareTokensLockedType)), Reissue(SWOP, toTreasure, true), ScriptTransfer(farmingTreasureAddr, toTreasure, SWOP), ScriptTransfer(i.caller, lockWavesFee, unit)]
888567 }
889568 })
890569
891570
892571
893-@Callable(msg)
894-func calcMintAmount (newBalances,user) = {
895- let amp = _A()
896- let xp = _xp()
897- let D1 = getDMem(newBalances, amp)
898- if ((shareSupply == 0))
899- then $Tuple2(nil, D1)
900- else {
901- let D0 = getDMem(xp, amp)
902- let feeDiscount = calculateFeeDiscount(user)
903- func calcInvBalances (acc,newBalance) = {
904- let $t02032120347 = acc
905- let invBalances = $t02032120347._1
906- let i = $t02032120347._2
907- let _fee = ((fraction(fee, feeDiscount, feeScale6, CEILING) * nCoins) / (4 * (nCoins - 1)))
908- let fees = {
909- let idealBalance = fraction(D1, xp[i], D0)
910- let difference = if ((idealBalance > newBalance))
911- then (idealBalance - newBalance)
912- else (newBalance - idealBalance)
913- fraction(_fee, difference, feeScale6)
914- }
915- let invariantBalance = (newBalance - fees)
916- $Tuple2((invBalances :+ invariantBalance), (i + 1))
572+@Callable(i)
573+func withdrawShareTokens (pool,shareTokensWithdrawAmount) = valueOrElse(isActive(), {
574+ let shareTokensId = fromBase58String(getStringValue(value(addressFromString(pool)), "share_asset_id"))
575+ let user = toString(i.originCaller)
576+ let $t02953329632 = claimCalc(pool, user)
577+ let farmInterest = $t02953329632._1
578+ let boostInterest = $t02953329632._2
579+ let boostLPinterest = $t02953329632._3
580+ let claimAmount = $t02953329632._4
581+ let toTreasure = $t02953329632._5
582+ let userStakedAmount = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensStaked)), 0)
583+ let userLockedAmount = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensLocked)), 0)
584+ let userAmountVirtual = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensVirtual)), userStakedAmount)
585+ let userStakedAmountNew = (userStakedAmount - shareTokensWithdrawAmount)
586+ let availableFundsNew = (userAvailableSWOP(pool, i.originCaller) + claimAmount)
587+ let totalShareAmount = getTotalShareToken(pool)
588+ let totalShareVirtual = valueOrElse(getInteger(this, (pool + kShareTokensVirtual)), totalShareAmount)
589+ let totalShareAmountNew = (totalShareAmount - shareTokensWithdrawAmount)
590+ let totalShareVirtualNew = (totalShareVirtual - shareTokensWithdrawAmount)
591+ let userAmountVirtualNew = (userAmountVirtual - shareTokensWithdrawAmount)
592+ if ((shareTokensWithdrawAmount > userStakedAmount))
593+ then throw("Withdraw amount more then user locked amount")
594+ else if ((accountBalance(shareTokensId) > totalShareAmount))
595+ then throw("Balance of share-token is lower than totalAmount")
596+ else {
597+ let uplp = if ((getString(Address(fromBase58String(pool)), "version") == "3.0.0"))
598+ then invoke(lpFarmingAddress, "updateUserInterest", [pool, (userStakedAmount + userLockedAmount)], nil)
599+ else 0
600+ if ((uplp == uplp))
601+ then [IntegerEntry((((pool + "_") + user) + kFarmUserLastInterest), farmInterest), IntegerEntry((((pool + "_") + user) + kBoostUserLastInterest), boostInterest), IntegerEntry((((pool + "_") + user) + kBoostLPLastInterest), boostLPinterest), IntegerEntry((pool + kFarmLastInterest), farmInterest), IntegerEntry((pool + kBoostLastInterest), boostInterest), IntegerEntry((pool + kBoostLPLastInterest), boostLPinterest), IntegerEntry((pool + kLastInterestHeight), height), IntegerEntry((((pool + "_") + user) + kUserShareTokensStaked), userStakedAmountNew), IntegerEntry((((pool + "_") + user) + kUserShareTokensVirtual), userAmountVirtualNew), IntegerEntry((pool + kShareTotalShareTokens), totalShareAmountNew), IntegerEntry((pool + kShareTokensVirtual), totalShareVirtualNew), IntegerEntry((((pool + "_") + user) + kAvailableSWOP), availableFundsNew), Reissue(SWOP, toTreasure, true), ScriptTransfer(farmingTreasureAddr, toTreasure, SWOP), ScriptTransfer(i.caller, shareTokensWithdrawAmount, shareTokensId)]
602+ else throw("Strict value is not equal to itself.")
917603 }
918-
919- let $t02094921019 = {
920- let $l = newBalances
921- let $s = size($l)
922- let $acc0 = $Tuple2(nil, 0)
923- func $f0_1 ($a,$i) = if (($i >= $s))
924- then $a
925- else calcInvBalances($a, $l[$i])
926-
927- func $f0_2 ($a,$i) = if (($i >= $s))
928- then $a
929- else throw("List size exceeds 10")
930-
931- $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)
932- }
933- let invBalances = $t02094921019._1
934- let k = $t02094921019._2
935- let D2 = getDMem(invBalances, amp)
936- let mintAmount = fraction(shareSupply, (D2 - D0), D0)
937- $Tuple2(nil, mintAmount)
938- }
939- }
604+ })
940605
941606
942607
943-@Callable(msg)
944-func reissueShare (amount) = valueOrElse(isSelfCall(msg), [Reissue(shareAssetId, amount, true)])
608+@Callable(i)
609+func claim (pool) = valueOrElse(isActive(), {
610+ let shareTokensId = fromBase58String(getStringValue(value(addressFromString(pool)), "share_asset_id"))
611+ let user = toString(i.caller)
612+ let shareTokenLocked = getTotalShareToken(pool)
613+ let $t03230132400 = claimCalc(pool, user)
614+ let farmInterest = $t03230132400._1
615+ let boostInterest = $t03230132400._2
616+ let boostLPinterest = $t03230132400._3
617+ let claimAmount = $t03230132400._4
618+ let toTreasure = $t03230132400._5
619+ let availableFund = (userAvailableSWOP(pool, i.caller) + claimAmount)
620+ if ((availableFund == 0))
621+ then throw("You have 0 available SWOP")
622+ else if ((accountBalance(shareTokensId) > shareTokenLocked))
623+ then throw("Balance of share-token is lower than totalAmount")
624+ else $Tuple2([IntegerEntry((((pool + "_") + user) + kFarmUserLastInterest), farmInterest), IntegerEntry((((pool + "_") + user) + kBoostUserLastInterest), boostInterest), IntegerEntry((((pool + "_") + user) + kBoostLPLastInterest), boostLPinterest), IntegerEntry((pool + kFarmLastInterest), farmInterest), IntegerEntry((pool + kBoostLastInterest), boostInterest), IntegerEntry((pool + kBoostLPLastInterest), boostLPinterest), IntegerEntry((pool + kLastInterestHeight), height), IntegerEntry((((pool + "_") + user) + kAvailableSWOP), 0), Reissue(SWOP, (toTreasure + availableFund), true), ScriptTransfer(farmingTreasureAddr, toTreasure, SWOP), ScriptTransfer(i.caller, availableFund, SWOP)], availableFund)
625+ })
945626
946627
947628
948-@Callable(msg)
949-func getDy (assetFrom,assetTo,dx,userAddress) = {
950- let xp = _xp()
951- let fromIndex = valueOrErrorMessage(indexOf(assetIds, assetFrom), "unknown token in")
952- let toIndex = valueOrErrorMessage(indexOf(assetIds, assetTo), "unknown token out")
953- let x = (xp[fromIndex] + dx)
954- let y = getY(fromIndex, toIndex, x, xp)
955- let dy = ((xp[toIndex] - y) - 1)
956- let feeDiscount = calculateFeeDiscount(Address(fromBase58String(userAddress)))
957- let _fee = fraction(fraction(fee, feeDiscount, feeScale6, CEILING), dy, feeScale6)
958- $Tuple2(nil, $Tuple2((dy - _fee), _fee))
959- }
629+@Callable(i)
630+func claimAndStake (pool) = valueOrElse(isActive(), {
631+ let claimAmount = {
632+ let @ = invoke(this, "claim", [pool], nil)
633+ if ($isInstanceOf(@, "Int"))
634+ then @
635+ else throw(($getType(@) + " couldn't be cast to Int"))
636+ }
637+ if ((claimAmount == claimAmount))
638+ then {
639+ let stakeToGov = invoke(govAddress, "lockSWOPFromFarming", nil, [AttachedPayment(SWOP, claimAmount)])
640+ if ((stakeToGov == stakeToGov))
641+ then nil
642+ else throw("Strict value is not equal to itself.")
643+ }
644+ else throw("Strict value is not equal to itself.")
645+ })
960646
961647
962648
963-@Callable(msg)
964-func exchange (tokenOut,min_dy) = valueOrElse(isActive(), if ((size(msg.payments) != 1))
965- then throw("size(payments) != 1")
649+@Callable(i)
650+func claimAll (pools) = valueOrElse(isActive(), {
651+ func claimInv (claimTotal,pool) = {
652+ let claimAmount = {
653+ let @ = invoke(this, "claim", [pool], nil)
654+ if ($isInstanceOf(@, "Int"))
655+ then @
656+ else throw(($getType(@) + " couldn't be cast to Int"))
657+ }
658+ if ((claimAmount == claimAmount))
659+ then (claimTotal + claimAmount)
660+ else throw("Strict value is not equal to itself.")
661+ }
662+
663+ let claimTotal = {
664+ let $l = pools
665+ let $s = size($l)
666+ let $acc0 = 0
667+ func $f0_1 ($a,$i) = if (($i >= $s))
668+ then $a
669+ else claimInv($a, $l[$i])
670+
671+ func $f0_2 ($a,$i) = if (($i >= $s))
672+ then $a
673+ else throw("List size exceeds 60")
674+
675+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60)
676+ }
677+ if ((claimTotal == 0))
678+ then throw("You have 0 available SWOP")
679+ else [ScriptTransfer(i.caller, claimTotal, SWOP)]
680+ })
681+
682+
683+
684+@Callable(i)
685+func claimAllAndStake (pools) = valueOrElse(isActive(), {
686+ func claimInv (claimTotal,pool) = {
687+ let claimAmount = {
688+ let @ = invoke(this, "claim", [pool], nil)
689+ if ($isInstanceOf(@, "Int"))
690+ then @
691+ else throw(($getType(@) + " couldn't be cast to Int"))
692+ }
693+ if ((claimAmount == claimAmount))
694+ then (claimTotal + claimAmount)
695+ else throw("Strict value is not equal to itself.")
696+ }
697+
698+ let claimTotal = {
699+ let $l = pools
700+ let $s = size($l)
701+ let $acc0 = 0
702+ func $f0_1 ($a,$i) = if (($i >= $s))
703+ then $a
704+ else claimInv($a, $l[$i])
705+
706+ func $f0_2 ($a,$i) = if (($i >= $s))
707+ then $a
708+ else throw("List size exceeds 60")
709+
710+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60)
711+ }
712+ if ((claimTotal == 0))
713+ then throw("You have 0 available SWOP")
714+ else {
715+ let stakeToGov = invoke(govAddress, "lockSWOPFromFarming", nil, [AttachedPayment(SWOP, claimTotal)])
716+ if ((stakeToGov == stakeToGov))
717+ then nil
718+ else throw("Strict value is not equal to itself.")
719+ }
720+ })
721+
722+
723+
724+@Callable(i)
725+func updateUserBoostInterest (pool,user) = valueOrElse(isActive(), if ((i.caller != votingAddress))
726+ then throw("Only voiting can call this function")
966727 else {
967- let suspicious = checkSuspicious()
968- if (suspicious._1)
969- then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.caller, msg.payments))
970- else {
971- let payment = msg.payments[0]
972- let tokenIn = getStrAssetId(payment.assetId)
973- let tokenOutB58 = fromBase58String(tokenOut)
974- let dx = payment.amount
975- let fromIndex = valueOrErrorMessage(indexOf(assetIds, tokenIn), "unknown token in")
976- let toIndex = valueOrErrorMessage(indexOf(assetIds, tokenOut), "unknown token out")
977- let xp = _xp()
978- let x = (xp[fromIndex] + dx)
979- let y = getY(fromIndex, toIndex, x, xp)
980- let _dy = ((xp[toIndex] - y) - 1)
981- let feeDiscount = calculateFeeDiscount(msg.originCaller)
982- let _fee = fraction(_dy, fraction(fee, feeDiscount, feeScale6, CEILING), feeScale6)
983- let dy = (_dy - _fee)
984- let governanceFees = fraction(_fee, feeGovernance, feeScale6)
985- if (assert((dy >= min_dy)))
986- then throw("Exchange resulted in fewer coins than expected")
987- else {
988- func makeNewBalances (acc,tokenBalance) = {
989- let $t02306023086 = acc
990- let newBalances = $t02306023086._1
991- let i = $t02306023086._2
992- if ((i == fromIndex))
993- then $Tuple2((newBalances :+ (tokenBalance + dx)), (i + 1))
994- else if ((i == toIndex))
995- then $Tuple2((newBalances :+ (tokenBalance - _dy)), (i + 1))
996- else $Tuple2((newBalances :+ tokenBalance), (i + 1))
997- }
998-
999- let $t02333723398 = {
1000- let $l = xp
1001- let $s = size($l)
1002- let $acc0 = $Tuple2(nil, 0)
1003- func $f0_1 ($a,$i) = if (($i >= $s))
1004- then $a
1005- else makeNewBalances($a, $l[$i])
1006-
1007- func $f0_2 ($a,$i) = if (($i >= $s))
1008- then $a
1009- else throw("List size exceeds 10")
1010-
1011- $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)
1012- }
1013- let newBalances = $t02333723398._1
1014- let i = $t02333723398._2
1015- if (checkDAppThreshold(newBalances))
1016- then throw()
1017- else {
1018- let s = stake(payment.amount, getStrAssetId(payment.assetId))
1019- if ((s == s))
1020- then {
1021- let us = unstake(_dy, tokenOut)
1022- if ((us == us))
1023- then {
1024- let lpFees = (_fee - governanceFees)
1025- let airdrop = if ((lpFees > 0))
1026- then invoke(lpFarmingAddress, "airDrop", nil, [AttachedPayment(tokenOutB58, lpFees)])
1027- else 0
1028- if ((airdrop == airdrop))
1029- then $Tuple2([IntegerEntry((tokenIn + kAssetBalance), x), IntegerEntry((tokenOut + kAssetBalance), (xp[toIndex] - _dy)), ScriptTransfer(msg.caller, dy, tokenOutB58), ScriptTransfer(moneyBoxAddress, governanceFees, tokenOutB58)], [dy, tokenOutB58])
1030- else throw("Strict value is not equal to itself.")
1031- }
1032- else throw("Strict value is not equal to itself.")
1033- }
1034- else throw("Strict value is not equal to itself.")
1035- }
1036- }
1037- }
728+ let $t03478034879 = claimCalc(pool, user)
729+ let farmInterest = $t03478034879._1
730+ let boostInterest = $t03478034879._2
731+ let boostLPinterest = $t03478034879._3
732+ let claimAmount = $t03478034879._4
733+ let toTreasure = $t03478034879._5
734+ let availableFundsNew = (userAvailableSWOP(pool, i.originCaller) + claimAmount)
735+[IntegerEntry((((pool + "_") + user) + kFarmUserLastInterest), farmInterest), IntegerEntry((((pool + "_") + user) + kBoostUserLastInterest), boostInterest), IntegerEntry((((pool + "_") + user) + kBoostLPLastInterest), boostLPinterest), IntegerEntry((pool + kFarmLastInterest), farmInterest), IntegerEntry((pool + kBoostLastInterest), boostInterest), IntegerEntry((pool + kBoostLPLastInterest), boostLPinterest), IntegerEntry((pool + kLastInterestHeight), height), IntegerEntry((((pool + "_") + user) + kAvailableSWOP), availableFundsNew), Reissue(SWOP, toTreasure, true), ScriptTransfer(farmingTreasureAddr, toTreasure, SWOP)]
1038736 })
1039737
1040738
1041739
1042-@Callable(msg)
1043-func withdraw (minAmounts) = valueOrElse(isActive(), if ((size(msg.payments) != 1))
1044- then throw("size(payments) != 1")
1045- else {
1046- let pmtAmount = msg.payments[0].amount
1047- let pmtAssetId = msg.payments[0].assetId
1048- if ((shareAssetId != pmtAssetId))
1049- then throw("unknown payment token")
1050- else {
1051- let suspicious = checkSuspicious()
1052- if (suspicious._1)
1053- then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.originCaller, msg.payments))
1054- else {
1055- func calcScriptActions (acc,balance) = {
1056- let $t02468924717 = acc
1057- let scriptActions = $t02468924717._1
1058- let i = $t02468924717._2
1059- let wAmount = fraction(balance, pmtAmount, shareSupply)
1060- if (assert((wAmount >= minAmounts[i])))
1061- then throw("Withdrawal resulted in fewer coins than expected")
1062- else {
1063- let us = unstake(wAmount, assetIds[i])
1064- if ((us == us))
1065- then $Tuple2((scriptActions ++ [IntegerEntry((assetIds[i] + kAssetBalance), (balance - wAmount)), ScriptTransfer(msg.originCaller, wAmount, fromBase58String(assetIds[i]))]), (i + 1))
1066- else throw("Strict value is not equal to itself.")
1067- }
1068- }
1069-
1070- let $t02520725275 = {
1071- let $l = _xp()
1072- let $s = size($l)
1073- let $acc0 = $Tuple2(nil, 0)
1074- func $f0_1 ($a,$i) = if (($i >= $s))
1075- then $a
1076- else calcScriptActions($a, $l[$i])
1077-
1078- func $f0_2 ($a,$i) = if (($i >= $s))
1079- then $a
1080- else throw("List size exceeds 10")
1081-
1082- $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)
1083- }
1084- let scriptActions = $t02520725275._1
1085- let i = $t02520725275._2
1086- (scriptActions ++ [Burn(shareAssetId, pmtAmount), IntegerEntry(kShareAssetSupply, (shareSupply - pmtAmount))])
1087- }
1088- }
1089- })
1090-
1091-
1092-
1093-@Callable(msg)
1094-func withdrawWithUnlock (minAmounts,unlockAmount) = valueOrElse(isActive(), if ((0 >= unlockAmount))
1095- then throw("Unlock amount must be positive")
1096- else {
1097- let suspicious = checkSuspicious()
1098- if (suspicious._1)
1099- then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.caller, msg.payments))
1100- else {
1101- let pmtAmount = if ((size(msg.payments) > 0))
1102- then if ((size(msg.payments) != 1))
1103- then throw("size(payments) != 1")
1104- else {
1105- let pmtAssetId = msg.payments[0].assetId
1106- if ((shareAssetId != pmtAssetId))
1107- then throw("unknown payment token")
1108- else msg.payments[0].amount
1109- }
1110- else 0
1111- let unlock = invoke(farmingAddress, "withdrawShareTokens", [toString(this), unlockAmount], nil)
1112- if ((unlock == unlock))
1113- then {
1114- let withdrawAmount = (pmtAmount + unlockAmount)
1115- let inv = invoke(this, "withdraw", [minAmounts], [AttachedPayment(shareAssetId, withdrawAmount)])
1116- if ((inv == inv))
1117- then nil
1118- else throw("Strict value is not equal to itself.")
1119- }
1120- else throw("Strict value is not equal to itself.")
1121- }
1122- })
1123-
1124-
1125-
1126-@Callable(msg)
1127-func calcWithdrawOneCoin (tokenAmount,tokenOut,user) = if ((0 >= tokenAmount))
1128- then throw("Amount must be positive")
1129- else {
1130- let i = valueOrErrorMessage(indexOf(assetIds, tokenOut), "unknown token out")
1131- $Tuple2(nil, _calcWithdrawOneCoin(_xp(), tokenAmount, i, Address(fromBase58String(user)))._1)
1132- }
1133-
1134-
1135-
1136-@Callable(msg)
1137-func withdrawOneCoin (tokenOut,minAmount) = valueOrElse(isActive(), if ((size(msg.payments) != 1))
1138- then throw("size(payments) != 1")
1139- else {
1140- let suspicious = checkSuspicious()
1141- if (suspicious._1)
1142- then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.originCaller, msg.payments))
1143- else {
1144- let pmtAmount = msg.payments[0].amount
1145- let pmtAssetId = msg.payments[0].assetId
1146- if ((pmtAssetId != shareAssetId))
1147- then throw("unknown token")
1148- else {
1149- let outIndex = valueOrErrorMessage(indexOf(assetIds, tokenOut), "unknown token out")
1150- let tokenOutB58 = fromBase58String(tokenOut)
1151- let xp = _xp()
1152- let $t02730727389 = _calcWithdrawOneCoin(xp, pmtAmount, outIndex, msg.originCaller)
1153- let dy = $t02730727389._1
1154- let dy_fee = $t02730727389._2
1155- if (assert((dy >= minAmount)))
1156- then throw("Not enough coins removed")
1157- else {
1158- let governanceFees = fraction(dy_fee, feeGovernance, feeScale6)
1159- let dy_and_fee = (dy + dy_fee)
1160- func makeNewBalances (acc,tokenBalance) = {
1161- let $t02764727673 = acc
1162- let newBalances = $t02764727673._1
1163- let i = $t02764727673._2
1164- if ((i == outIndex))
1165- then $Tuple2((newBalances :+ (tokenBalance - dy_and_fee)), (i + 1))
1166- else $Tuple2((newBalances :+ tokenBalance), (i + 1))
1167- }
1168-
1169- let $t02784027901 = {
1170- let $l = xp
1171- let $s = size($l)
1172- let $acc0 = $Tuple2(nil, 0)
1173- func $f0_1 ($a,$i) = if (($i >= $s))
1174- then $a
1175- else makeNewBalances($a, $l[$i])
1176-
1177- func $f0_2 ($a,$i) = if (($i >= $s))
1178- then $a
1179- else throw("List size exceeds 10")
1180-
1181- $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)
1182- }
1183- let newBalances = $t02784027901._1
1184- let v = $t02784027901._2
1185- if (checkDAppThreshold(newBalances))
1186- then throw()
1187- else {
1188- let us = unstake(dy_and_fee, tokenOut)
1189- if ((us == us))
1190- then {
1191- let lpFees = (dy_fee - governanceFees)
1192- let airdrop = if ((lpFees > 0))
1193- then invoke(lpFarmingAddress, "airDrop", nil, [AttachedPayment(tokenOutB58, lpFees)])
1194- else 0
1195- if ((airdrop == airdrop))
1196- 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))]
1197- else throw("Strict value is not equal to itself.")
1198- }
1199- else throw("Strict value is not equal to itself.")
1200- }
1201- }
1202- }
1203- }
1204- })
1205-
1206-
1207-
1208-@Callable(msg)
1209-func withdrawOneCoinWithUnlock (tokenOut,minAmount,unlockAmount) = valueOrElse(isActive(), if ((0 >= unlockAmount))
1210- then throw("Unlock amount must be positive")
1211- else {
1212- let suspicious = checkSuspicious()
1213- if (suspicious._1)
1214- then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.caller, msg.payments))
1215- else {
1216- let pmtAmount = if ((size(msg.payments) > 0))
1217- then if ((size(msg.payments) != 1))
1218- then throw("size(payments) != 1")
1219- else {
1220- let pmtAssetId = msg.payments[0].assetId
1221- if ((shareAssetId != pmtAssetId))
1222- then throw("unknown payment token")
1223- else msg.payments[0].amount
1224- }
1225- else 0
1226- let unlock = invoke(farmingAddress, "withdrawShareTokens", [toString(this), unlockAmount], nil)
1227- if ((unlock == unlock))
1228- then {
1229- let withdrawAmount = (pmtAmount + unlockAmount)
1230- let inv = invoke(this, "withdrawOneCoin", [tokenOut, minAmount], [AttachedPayment(shareAssetId, withdrawAmount)])
1231- if ((inv == inv))
1232- then nil
1233- else throw("Strict value is not equal to itself.")
1234- }
1235- else throw("Strict value is not equal to itself.")
1236- }
1237- })
1238-
1239-
1240-
1241-@Callable(msg)
1242-func A () = $Tuple2(nil, _A())
1243-
1244-
1245-
1246-@Callable(msg)
1247-func getVirtualPrice () = {
1248- let D = get_D(_xp(), _A())
1249- $Tuple2(nil, fraction(D, PRECISION, shareSupply))
1250- }
1251-
1252-
1253-
1254-@Callable(msg)
1255-func calcTokenAmount (amounts,deposit) = {
1256- let amp = _A()
1257- let balances = _xp()
1258- let D0 = getDMem(balances, amp)
1259- func calcNewBalances (acc,balance) = {
1260- let $t02991829944 = acc
1261- let newBalances = $t02991829944._1
1262- let i = $t02991829944._2
1263- let newBalance = (balance + (if (deposit)
1264- then amounts[i]
1265- else -(amounts[i])))
1266- $Tuple2((newBalances :+ newBalance), (i + 1))
1267- }
1268-
1269- let newBalances = ( let $l = balances
1270- let $s = size($l)
1271- let $acc0 = $Tuple2(nil, 0)
1272- func $f0_1 ($a,$i) = if (($i >= $s))
1273- then $a
1274- else calcNewBalances($a, $l[$i])
1275-
1276- func $f0_2 ($a,$i) = if (($i >= $s))
1277- then $a
1278- else throw("List size exceeds 10")
1279-
1280- $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
1281- let D1 = getDMem(newBalances, amp)
1282- let diff = if (deposit)
1283- then (D1 - D0)
1284- else (D0 - D1)
1285- $Tuple2(nil, fraction(diff, shareSupply, D0))
1286- }
1287-
1288-
1289-
1290-@Callable(msg)
1291-func rampA (_futureA,_futureTime) = valueOrElse(isActive(), valueOrElse(isAdminCall(msg), if (assert((blockTimestamp >= (initial_A_time + MIN_RAMP_TIME))))
1292- then throw("too often")
1293- else if (assert((_futureTime >= (blockTimestamp + MIN_RAMP_TIME))))
1294- then throw("insufficient time")
1295- else {
1296- let _initial_A = _A()
1297- if (assert(if ((_futureA > 0))
1298- then (MAX_A > _futureA)
1299- else false))
1300- then throw("out of base range")
1301- else if (assert(if (if ((_futureA >= _initial_A))
1302- then ((_initial_A * MAX_A_CHANGE) >= _futureA)
1303- else false)
1304- then true
1305- else if ((_initial_A > _futureA))
1306- then ((_futureA * MAX_A_CHANGE) >= _initial_A)
1307- else false))
1308- then throw("out of range")
1309- else [IntegerEntry("initial_A", _initial_A), IntegerEntry("future_A", _futureA), IntegerEntry("initial_A_time", blockTimestamp), IntegerEntry("future_A_time", _futureTime)]
1310- }))
1311-
1312-
1313-
1314-@Callable(msg)
1315-func stopRampA () = valueOrElse(isActive(), valueOrElse(isAdminCall(msg), {
1316- let currentA = _A()
1317-[IntegerEntry("initial_A", currentA), IntegerEntry("future_A", currentA), IntegerEntry("initial_A_time", blockTimestamp), IntegerEntry("future_A_time", blockTimestamp)]
1318- }))
1319-
1320-
1321-
1322-@Callable(msg)
1323-func shutdown () = valueOrElse(isAdminCall(msg), if (!(active))
740+@Callable(i)
741+func shutdown () = valueOrElse(isAdminCall(i), if (!(active))
1324742 then throw(("DApp is already suspended. Cause: " + valueOrElse(getString(this, kCause), "the cause wasn't specified")))
1325743 else suspend("Paused by admin"))
1326744
1327745
1328746
1329-@Callable(msg)
1330-func activate () = valueOrElse(isAdminCall(msg), if (active)
1331- then throwIsActive()
747+@Callable(i)
748+func activate () = valueOrElse(isAdminCall(i), if (active)
749+ then throw("DApp is already active")
1332750 else [BooleanEntry(kActive, true), DeleteEntry(kCause)])
1333751
1334752
1335-
1336-@Callable(msg)
1337-func takeIntoAccountExtraFunds () = valueOrElse(isActive(), if ((msg.caller != moneyBoxAddress))
1338- then throw("Only the wallet can call this function")
1339- else {
1340- let balances = _xp()
1341- func takeExtraFunds (acc,assetId) = {
1342- let $t03228632304 = acc
1343- let sum = $t03228632304._1
1344- let i = $t03228632304._2
1345- let tokenB58 = fromBase58String(assetId)
1346- let rBalance = (assetBalance(this, tokenB58) + stakedAmount(tokenB58))
1347- let enrollAmount = (rBalance - balances[i])
1348- if ((0 > enrollAmount))
1349- then suspend(("Enroll amount negative for asset" + assetId))
1350- else {
1351- let airdrop = if ((enrollAmount > 0))
1352- then invoke(lpFarmingAddress, "airDrop", nil, [AttachedPayment(tokenB58, enrollAmount)])
1353- else 0
1354- if ((airdrop == airdrop))
1355- then $Tuple2((sum + enrollAmount), (i + 1))
1356- else throw("Strict value is not equal to itself.")
1357- }
1358- }
1359-
1360- let k = {
1361- let $l = assetIds
1362- let $s = size($l)
1363- let $acc0 = $Tuple2(0, 0)
1364- func $f0_1 ($a,$i) = if (($i >= $s))
1365- then $a
1366- else takeExtraFunds($a, $l[$i])
1367-
1368- func $f0_2 ($a,$i) = if (($i >= $s))
1369- then $a
1370- else throw("List size exceeds 10")
1371-
1372- $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)
1373- }
1374- if ((k._1 == 0))
1375- then throw("No money to take")
1376- else nil
1377- })
1378-
1379-
1380753 @Verifier(tx)
1381-func verify () = {
1382- let multiSignedByAdmins = {
754+func verify () = match tx {
755+ case _ =>
1383756 let adminPubKey1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
1384757 then 1
1385758 else 0
1390763 then 1
1391764 else 0
1392765 (((adminPubKey1Signed + adminPubKey2Signed) + adminPubKey3Signed) >= 2)
1393- }
1394- match tx {
1395- case inv: InvokeScriptTransaction =>
1396- let callTakeIntoAccount = if ((inv.dApp == this))
1397- then (inv.function == "takeIntoAccountExtraFunds")
1398- else false
1399- let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
1400- then true
1401- else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey2))
1402- then true
1403- else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey3))
1404- then true
1405- else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKeyInvoke)
1406- if (if (callTakeIntoAccount)
1407- then signedByAdmin
1408- else false)
1409- then true
1410- else multiSignedByAdmins
1411- case _ =>
1412- multiSignedByAdmins
1413- }
1414- }
766+}
1415767
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let PRECISION = 1000000
4+let kActive = "active"
55
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"
6+let kActiveGlob = "active_all_contracts"
237
248 let kCause = "shutdown_cause"
259
26-let kShareAssetId = "share_asset_id"
10+let kRewardPoolFractionCurrent = "_current_pool_fraction_reward"
2711
28-let kShareAssetSupply = "share_asset_supply"
12+let kRewardPoolFractionPrevious = "_previous_pool_fraction_reward"
2913
30-let kFee = "commission"
14+let kHeightPoolFraction = "_pool_reward_update_height"
3115
32-let kDAppThresholdCoef = "dAppThresholdCoef"
16+let kTotalRewardPerBlockCurrent = "total_reward_per_block_current"
3317
34-let kUSDNAddress = "staking_usdnnsbt_address"
18+let kTotalRewardPerBlockPrevious = "total_reward_per_block_previous"
3519
36-let kDiscounts = "discounts"
20+let kRewardUpdateHeight = "reward_update_height"
3721
38-let kDiscountValues = "discount_values"
22+let kUserShareTokensStaked = "_share_tokens_locked"
3923
40-let kUserSwopInGov = "_SWOP_amount"
24+let kUserShareTokensLocked = "_share_tokens_blocked"
4125
42-let kUserGSwopInGov = "_GSwop_amount"
26+let kUserShareTokensLockedType = "_share_tokens_blocked_type"
27+
28+let kUserShareTokensLockedHeight = "_share_tokens_blocked_height"
29+
30+let kUserShareTokensVirtual = "_share_tokens_virtual"
31+
32+let kShareTotalShareTokens = "_total_share_tokens_locked"
33+
34+let kShareTokensVirtual = "_total_share_tokens_virtual"
35+
36+let kLockParams = "_lock_params"
37+
38+let kLockWavesFee = "lock_waves_fee"
39+
40+let kPoolBoostCoef = "_boost_coef"
41+
42+let kFarmLastInterest = "_last_interest"
43+
44+let kFarmUserLastInterest = "_last_interest"
45+
46+let kBoostLastInterest = "_last_interest_b"
47+
48+let kBoostUserLastInterest = "_last_interest_u_b"
49+
50+let kBoostLPLastInterest = "_last_interest_lpb"
51+
52+let kBoostLPUserLastInterest = "_last_interest_u_lpb"
53+
54+let kLastInterestHeight = "_last_interest_height"
55+
56+let kSWOPid = "SWOP_id"
57+
58+let kAvailableSWOP = "_available_SWOP"
59+
60+let kSwopYearEmission = "swop_year_emission"
61+
62+let kHarvestPoolVote = "_harvest_pool_vote_gSWOP"
63+
64+let kPoolVote = "_pool_vote_gSWOP"
65+
66+let kUserPoolVote = "_user_vote_gSWOP"
67+
68+let kHarvestUserPoolVote = "_harvest_user_pool_vote_gSWOP"
69+
70+let kBasePeriod = "base_period"
71+
72+let kPeriodLength = "period_length"
73+
74+let kStartHeight = "start_height"
75+
76+let kFirstHarvestHeight = "first_harvest_height"
77+
78+let kShareLimitFH = "share_limit_on_first_harvest"
4379
4480 let kAdminPubKey1 = "admin_pub_1"
4581
4682 let kAdminPubKey2 = "admin_pub_2"
4783
4884 let kAdminPubKey3 = "admin_pub_3"
4985
5086 let kAdminInvokePubKey = "admin_invoke_pub"
5187
5288 let kMoneyBoxAddress = "money_box_address"
5389
54-let kGovAddress = "governance_address"
55-
5690 let kVotingAddress = "voting_address"
5791
58-let kFarmingAddress = "farming_address"
92+let kGovAddress = "governance_address"
5993
6094 let kLPFarmingAddress = "lp_farming"
6195
96+let kFarmingTreasureAddr = "farming_treasure"
97+
6298 let oracle = Address(base58'3MvVBtsXroQpy1tsPw21TU2ET9A8WfmrNjz')
99+
100+let totalVoteShare = 10000000000
101+
102+let scaleValue8 = 100000000
103+
104+let lockBoostCoefScale = 1000
105+
106+let defPoolBoostCoef = 500
63107
64108 func getBase58FromOracle (key) = match getString(oracle, key) {
65109 case string: String =>
66110 fromBase58String(string)
67111 case nothing =>
68112 throw((key + "is empty"))
69113 }
70114
71115
72116 let adminPubKey1 = getBase58FromOracle(kAdminPubKey1)
73117
74118 let adminPubKey2 = getBase58FromOracle(kAdminPubKey2)
75119
76120 let adminPubKey3 = getBase58FromOracle(kAdminPubKey3)
77121
78-let adminPubKeyInvoke = getBase58FromOracle(kAdminInvokePubKey)
122+let moneyBoxAddress = Address(getBase58FromOracle(kMoneyBoxAddress))
79123
80-let moneyBoxAddress = Address(getBase58FromOracle(kMoneyBoxAddress))
124+let votingAddress = Address(getBase58FromOracle(kVotingAddress))
81125
82126 let govAddress = Address(getBase58FromOracle(kGovAddress))
83127
84-let stakingUSDNAddress = Address(getBase58FromOracle(kUSDNAddress))
85-
86-let votingAddress = Address(getBase58FromOracle(kVotingAddress))
87-
88-let farmingAddress = Address(getBase58FromOracle(kFarmingAddress))
128+let adminInvokePubKey = getBase58FromOracle(kAdminInvokePubKey)
89129
90130 let lpFarmingAddress = Address(getBase58FromOracle(kLPFarmingAddress))
91131
92-let USDN = base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p'
132+let farmingTreasureAddr = Address(getBase58FromOracle(kFarmingTreasureAddr))
93133
94-let stakingAssets = [toBase58String(USDN)]
134+let basePeriod = valueOrErrorMessage(getInteger(votingAddress, kBasePeriod), "Empty kBasePeriod")
135+
136+let startHeight = valueOrErrorMessage(getInteger(votingAddress, kStartHeight), "Empty kStartHeight")
137+
138+let periodLength = valueOrErrorMessage(getInteger(votingAddress, kPeriodLength), "Empty kPeriodLength")
139+
140+let currPeriod = (basePeriod + ((height - startHeight) / periodLength))
95141
96142 let active = getBooleanValue(this, kActive)
97143
98-let shareAssetId = fromBase58String(getStringValue(this, kShareAssetId))
144+let activeGlob = valueOrElse(getBoolean(oracle, kActiveGlob), true)
99145
100-let shareSupply = getIntegerValue(this, kShareAssetSupply)
146+let SwopYearEmission = getIntegerValue(this, kSwopYearEmission)
101147
102-let feeScale6 = 1000000
148+let SWOP = fromBase58String(getStringValue(this, kSWOPid))
103149
104-let fee = getIntegerValue(this, kFee)
150+func getHeightFirstHarvest (pool) = valueOrElse(getInteger(Address(fromBase58String(pool)), kFirstHarvestHeight), 0)
105151
106-let feeGovernance = fraction(40, feeScale6, 100)
107152
108-let initial_A = getIntegerValue(this, "initial_A")
153+func getFHShareLimitToken (pool) = valueOrErrorMessage(getInteger(pool, kShareLimitFH), ("No data on the key: " + kShareLimitFH))
109154
110-let future_A = getIntegerValue(this, "future_A")
111155
112-let initial_A_time = valueOrElse(getInteger(this, "initial_A_time"), 0)
156+func getTotalShareToken (pool) = valueOrErrorMessage(getInteger(this, (pool + kShareTotalShareTokens)), (("No data on the key: " + pool) + kShareTotalShareTokens))
113157
114-let future_A_time = valueOrElse(getInteger(this, "future_A_time"), 0)
115158
116-let assetIds = split(getStringValue(this, kAssets), ",")
159+func getPoolVoted (pool) = valueOrElse(getInteger(votingAddress, (pool + kPoolVote)), 0)
117160
118-let nCoins = size(assetIds)
161+
162+func getUserPoolVoted (pool,user) = valueOrElse(getInteger(votingAddress, (((user + "_") + pool) + kPoolVote)), 0)
163+
164+
165+func getShareAssetId (pool) = fromBase58String(getStringValue(value(addressFromString(pool)), "share_asset_id"))
166+
167+
168+func accountBalance (assetId) = match assetId {
169+ case id: ByteVector =>
170+ assetBalance(this, id)
171+ case waves: Unit =>
172+ wavesBalance(this).available
173+ case _ =>
174+ throw("Match error")
175+}
176+
177+
178+func getAssetInfo (assetId) = match assetId {
179+ case id: ByteVector =>
180+ let stringId = toBase58String(id)
181+ let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
182+ $Tuple3(stringId, info.name, info.decimals)
183+ case waves: Unit =>
184+ $Tuple3("WAVES", "WAVES", 8)
185+ case _ =>
186+ throw("Match error")
187+}
188+
189+
190+func calcScaleValue (assetId1,assetId2) = {
191+ let assetId1Decimals = value(assetInfo(assetId1)).decimals
192+ let assetId2Decimals = value(assetInfo(assetId2)).decimals
193+ let scaleDigits = ((assetId2Decimals - assetId1Decimals) + 8)
194+ pow(10, 0, scaleDigits, 0, 0, DOWN)
195+ }
196+
197+
198+func userAvailableSWOP (pool,user) = valueOrElse(getInteger(this, (((pool + "_") + toString(user)) + kAvailableSWOP)), 0)
199+
200+
201+func rewardInfo (pool) = {
202+ let totalRewardPerBlockCurrent = valueOrErrorMessage(getInteger(govAddress, kTotalRewardPerBlockCurrent), ((("No data on the key: " + kTotalRewardPerBlockCurrent) + " at address ") + toString(govAddress)))
203+ let totalRewardPerBlockPrevious = valueOrErrorMessage(getInteger(govAddress, kTotalRewardPerBlockPrevious), ((("No data on the key: " + kTotalRewardPerBlockPrevious) + " at address ") + toString(govAddress)))
204+ let rewardPoolFractionCurrent = valueOrErrorMessage(getInteger(govAddress, (pool + kRewardPoolFractionCurrent)), (((("No data on the key: " + pool) + kRewardPoolFractionCurrent) + " at address ") + toString(govAddress)))
205+ let rewardUpdateHeight = valueOrErrorMessage(getInteger(govAddress, kRewardUpdateHeight), ((("No data on the key: " + kRewardUpdateHeight) + " at address ") + toString(govAddress)))
206+ let poolRewardUpdateHeight = valueOrElse(getInteger(govAddress, (pool + kHeightPoolFraction)), rewardUpdateHeight)
207+ let rewardPoolFractionPrevious = valueOrErrorMessage(getInteger(govAddress, (pool + kRewardPoolFractionPrevious)), (((("No data on the key: " + pool) + kRewardPoolFractionPrevious) + " at address ") + toString(govAddress)))
208+ let rewardPoolCurrent = fraction(totalRewardPerBlockCurrent, rewardPoolFractionCurrent, totalVoteShare)
209+ let rewardPoolPrevious = fraction(totalRewardPerBlockCurrent, rewardPoolFractionPrevious, totalVoteShare)
210+ if (if ((rewardPoolCurrent > totalRewardPerBlockCurrent))
211+ then true
212+ else (rewardPoolPrevious > totalRewardPerBlockPrevious))
213+ then throw("rewardPoolCurrent > totalRewardPerBlockCurrent or rewardPoolPrevious > totalRewardPerBlockPrevious")
214+ else $Tuple4(rewardPoolCurrent, rewardUpdateHeight, rewardPoolPrevious, poolRewardUpdateHeight)
215+ }
216+
217+
218+func getLastInterestInfo (pool) = {
219+ let farmInterest = valueOrErrorMessage(getInteger(this, (pool + kFarmLastInterest)), (("No data on the key: " + pool) + kFarmLastInterest))
220+ let boostInterest = valueOrErrorMessage(getInteger(this, (pool + kFarmLastInterest)), (("No data on the key: " + pool) + kBoostLastInterest))
221+ let boostLPInterest = valueOrErrorMessage(getInteger(this, (pool + kFarmLastInterest)), (("No data on the key: " + pool) + kBoostLPLastInterest))
222+ let lastInterestHeight = valueOrElse(getInteger(this, (pool + kLastInterestHeight)), height)
223+ $Tuple4(lastInterestHeight, farmInterest, boostInterest, boostLPInterest)
224+ }
225+
226+
227+func calcFarmRwd (pool,curTotalReward) = {
228+ let poolBoostCoef = valueOrElse(getInteger(this, (pool + kPoolBoostCoef)), defPoolBoostCoef)
229+ ((curTotalReward / (poolBoostCoef + 1000)) / lockBoostCoefScale)
230+ }
231+
232+
233+func calcBoostRwd (pool,curTotalReward) = {
234+ let poolBoostCoef = valueOrElse(getInteger(this, (pool + kPoolBoostCoef)), defPoolBoostCoef)
235+ (fraction(curTotalReward, poolBoostCoef, (poolBoostCoef + 1000)) / lockBoostCoefScale)
236+ }
237+
238+
239+func calcInterest (pool,lastInterestHeight,rewardUpdateHeight,poolRewardUpdateHeight,farmInterest,boostInterest,poolVoted,boostLpInterest,currentRewardPerBlock,shareTokenLocked,previousRewardPerBlock,scaleValue) = if ((shareTokenLocked == 0))
240+ then $Tuple3(0, 0, 0)
241+ else if (if ((rewardUpdateHeight > height))
242+ then (rewardUpdateHeight == poolRewardUpdateHeight)
243+ else false)
244+ then {
245+ let reward = (previousRewardPerBlock * (height - lastInterestHeight))
246+ let newFarmInterest = (farmInterest + fraction(calcFarmRwd(pool, reward), scaleValue, shareTokenLocked))
247+ let newBoostInterest = (boostInterest + (if ((poolVoted > 0))
248+ then fraction(calcBoostRwd(pool, reward), scaleValue8, poolVoted)
249+ else 0))
250+ let newBoostLPInterest = (boostLpInterest + (if (if ((poolVoted > 0))
251+ then (shareTokenLocked > 0)
252+ else false)
253+ then fraction(fraction(calcBoostRwd(pool, reward), scaleValue8, shareTokenLocked), scaleValue8, poolVoted)
254+ else 0))
255+ $Tuple3(newFarmInterest, newBoostInterest, newBoostLPInterest)
256+ }
257+ else if (if ((height > rewardUpdateHeight))
258+ then (rewardUpdateHeight != poolRewardUpdateHeight)
259+ else false)
260+ then {
261+ let reward = (previousRewardPerBlock * (height - lastInterestHeight))
262+ let newFarmInterest = (farmInterest + fraction(calcFarmRwd(pool, reward), scaleValue, shareTokenLocked))
263+ let newBoostInterest = (boostInterest + (if ((poolVoted > 0))
264+ then fraction(calcBoostRwd(pool, reward), scaleValue8, poolVoted)
265+ else 0))
266+ let newBoostLPInterest = (boostLpInterest + (if (if ((poolVoted > 0))
267+ then (shareTokenLocked > 0)
268+ else false)
269+ then fraction(fraction(calcBoostRwd(pool, reward), scaleValue8, shareTokenLocked), scaleValue8, poolVoted)
270+ else 0))
271+ $Tuple3(newFarmInterest, newBoostInterest, newBoostLPInterest)
272+ }
273+ else if (if (if ((height > rewardUpdateHeight))
274+ then (rewardUpdateHeight == poolRewardUpdateHeight)
275+ else false)
276+ then (lastInterestHeight > rewardUpdateHeight)
277+ else false)
278+ then {
279+ let reward = (currentRewardPerBlock * (height - lastInterestHeight))
280+ let newFarmInterest = (farmInterest + fraction(calcFarmRwd(pool, reward), scaleValue, shareTokenLocked))
281+ let newBoostInterest = (boostInterest + (if ((poolVoted > 0))
282+ then fraction(calcBoostRwd(pool, reward), scaleValue8, poolVoted)
283+ else 0))
284+ let newBoostLPInterest = (boostLpInterest + (if (if ((poolVoted > 0))
285+ then (shareTokenLocked > 0)
286+ else false)
287+ then fraction(fraction(calcBoostRwd(pool, reward), scaleValue8, shareTokenLocked), scaleValue8, poolVoted)
288+ else 0))
289+ $Tuple3(newFarmInterest, newBoostInterest, newBoostLPInterest)
290+ }
291+ else {
292+ let rwdBfrUpd = (previousRewardPerBlock * (rewardUpdateHeight - lastInterestHeight))
293+ let framIntrAftrUp = (farmInterest + fraction(calcFarmRwd(pool, rwdBfrUpd), scaleValue, shareTokenLocked))
294+ let boostIntrAftrUp = (boostInterest + (if ((poolVoted > 0))
295+ then fraction(calcBoostRwd(pool, rwdBfrUpd), scaleValue, poolVoted)
296+ else 0))
297+ let bostLPIntrAftrUp = (farmInterest + (if (if ((poolVoted > 0))
298+ then (shareTokenLocked > 0)
299+ else false)
300+ then fraction(calcBoostRwd(pool, rwdBfrUpd), scaleValue, poolVoted)
301+ else 0))
302+ let reward = (currentRewardPerBlock * (height - rewardUpdateHeight))
303+ let newFarmInterest = (framIntrAftrUp + fraction(calcFarmRwd(pool, reward), scaleValue, shareTokenLocked))
304+ let newBoostInterest = (boostIntrAftrUp + (if ((poolVoted > 0))
305+ then fraction(calcBoostRwd(pool, reward), scaleValue8, poolVoted)
306+ else 0))
307+ let newBoostLPInterest = (bostLPIntrAftrUp + (if (if ((poolVoted > 0))
308+ then (shareTokenLocked > 0)
309+ else false)
310+ then fraction(fraction(calcBoostRwd(pool, reward), scaleValue8, shareTokenLocked), scaleValue8, poolVoted)
311+ else 0))
312+ $Tuple3(newFarmInterest, newBoostInterest, newBoostLPInterest)
313+ }
314+
315+
316+func claimCalc (pool,user) = {
317+ let scaleValue = calcScaleValue(SWOP, getShareAssetId(pool))
318+ let poolVoted = getPoolVoted(pool)
319+ let uPoolVoted = getUserPoolVoted(pool, user)
320+ let shareToken = getTotalShareToken(pool)
321+ let totalShareVirtual = valueOrElse(getInteger(this, (pool + kShareTokensVirtual)), shareToken)
322+ let $t01440614504 = getLastInterestInfo(pool)
323+ let lastInterestHeight = $t01440614504._1
324+ let farmInterest = $t01440614504._2
325+ let boostInterest = $t01440614504._3
326+ let boostLPInterest = $t01440614504._4
327+ let $t01450914623 = rewardInfo(pool)
328+ let currentRewardPerBlock = $t01450914623._1
329+ let rewardUpdateHeight = $t01450914623._2
330+ let previousRewardPerBlock = $t01450914623._3
331+ let poolRewardUpdateHeight = $t01450914623._4
332+ let uFarmInterest = valueOrElse(getInteger(this, (((pool + "_") + user) + kFarmUserLastInterest)), farmInterest)
333+ let uBoostInterest = valueOrElse(getInteger(this, (((pool + "_") + user) + kBoostUserLastInterest)), boostInterest)
334+ let uBoostLPInterest = valueOrElse(getInteger(this, (((pool + "_") + user) + kBoostLPUserLastInterest)), boostLPInterest)
335+ let uShareTokensStaked = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensStaked)), 0)
336+ let uShareTokensVirt = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensVirtual)), uShareTokensStaked)
337+ let $t01519115584 = calcInterest(pool, lastInterestHeight, rewardUpdateHeight, poolRewardUpdateHeight, farmInterest, boostInterest, poolVoted, boostLPInterest, currentRewardPerBlock, totalShareVirtual, previousRewardPerBlock, scaleValue)
338+ let newFarmInterest = $t01519115584._1
339+ let newBoostInterest = $t01519115584._2
340+ let newBoostLPInterest = $t01519115584._3
341+ let claimFarming = fraction(uShareTokensVirt, (newFarmInterest - uFarmInterest), scaleValue)
342+ let claimBoostingMax = fraction(uPoolVoted, (newBoostInterest - uBoostInterest), scaleValue8)
343+ let claimBoosting = (fraction((uShareTokensVirt * uPoolVoted), (newBoostLPInterest - uBoostLPInterest), scaleValue8) / scaleValue8)
344+ let toTreasury = (claimBoostingMax - claimBoosting)
345+ $Tuple5(newFarmInterest, newBoostInterest, newBoostLPInterest, (claimFarming + claimBoosting), toTreasury)
346+ }
347+
348+
349+func canLockInFirstHarvest (pool,user,userShareTokensStaked,pmtAmount,lockType) = if ((getHeightFirstHarvest(pool) > height))
350+ then {
351+ let totalVoteAmount = valueOrElse(getInteger(votingAddress, (pool + kHarvestPoolVote)), 0)
352+ let userVoteAmount = valueOrElse(getInteger(votingAddress, (((user + "_") + pool) + kHarvestPoolVote)), 0)
353+ let FHShareTokenLimit = getFHShareLimitToken(addressFromStringValue(pool))
354+ let FHShareTokenUserLimit = (fraction(FHShareTokenLimit, userVoteAmount, totalVoteAmount) - userShareTokensStaked)
355+ if ((lockType > 0))
356+ then throw("You can't lock shareTokens till first harvest end.")
357+ else if ((userVoteAmount == 0))
358+ then 0
359+ else if ((pmtAmount >= FHShareTokenUserLimit))
360+ then (pmtAmount - FHShareTokenUserLimit)
361+ else 0
362+ }
363+ else 0
364+
365+
366+func getLockParams (type) = {
367+ let lockParams = split(valueOrErrorMessage(getString(this, (toString(type) + kLockParams)), ("There are no key for lock type" + toString(type))), "_")
368+ $Tuple2(parseIntValue(lockParams[0]), parseIntValue(lockParams[1]))
369+ }
370+
119371
120372 func suspend (cause) = [BooleanEntry(kActive, false), StringEntry(kCause, cause)]
121373
122374
123-func throwIsActive () = throw("DApp is already active")
124-
125-
126-func isActive () = if (active)
375+func isActive () = if (if (active)
376+ then activeGlob
377+ else false)
127378 then unit
128379 else throw("DApp is inactive at this moment")
129380
130381
131382 func isAdminCall (i) = if (containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey))
132383 then unit
133384 else throw("Only admin can call this function")
134385
135386
136-func isSelfCall (i) = if ((this == i.caller))
137- then unit
138- else throw("Only contract itself can call this function")
139-
140-
141-let big2 = toBigInt(2)
142-
143-let iter10 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
144-
145-let iter15 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
146-
147-let iter16 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
148-
149-let blockTimestamp = height
150-
151-func assert (a) = if (a)
152- then false
153- else true
154-
155-
156-func calculateFeeDiscount (userAddr) = {
157- let user = match userAddr {
158- case u: Address =>
159- toString(u)
160- case u: String =>
161- u
162- case _ =>
163- throw("Unknow type of user Addr")
164- }
165- let swopAmount = valueOrElse(getInteger(govAddress, (user + kUserGSwopInGov)), 0)
166- let gSwopAmount = valueOrElse(getInteger(govAddress, (user + kUserGSwopInGov)), swopAmount)
167- let discountValues = split(getStringValue(oracle, kDiscountValues), ",")
168- let discounts = split(getStringValue(oracle, kDiscounts), ",")
169- if (if ((gSwopAmount >= parseIntValue(discountValues[0])))
170- then (parseIntValue(discountValues[1]) > gSwopAmount)
171- else false)
172- then (feeScale6 - parseIntValue(discounts[0]))
173- else if (if ((gSwopAmount >= parseIntValue(discountValues[1])))
174- then (parseIntValue(discountValues[2]) > gSwopAmount)
175- else false)
176- then (feeScale6 - parseIntValue(discounts[1]))
177- else if (if ((gSwopAmount >= parseIntValue(discountValues[2])))
178- then (parseIntValue(discountValues[3]) > gSwopAmount)
179- else false)
180- then (feeScale6 - parseIntValue(discounts[2]))
181- else if (if ((gSwopAmount >= parseIntValue(discountValues[3])))
182- then (parseIntValue(discountValues[4]) > gSwopAmount)
183- else false)
184- then (feeScale6 - parseIntValue(discounts[3]))
185- else if ((gSwopAmount >= parseIntValue(discountValues[4])))
186- then (feeScale6 - parseIntValue(discounts[4]))
187- else feeScale6
188- }
189-
190-
191-func _A () = {
192- let t1 = future_A_time
193- let A1 = future_A
194- if ((t1 > blockTimestamp))
195- then {
196- let A0 = initial_A
197- let t0 = initial_A_time
198- if ((A1 > A0))
199- then (A0 + (((A1 - A0) * (blockTimestamp - t0)) / (t1 - t0)))
200- else (A0 - (((A0 - A1) * (blockTimestamp - t0)) / (t1 - t0)))
201- }
202- else A1
203- }
204-
205-
206-func _xp () = {
207- func assetBalances (acc,assetId) = (acc :+ valueOrElse(getInteger(this, (assetId + kAssetBalance)), 0))
208-
209- let $l = assetIds
210- let $s = size($l)
211- let $acc0 = nil
212- func $f0_1 ($a,$i) = if (($i >= $s))
213- then $a
214- else assetBalances($a, $l[$i])
215-
216- func $f0_2 ($a,$i) = if (($i >= $s))
217- then $a
218- else throw("List size exceeds 10")
219-
220- $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)
221- }
222-
223-
224-func _xp_mem (xp) = xp
225-
226-
227-func sumList (acc,element) = (acc + element)
228-
229-
230-func get_D (xp,amp) = {
231- let @ = invoke(this, "D", [xp, amp], nil)
232- if ($isInstanceOf(@, "Int"))
233- then @
234- else throw(($getType(@) + " couldn't be cast to Int"))
235- }
236-
237-
238-func get_D_internal (xp,amp) = {
239- let S = {
240- let $l = xp
241- let $s = size($l)
242- let $acc0 = 0
243- func $f0_1 ($a,$i) = if (($i >= $s))
244- then $a
245- else sumList($a, $l[$i])
246-
247- func $f0_2 ($a,$i) = if (($i >= $s))
248- then $a
249- else throw("List size exceeds 10")
250-
251- $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)
252- }
253- if ((S == 0))
254- then 0
255- else {
256- let Ann = (amp * nCoins)
257- let AnnS = (toBigInt(Ann) * toBigInt(S))
258- let Ann1 = toBigInt((Ann - 1))
259- func Dproc (acc,i) = if ((acc._2 == true))
260- then acc
261- else {
262- let Dprev = acc._1
263- func D_PProc (D_P,i) = if ((nCoins > i))
264- then ((D_P * Dprev) / (toBigInt(xp[i]) * toBigInt(nCoins)))
265- else D_P
266-
267- let D_P = {
268- let $l = iter10
269- let $s = size($l)
270- let $acc0 = Dprev
271- func $f1_1 ($a,$i) = if (($i >= $s))
272- then $a
273- else D_PProc($a, $l[$i])
274-
275- func $f1_2 ($a,$i) = if (($i >= $s))
276- then $a
277- else throw("List size exceeds 10")
278-
279- $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)
280- }
281- let D = fraction((AnnS + (toBigInt(nCoins) * D_P)), Dprev, ((Ann1 * Dprev) + (toBigInt((nCoins + 1)) * D_P)))
282- if ((D > Dprev))
283- then if ((1 >= toInt((D - Dprev))))
284- then $Tuple2(D, true)
285- else $Tuple2(D, false)
286- else if ((1 >= toInt((Dprev - D))))
287- then $Tuple2(D, true)
288- else $Tuple2(D, false)
289- }
290-
291- let $t064616527 = {
292- let $l = iter15
293- let $s = size($l)
294- let $acc0 = $Tuple2(toBigInt(S), false)
295- func $f1_1 ($a,$i) = if (($i >= $s))
296- then $a
297- else Dproc($a, $l[$i])
298-
299- func $f1_2 ($a,$i) = if (($i >= $s))
300- then $a
301- else throw("List size exceeds 15")
302-
303- $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)
304- }
305- let D = $t064616527._1
306- let finished = $t064616527._2
307- if ((finished == false))
308- then throw(("get_D() not finished with " + toString(D)))
309- else toInt(D)
310- }
311- }
312-
313-
314-func getDMem (xp,amp) = get_D(_xp_mem(xp), amp)
315-
316-
317-func getY (in,out,x,xp_) = if (assert((in != out)))
318- then throw("same coin")
319- else if (assert(if ((out >= 0))
320- then (in >= 0)
321- else false))
322- then throw("below zero")
323- else if (assert(if ((nCoins > out))
324- then (nCoins > in)
325- else false))
326- then throw("above N_COINS")
327- else {
328- let amp = _A()
329- let D = get_D(xp_, amp)
330- let Ann = (amp * nCoins)
331- func S_c (acc,i) = {
332- let $t070987115 = acc
333- let S_ = $t070987115._1
334- let c = $t070987115._2
335- let x_ = if ((in == i))
336- then x
337- else xp_[i]
338- if (if ((i != out))
339- then (nCoins > i)
340- else false)
341- then $Tuple2((S_ + x_), fraction(c, toBigInt(D), toBigInt((x_ * nCoins))))
342- else $Tuple2(S_, c)
343- }
344-
345- let $t073237378 = {
346- let $l = iter10
347- let $s = size($l)
348- let $acc0 = $Tuple2(0, toBigInt(D))
349- func $f0_1 ($a,$i) = if (($i >= $s))
350- then $a
351- else S_c($a, $l[$i])
352-
353- func $f0_2 ($a,$i) = if (($i >= $s))
354- then $a
355- else throw("List size exceeds 10")
356-
357- $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)
358- }
359- let S_ = $t073237378._1
360- let c_ = $t073237378._2
361- let c = fraction(c_, toBigInt(D), toBigInt((Ann * nCoins)))
362- let bD = toBigInt(((S_ + (D / Ann)) - D))
363- func y_proc (acc,_i) = if ((acc._2 == true))
364- then acc
365- else {
366- let y_prev = acc._1
367- let y = (((y_prev * y_prev) + c) / ((big2 * y_prev) + bD))
368- if ((y > y_prev))
369- then if ((1 >= toInt((y - y_prev))))
370- then $Tuple2(y, true)
371- else $Tuple2(y, false)
372- else if ((1 >= toInt((y_prev - y))))
373- then $Tuple2(y, true)
374- else $Tuple2(y, false)
375- }
376-
377- let $t078607927 = {
378- let $l = iter16
379- let $s = size($l)
380- let $acc0 = $Tuple2(toBigInt(D), false)
381- func $f1_1 ($a,$i) = if (($i >= $s))
382- then $a
383- else y_proc($a, $l[$i])
384-
385- func $f1_2 ($a,$i) = if (($i >= $s))
386- then $a
387- else throw("List size exceeds 16")
388-
389- $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)
390- }
391- let y = $t078607927._1
392- let finished = $t078607927._2
393- if ((finished == false))
394- then throw(("getY() not finished with " + toString(y)))
395- else toInt(y)
396- }
397-
398-
399-func get_y_D (A_,in,xp,D) = if (assert((in >= 0)))
400- then throw("i below zero")
401- else if (assert((nCoins > in)))
402- then throw("i above N_COINS")
403- else {
404- let Ann = (A_ * nCoins)
405- func S_c (acc,i) = {
406- let $t083068323 = acc
407- let S_ = $t083068323._1
408- let c = $t083068323._2
409- let x_ = if (if ((in != i))
410- then (nCoins > i)
411- else false)
412- then xp[i]
413- else 0
414- if (if ((nCoins > i))
415- then (in != i)
416- else false)
417- then $Tuple2((S_ + x_), fraction(c, toBigInt(D), toBigInt((x_ * nCoins))))
418- else $Tuple2(S_, c)
419- }
420-
421- let $t085438598 = {
422- let $l = iter10
423- let $s = size($l)
424- let $acc0 = $Tuple2(0, toBigInt(D))
425- func $f0_1 ($a,$i) = if (($i >= $s))
426- then $a
427- else S_c($a, $l[$i])
428-
429- func $f0_2 ($a,$i) = if (($i >= $s))
430- then $a
431- else throw("List size exceeds 10")
432-
433- $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)
434- }
435- let S_ = $t085438598._1
436- let c_ = $t085438598._2
437- let c = fraction(c_, toBigInt(D), toBigInt((Ann * nCoins)))
438- let bD = toBigInt(((S_ + (D / Ann)) - D))
439- func y_D_proc (acc,i) = if ((acc._2 == true))
440- then acc
441- else {
442- let y_prev = acc._1
443- let y = (((y_prev * y_prev) + c) / ((big2 * y_prev) + bD))
444- if ((y > y_prev))
445- then if ((1 >= toInt((y - y_prev))))
446- then $Tuple2(y, true)
447- else $Tuple2(y, false)
448- else if ((1 >= toInt((y_prev - y))))
449- then $Tuple2(y, true)
450- else $Tuple2(y, false)
451- }
452-
453- let $t090819150 = {
454- let $l = iter16
455- let $s = size($l)
456- let $acc0 = $Tuple2(toBigInt(D), false)
457- func $f1_1 ($a,$i) = if (($i >= $s))
458- then $a
459- else y_D_proc($a, $l[$i])
460-
461- func $f1_2 ($a,$i) = if (($i >= $s))
462- then $a
463- else throw("List size exceeds 16")
464-
465- $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)
466- }
467- let y = $t090819150._1
468- let finished = $t090819150._2
469- if ((finished == false))
470- then throw(("get_y_D() not finished with " + toString(y)))
471- else toInt(y)
472- }
473-
474-
475-func _calcWithdrawOneCoin (xp,_token_amount,i,caller) = {
476- let feeDiscount = calculateFeeDiscount(caller)
477- let amp = _A()
478- let _fee = ((fraction(fee, feeDiscount, feeScale6, CEILING) * nCoins) / (4 * (nCoins - 1)))
479- let total_supply = shareSupply
480- let D0 = get_D(xp, amp)
481- let D1 = (D0 - fraction(_token_amount, D0, total_supply))
482- let new_y = get_y_D(amp, i, xp, D1)
483- let dy_0 = (xp[i] - new_y)
484- func xp_reduced_proc (acc,xp_j) = {
485- let $t097919820 = acc
486- let xp_reduced = $t097919820._1
487- let index = $t097919820._2
488- let dx_expected = if ((index == i))
489- then (fraction(xp_j, D1, D0) - new_y)
490- else (xp_j - fraction(xp_j, D1, D0))
491- $Tuple2((xp_reduced :+ (xp_j - fraction(_fee, dx_expected, feeScale6))), (index + 1))
492- }
493-
494- let $t01008210146 = {
495- let $l = xp
496- let $s = size($l)
497- let $acc0 = $Tuple2(nil, 0)
498- func $f0_1 ($a,$i) = if (($i >= $s))
499- then $a
500- else xp_reduced_proc($a, $l[$i])
501-
502- func $f0_2 ($a,$i) = if (($i >= $s))
503- then $a
504- else throw("List size exceeds 10")
505-
506- $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)
507- }
508- let xp_reduced = $t01008210146._1
509- let index = $t01008210146._2
510- let xp_reduced_i = xp_reduced[i]
511- let dy = ((xp_reduced_i - get_y_D(amp, i, xp_reduced, D1)) - 1)
512- $Tuple2(dy, (dy_0 - dy))
513- }
514-
515-
516-func getStrAssetId (assetId) = match assetId {
517- case id: ByteVector =>
518- toBase58String(id)
519- case waves: Unit =>
520- "WAVES"
521- case _ =>
522- throw("Match error")
523-}
524-
525-
526-func calcStakingFuncAndAddres (stake,assetId) = if (stake)
527- then $Tuple2("lockNeutrino", stakingUSDNAddress)
528- else $Tuple2("unlockNeutrino", stakingUSDNAddress)
529-
530-
531-func calcStakingParams (stake,amount,assetId) = if (stake)
532- then {
533- let $t01071010776 = calcStakingFuncAndAddres(stake, assetId)
534- let call = $t01071010776._1
535- let stakingAddr = $t01071010776._2
536- $Tuple4(call, stakingAddr, nil, [AttachedPayment(assetId, amount)])
537- }
387+@Callable(i)
388+func init (earlyLP) = if (isDefined(getString(this, kSWOPid)))
389+ then throw("SWOP already initialized")
538390 else {
539- let $t01086210928 = calcStakingFuncAndAddres(stake, assetId)
540- let call = $t01086210928._1
541- let stakingAddr = $t01086210928._2
542- $Tuple4(call, stakingAddr, [amount, toBase58String(assetId)], nil)
391+ let initAmount = 100000000000000
392+ let SWOPissue = Issue("SWOP", "SWOP protocol token", initAmount, 8, true)
393+ let SWOPid = calculateAssetId(SWOPissue)
394+[BooleanEntry(kActive, true), Issue("SWOP", "SWOP protocol token", initAmount, 8, true), StringEntry(kSWOPid, toBase58String(SWOPid))]
543395 }
544396
545397
546-func stake (amount,assetIdString) = if (containsElement(stakingAssets, assetIdString))
547- then {
548- let $t01111511217 = calcStakingParams(true, amount, fromBase58String(assetIdString))
549- let call = $t01111511217._1
550- let addr = $t01111511217._2
551- let params = $t01111511217._3
552- let payments = $t01111511217._4
553- invoke(addr, call, params, payments)
554- }
555- else 0
556398
557-
558-func unstake (amount,assetIdString) = if (containsElement(stakingAssets, assetIdString))
559- then {
560- let $t01140211505 = calcStakingParams(false, amount, fromBase58String(assetIdString))
561- let call = $t01140211505._1
562- let addr = $t01140211505._2
563- let params = $t01140211505._3
564- let payments = $t01140211505._4
565- invoke(addr, call, params, payments)
566- }
567- else 0
568-
569-
570-func stakedAmount (assetId) = {
571- let stakedAmountCalculated = match assetId {
572- case aId: ByteVector =>
573- if ((aId == USDN))
574- then getInteger(stakingUSDNAddress, ((("rpd_balance_" + toBase58String(aId)) + "_") + toString(this)))
575- else 0
576- case _: Unit =>
577- 0
578- case _ =>
579- throw("Match error")
580- }
581- match stakedAmountCalculated {
582- case i: Int =>
583- i
584- case _ =>
585- 0
586- }
587- }
588-
589-
590-func checkSuspicious () = {
591- let contractBalances = _xp()
592- func checkBalance (acc,assetId) = {
593- let $t01211612141 = acc
594- let suspicious = $t01211612141._1
595- let i = $t01211612141._2
596- if (suspicious)
597- then $Tuple2(suspicious, i)
598- else {
599- let aBalance = (assetBalance(this, fromBase58String(assetId)) + stakedAmount(fromBase58String(assetId)))
600- if ((contractBalances[i] > aBalance))
601- then $Tuple2(true, i)
602- else $Tuple2(false, (i + 1))
603- }
604- }
605-
606- let $l = assetIds
607- let $s = size($l)
608- let $acc0 = $Tuple2(false, 0)
609- func $f0_1 ($a,$i) = if (($i >= $s))
610- then $a
611- else checkBalance($a, $l[$i])
612-
613- func $f0_2 ($a,$i) = if (($i >= $s))
614- then $a
615- else throw("List size exceeds 10")
616-
617- $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)
618- }
619-
620-
621-func suspendSuspicious (i) = suspend(("Suspicious state with asset: " + assetIds[i]))
622-
623-
624-func returnPayments (caller,payments) = {
625- func parsePayments (acc,payment) = (acc :+ ScriptTransfer(caller, payment.amount, payment.assetId))
626-
627- let $l = payments
628- let $s = size($l)
629- let $acc0 = nil
630- func $f0_1 ($a,$i) = if (($i >= $s))
631- then $a
632- else parsePayments($a, $l[$i])
633-
634- func $f0_2 ($a,$i) = if (($i >= $s))
635- then $a
636- else throw("List size exceeds 10")
637-
638- $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)
639- }
640-
641-
642-func checkDAppThreshold (newBalances) = {
643- let dAppThresholdCoef = valueOrErrorMessage(getInteger(this, kDAppThresholdCoef), "No dAppThresholdCoef key")
644- let thresholdScale = 10000
645- let maxBalance = max(newBalances)
646- let minBalance = min(newBalances)
647- let ratio = fraction(maxBalance, thresholdScale, minBalance)
648- if ((ratio > (dAppThresholdCoef * thresholdScale)))
649- then throw("New balance in assets of the DApp is less than threshold")
650- else false
651- }
652-
653-
654-func checkCoins (assetIds) = {
655- let coins = split(assetIds, ",")
656- if ((size(coins) > 10))
657- then throw("To many coins, max coins size 10")
658- else {
659- func checkCoin (error,assetId) = {
660- let asset = valueOrErrorMessage(fromBase58String(assetId), ("fromBase58String: " + assetId))
661- let decimals = valueOrErrorMessage(assetInfo(asset), ("assetInfo: " + assetId)).decimals
662- if ((decimals != DECIMALS))
663- then throw("wrong decimals")
664- else false
665- }
666-
667- let $l = coins
668- let $s = size($l)
669- let $acc0 = false
670- func $f0_1 ($a,$i) = if (($i >= $s))
671- then $a
672- else checkCoin($a, $l[$i])
673-
674- func $f0_2 ($a,$i) = if (($i >= $s))
675- then $a
676- else throw("List size exceeds 10")
677-
678- $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)
679- }
680- }
681-
682-
683-@Callable(msg)
684-func D (xp,amp) = {
685- let D = get_D_internal(xp, amp)
686- $Tuple2([IntegerEntry("D", D)], D)
687- }
399+@Callable(i)
400+func initPoolShareFarming (pool) = valueOrElse(isAdminCall(i), [IntegerEntry((pool + kShareTotalShareTokens), 0), IntegerEntry((pool + kFarmLastInterest), 0), IntegerEntry((pool + kBoostLastInterest), 0), IntegerEntry((pool + kBoostLPLastInterest), 0), IntegerEntry((pool + kLastInterestHeight), height)])
688401
689402
690403
691-@Callable(msg)
692-func init (assetIds,_A,_dAppThresholdCoef) = if (!(isDataStorageUntouched(this)))
693- then throw("Already initialized")
694- else if ((0 >= _A))
695- then throw("Amp must be must > 0")
696- else if ((0 >= _dAppThresholdCoef))
697- then throw("dApp Threshold Coef must be > 0")
698- else {
699- let shareName = "s_Multi_USD"
700- let shareDescription = ("ShareToken of SwopFi protocol for MultiStable USD pool at address " + toString(this))
701- let issueToken = Issue(shareName, shareDescription, 0, 6, true)
702- let tokenId = calculateAssetId(issueToken)
703- if (checkCoins(assetIds))
704- then throw()
705- 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]
706- }
404+@Callable(i)
405+func updatePoolInterest (pool) = valueOrElse(isActive(), if ((i.caller != govAddress))
406+ then throw("Only Governance can call this function")
407+ else {
408+ let user = toString(addressFromPublicKey(adminInvokePubKey))
409+ let $t01861718691 = claimCalc(pool, user)
410+ let farmInterest = $t01861718691._1
411+ let boostInterest = $t01861718691._2
412+ let boostLPinterest = $t01861718691._3
413+[IntegerEntry((pool + kFarmLastInterest), farmInterest), IntegerEntry((pool + kBoostLastInterest), boostInterest), IntegerEntry((pool + kBoostLPLastInterest), boostLPinterest), IntegerEntry((pool + kLastInterestHeight), height)]
414+ })
707415
708416
709417
710-@Callable(msg)
711-func addLiquidity (minMintAmount,stakeFarming,lockType) = valueOrElse(isActive(), {
712- let amp = _A()
713- let xp = _xp()
714- let D0 = if ((shareSupply == 0))
715- then 0
716- else getDMem(xp, amp)
717- let $t01534915604 = if (if ((lockType > 0))
718- then (msg.payments[(size(msg.payments) - 1)].assetId == unit)
719- else false)
720- then $Tuple2(removeByIndex(msg.payments, (size(msg.payments) - 1)), [msg.payments[(size(msg.payments) - 1)]])
721- else $Tuple2(msg.payments, nil)
722- let payments = $t01534915604._1
723- let lockFee = $t01534915604._2
724- let paymentsSize = size(payments)
725- func validPayments (n) = if ((paymentsSize > nCoins))
726- then throw(("payments size > " + toString(nCoins)))
727- else if ((1 > paymentsSize))
728- then throw("payments size < 1")
729- else if (if ((shareSupply == 0))
730- then (nCoins != paymentsSize)
731- else false)
732- then throw("initial deposit requires all coins")
418+@Callable(i)
419+func lockShareTokens (pool,lockType) = valueOrElse(isActive(), {
420+ let shareAssetId = getShareAssetId(pool)
421+ let user = toString(i.originCaller)
422+ let totalShare = getTotalShareToken(pool)
423+ let totalShareVirtual = valueOrElse(getInteger(this, (pool + kShareTokensVirtual)), totalShare)
424+ let userStakedAmount = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensStaked)), 0)
425+ let userLockedHeigt = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensLockedHeight)), 0)
426+ let userLockedAmount = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensLocked)), 0)
427+ let userAmountVirtual = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensVirtual)), userStakedAmount)
428+ let totalUserShareTokens = ((userStakedAmount + userLockedAmount) + i.payments[0].amount)
429+ let $t01980019852 = getLockParams(lockType)
430+ let lockPeriod = $t01980019852._1
431+ let lockCoef = $t01980019852._2
432+ let lockWavesFee = getIntegerValue(this, kLockWavesFee)
433+ if ((i.payments[0].assetId != shareAssetId))
434+ then throw("Wrong sharetoken in payment")
435+ else if ((0 >= i.payments[0].amount))
436+ then throw("Payment amount must be greater than 0")
437+ else if ((0 > lockType))
438+ then throw("lockType must be >= 0")
733439 else {
734- func paymantValid (acc,payment) = if (containsElement(assetIds, getStrAssetId(payment.assetId)))
735- then true
736- else throw("Invalid asset in payment")
737-
738- let $l = payments
739- let $s = size($l)
740- let $acc0 = false
741- func $f0_1 ($a,$i) = if (($i >= $s))
742- then $a
743- else paymantValid($a, $l[$i])
744-
745- func $f0_2 ($a,$i) = if (($i >= $s))
746- then $a
747- else throw("List size exceeds 10")
748-
749- $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)
750- }
751-
752- if (!(validPayments(paymentsSize)))
753- then throw()
754- else {
755- let suspicious = checkSuspicious()
756- if (suspicious._1)
757- then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.caller, payments))
758- else {
759- func parsePayments (acc,assetId) = {
760- let $t01647416500 = acc
761- let newBalances = $t01647416500._1
762- let i = $t01647416500._2
763- func parsePayment (newBalance,payment) = if ((getStrAssetId(payment.assetId) == assetId))
764- then (newBalance + payment.amount)
765- else newBalance
766-
767- let newBalace = {
768- let $l = payments
769- let $s = size($l)
770- let $acc0 = xp[i]
771- func $f0_1 ($a,$i) = if (($i >= $s))
772- then $a
773- else parsePayment($a, $l[$i])
774-
775- func $f0_2 ($a,$i) = if (($i >= $s))
776- then $a
777- else throw("List size exceeds 10")
778-
779- $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)
780- }
781- $Tuple2((newBalances :+ newBalace), (i + 1))
782- }
783-
784- let $t01685016917 = {
785- let $l = assetIds
786- let $s = size($l)
787- let $acc0 = $Tuple2(nil, 0)
788- func $f0_1 ($a,$i) = if (($i >= $s))
789- then $a
790- else parsePayments($a, $l[$i])
791-
792- func $f0_2 ($a,$i) = if (($i >= $s))
793- then $a
794- else throw("List size exceeds 10")
795-
796- $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)
797- }
798- let newBalances = $t01685016917._1
799- let k = $t01685016917._2
800- if (checkDAppThreshold(newBalances))
801- then throw()
802- else {
803- let D1 = getDMem(newBalances, amp)
804- if (assert((D1 > D0)))
805- then throw("D1 > D0")
440+ let shareTokensChangeOnFH = canLockInFirstHarvest(pool, user, userStakedAmount, i.payments[0].amount, lockType)
441+ if ((shareTokensChangeOnFH == shareTokensChangeOnFH))
442+ then {
443+ let $t02027922124 = if ((lockType == 0))
444+ then {
445+ let userAmountVirtualNew = ((userAmountVirtual + i.payments[0].amount) - shareTokensChangeOnFH)
446+ $Tuple2([IntegerEntry((((pool + "_") + user) + kUserShareTokensStaked), ((userStakedAmount + i.payments[0].amount) - shareTokensChangeOnFH)), IntegerEntry((pool + kShareTokensVirtual), ((totalShareVirtual + i.payments[0].amount) - shareTokensChangeOnFH)), ScriptTransfer(i.originCaller, shareTokensChangeOnFH, i.payments[0].assetId)], ((totalShare + i.payments[0].amount) - shareTokensChangeOnFH))
447+ }
448+ else if (if ((userLockedHeigt == 0))
449+ then if (if ((2 > size(i.payments)))
450+ then true
451+ else (i.payments[1].assetId != unit))
452+ then true
453+ else (lockWavesFee > i.payments[1].amount)
454+ else false)
455+ then throw((("You need to pay additional waves comission " + toString(lockWavesFee)) + "WAVES"))
456+ else if ((userLockedHeigt > (height + lockPeriod)))
457+ then throw("You cannot lock sharetokens for a period less than what you have already locked")
458+ else {
459+ let userLockedAmountNew = (userLockedAmount + i.payments[0].amount)
460+ let userLockedHeigtNew = (height + lockPeriod)
461+ let userAmountVirtualNew = (fraction(userLockedAmountNew, lockCoef, lockBoostCoefScale) + userStakedAmount)
462+ $Tuple2([IntegerEntry((((pool + "_") + user) + kUserShareTokensLocked), userLockedAmountNew), IntegerEntry((((pool + "_") + user) + kUserShareTokensLockedHeight), userLockedHeigtNew), IntegerEntry((((pool + "_") + user) + kUserShareTokensLockedType), lockType), IntegerEntry((((pool + "_") + user) + kUserShareTokensVirtual), userAmountVirtualNew), IntegerEntry((pool + kShareTokensVirtual), ((totalShareVirtual - userAmountVirtual) + userAmountVirtualNew))], (totalShare + i.payments[0].amount))
463+ }
464+ let lockEntries = $t02027922124._1
465+ let totalShareNew = $t02027922124._2
466+ if ((accountBalance(shareAssetId) > totalShareNew))
467+ then throw("Balance of share-token is lower than totalAmount")
806468 else {
807- let feeDiscount = calculateFeeDiscount(msg.caller)
808- func calcScriptActions (acc,newBalance) = {
809- let $t01723717278 = acc
810- let invBalances = $t01723717278._1
811- let scriptActions = $t01723717278._2
812- let i = $t01723717278._3
813- if ((shareSupply > 0))
814- then {
815- let _fee = ((fraction(fee, feeDiscount, feeScale6, CEILING) * nCoins) / (4 * (nCoins - 1)))
816- let fees = {
817- let idealBalance = fraction(D1, xp[i], D0)
818- let difference = if ((idealBalance > newBalance))
819- then (idealBalance - newBalance)
820- else (newBalance - idealBalance)
821- fraction(_fee, difference, feeScale6)
822- }
823- let governanceFees = fraction(fees, feeGovernance, feeScale6)
824- let finalBalance = (newBalance - fees)
825- let invariantBalance = (newBalance - fees)
826- let pmt = (newBalance - xp[i])
827- let lpFees = (fees - governanceFees)
828- let inv = if ((pmt > 0))
829- then stake((pmt - fees), assetIds[i])
830- else unstake(fees, assetIds[i])
831- if ((inv == inv))
832- then {
833- let airdrop = if ((lpFees > 0))
834- then invoke(lpFarmingAddress, "airDrop", nil, [AttachedPayment(fromBase58String(assetIds[i]), lpFees)])
835- else 0
836- if ((airdrop == airdrop))
837- then $Tuple3((invBalances :+ invariantBalance), (scriptActions ++ [ScriptTransfer(moneyBoxAddress, governanceFees, fromBase58String(assetIds[i])), IntegerEntry((assetIds[i] + kAssetBalance), finalBalance)]), (i + 1))
838- else throw("Strict value is not equal to itself.")
839- }
840- else throw("Strict value is not equal to itself.")
841- }
842- else {
843- let inv = stake(newBalance, assetIds[i])
844- if ((inv == inv))
845- then $Tuple3((invBalances :+ newBalance), (scriptActions :+ IntegerEntry((assetIds[i] + kAssetBalance), newBalance)), (i + 1))
846- else throw("Strict value is not equal to itself.")
847- }
848- }
849-
850- let $t01898319071 = {
851- let $l = newBalances
852- let $s = size($l)
853- let $acc0 = $Tuple3(nil, nil, 0)
854- func $f1_1 ($a,$i) = if (($i >= $s))
855- then $a
856- else calcScriptActions($a, $l[$i])
857-
858- func $f1_2 ($a,$i) = if (($i >= $s))
859- then $a
860- else throw("List size exceeds 10")
861-
862- $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)
863- }
864- let invBalances = $t01898319071._1
865- let scriptActions = $t01898319071._2
866- let D2 = getDMem(invBalances, amp)
867- let mint_amount = if ((shareSupply == 0))
868- then D1
869- else fraction(shareSupply, (D2 - D0), D0)
870- if (assert((mint_amount >= minMintAmount)))
871- then throw("Slippage screwed you")
872- else if (stakeFarming)
873- then {
874- let re = invoke(this, "reissueShare", [mint_amount], nil)
875- if ((re == re))
876- then {
877- let s = invoke(farmingAddress, "lockShareTokens", [toString(this), lockType], ([AttachedPayment(shareAssetId, mint_amount)] ++ lockFee))
878- if ((s == s))
879- then (scriptActions :+ IntegerEntry(kShareAssetSupply, (shareSupply + mint_amount)))
880- else throw("Strict value is not equal to itself.")
881- }
882- else throw("Strict value is not equal to itself.")
883- }
884- else (scriptActions ++ [Reissue(shareAssetId, mint_amount, true), ScriptTransfer(msg.caller, mint_amount, shareAssetId), IntegerEntry(kShareAssetSupply, (shareSupply + mint_amount))])
469+ let $t02224922348 = claimCalc(pool, user)
470+ let farmInterest = $t02224922348._1
471+ let boostInterest = $t02224922348._2
472+ let boostLPinterest = $t02224922348._3
473+ let claimAmount = $t02224922348._4
474+ let toTreasure = $t02224922348._5
475+ let availableFundsNew = (userAvailableSWOP(pool, i.originCaller) + claimAmount)
476+ let uplp = if ((getString(Address(fromBase58String(pool)), "version") == "3.0.0"))
477+ then invoke(lpFarmingAddress, "updateUserInterest", [pool, totalUserShareTokens], nil)
478+ else 0
479+ if ((uplp == uplp))
480+ then ([IntegerEntry((((pool + "_") + user) + kFarmUserLastInterest), farmInterest), IntegerEntry((((pool + "_") + user) + kBoostUserLastInterest), boostInterest), IntegerEntry((((pool + "_") + user) + kBoostLPLastInterest), boostLPinterest), IntegerEntry((pool + kFarmLastInterest), farmInterest), IntegerEntry((pool + kBoostLastInterest), boostInterest), IntegerEntry((pool + kBoostLPLastInterest), boostLPinterest), IntegerEntry((pool + kLastInterestHeight), height), IntegerEntry((pool + kShareTotalShareTokens), totalShareNew), IntegerEntry((((pool + "_") + user) + kAvailableSWOP), availableFundsNew), Reissue(SWOP, toTreasure, true), ScriptTransfer(farmingTreasureAddr, toTreasure, SWOP)] ++ lockEntries)
481+ else throw("Strict value is not equal to itself.")
885482 }
886483 }
484+ else throw("Strict value is not equal to itself.")
887485 }
486+ })
487+
488+
489+
490+@Callable(i)
491+func lockStakedShareTokens (pool,lockType,lockAmount) = valueOrElse(isActive(), {
492+ let shareAssetId = getShareAssetId(pool)
493+ let user = toString(i.originCaller)
494+ let totalShare = getTotalShareToken(pool)
495+ let totalShareVirtual = valueOrElse(getInteger(this, (pool + kShareTokensVirtual)), totalShare)
496+ let userStakedAmount = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensStaked)), 0)
497+ let userLockedHeigt = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensLockedHeight)), 0)
498+ let userLockedAmount = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensLocked)), 0)
499+ let userAmountVirtual = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensVirtual)), userStakedAmount)
500+ let totalUserShareTokens = (userStakedAmount + userLockedAmount)
501+ let $t02425624308 = getLockParams(lockType)
502+ let lockPeriod = $t02425624308._1
503+ let lockCoef = $t02425624308._2
504+ let lockWavesFee = getIntegerValue(this, kLockWavesFee)
505+ if ((getHeightFirstHarvest(pool) > height))
506+ then throw("You can't lock shareTokens till first harvest end.")
507+ else if ((0 >= lockType))
508+ then throw("lockType must be > 0")
509+ else if ((lockAmount > userStakedAmount))
510+ then throw(("You can't lock more than " + toString(userStakedAmount)))
511+ else if ((accountBalance(shareAssetId) > totalShare))
512+ then throw("Balance of share-token is lower than totalAmount")
513+ else if (if ((userLockedHeigt == 0))
514+ then if (if ((1 > size(i.payments)))
515+ then true
516+ else (i.payments[0].assetId != unit))
517+ then true
518+ else (lockWavesFee > i.payments[0].amount)
519+ else false)
520+ then throw((("You need to pay additional waves comission " + toString(lockWavesFee)) + "WAVES"))
521+ else if (if ((userLockedHeigt == 0))
522+ then (0 >= lockAmount)
523+ else false)
524+ then throw("lockAmount must be greater than 0")
525+ else if ((0 > lockAmount))
526+ then throw("lockAmount must be positive")
527+ else if ((userLockedHeigt > (height + lockPeriod)))
528+ then throw("You cannot lock sharetokens for a period less than what you have already locked")
529+ else {
530+ let userLockedAmountNew = (userLockedAmount + lockAmount)
531+ let userStakedAmountNew = (userStakedAmount - lockAmount)
532+ let userLockedHeigtNew = (height + lockPeriod)
533+ let userAmountVirtualNew = (fraction(userLockedAmountNew, lockCoef, lockBoostCoefScale) + userStakedAmount)
534+ let $t02559525694 = claimCalc(pool, user)
535+ let farmInterest = $t02559525694._1
536+ let boostInterest = $t02559525694._2
537+ let boostLPinterest = $t02559525694._3
538+ let claimAmount = $t02559525694._4
539+ let toTreasure = $t02559525694._5
540+ let availableFundsNew = (userAvailableSWOP(pool, i.originCaller) + claimAmount)
541+[IntegerEntry((((pool + "_") + user) + kUserShareTokensStaked), userStakedAmountNew), IntegerEntry((((pool + "_") + user) + kUserShareTokensLocked), userLockedAmountNew), IntegerEntry((((pool + "_") + user) + kUserShareTokensLockedHeight), userLockedHeigtNew), IntegerEntry((((pool + "_") + user) + kUserShareTokensLockedType), lockType), IntegerEntry((((pool + "_") + user) + kUserShareTokensVirtual), userAmountVirtualNew), IntegerEntry((pool + kShareTokensVirtual), ((totalShareVirtual - userAmountVirtual) + userAmountVirtualNew)), IntegerEntry((((pool + "_") + user) + kFarmUserLastInterest), farmInterest), IntegerEntry((((pool + "_") + user) + kBoostUserLastInterest), boostInterest), IntegerEntry((((pool + "_") + user) + kBoostLPLastInterest), boostLPinterest), IntegerEntry((pool + kFarmLastInterest), farmInterest), IntegerEntry((pool + kBoostLastInterest), boostInterest), IntegerEntry((pool + kBoostLPLastInterest), boostLPinterest), IntegerEntry((pool + kLastInterestHeight), height), IntegerEntry((((pool + "_") + user) + kAvailableSWOP), availableFundsNew), Reissue(SWOP, toTreasure, true), ScriptTransfer(farmingTreasureAddr, toTreasure, SWOP)]
542+ }
543+ })
544+
545+
546+
547+@Callable(i)
548+func unlockUserLock (pool,user) = valueOrElse(isActive(), {
549+ let lockWavesFee = getIntegerValue(this, kLockWavesFee)
550+ let userLockedHeigt = valueOrErrorMessage(getInteger(this, (((pool + "_") + user) + kUserShareTokensLockedHeight)), (((("There is no pool " + pool) + " or user ") + user) + "with lock"))
551+ let totalShareVirtual = getIntegerValue(this, (pool + kShareTokensVirtual))
552+ let userStakedAmount = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensStaked)), 0)
553+ let userLockedAmount = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensLocked)), 0)
554+ let userAmountVirtual = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensVirtual)), userStakedAmount)
555+ if ((userLockedHeigt > height))
556+ then throw(("You can't unlock sharetokens till " + toString(userLockedHeigt)))
557+ else {
558+ let userStakedAmountNew = (userStakedAmount + userLockedAmount)
559+ let $t02793028029 = claimCalc(pool, user)
560+ let farmInterest = $t02793028029._1
561+ let boostInterest = $t02793028029._2
562+ let boostLPinterest = $t02793028029._3
563+ let claimAmount = $t02793028029._4
564+ let toTreasure = $t02793028029._5
565+ let availableFundsNew = (userAvailableSWOP(pool, i.originCaller) + claimAmount)
566+[IntegerEntry((((pool + "_") + user) + kFarmUserLastInterest), farmInterest), IntegerEntry((((pool + "_") + user) + kBoostUserLastInterest), boostInterest), IntegerEntry((((pool + "_") + user) + kBoostLPLastInterest), boostLPinterest), IntegerEntry((pool + kFarmLastInterest), farmInterest), IntegerEntry((pool + kBoostLastInterest), boostInterest), IntegerEntry((pool + kBoostLPLastInterest), boostLPinterest), IntegerEntry((pool + kLastInterestHeight), height), IntegerEntry((((pool + "_") + user) + kUserShareTokensStaked), userStakedAmountNew), IntegerEntry((((pool + "_") + user) + kUserShareTokensVirtual), userStakedAmountNew), IntegerEntry((pool + kShareTokensVirtual), ((totalShareVirtual - userAmountVirtual) + userStakedAmountNew)), DeleteEntry((((pool + "_") + user) + kUserShareTokensLocked)), DeleteEntry((((pool + "_") + user) + kUserShareTokensLockedHeight)), DeleteEntry((((pool + "_") + user) + kUserShareTokensLockedType)), Reissue(SWOP, toTreasure, true), ScriptTransfer(farmingTreasureAddr, toTreasure, SWOP), ScriptTransfer(i.caller, lockWavesFee, unit)]
888567 }
889568 })
890569
891570
892571
893-@Callable(msg)
894-func calcMintAmount (newBalances,user) = {
895- let amp = _A()
896- let xp = _xp()
897- let D1 = getDMem(newBalances, amp)
898- if ((shareSupply == 0))
899- then $Tuple2(nil, D1)
900- else {
901- let D0 = getDMem(xp, amp)
902- let feeDiscount = calculateFeeDiscount(user)
903- func calcInvBalances (acc,newBalance) = {
904- let $t02032120347 = acc
905- let invBalances = $t02032120347._1
906- let i = $t02032120347._2
907- let _fee = ((fraction(fee, feeDiscount, feeScale6, CEILING) * nCoins) / (4 * (nCoins - 1)))
908- let fees = {
909- let idealBalance = fraction(D1, xp[i], D0)
910- let difference = if ((idealBalance > newBalance))
911- then (idealBalance - newBalance)
912- else (newBalance - idealBalance)
913- fraction(_fee, difference, feeScale6)
914- }
915- let invariantBalance = (newBalance - fees)
916- $Tuple2((invBalances :+ invariantBalance), (i + 1))
572+@Callable(i)
573+func withdrawShareTokens (pool,shareTokensWithdrawAmount) = valueOrElse(isActive(), {
574+ let shareTokensId = fromBase58String(getStringValue(value(addressFromString(pool)), "share_asset_id"))
575+ let user = toString(i.originCaller)
576+ let $t02953329632 = claimCalc(pool, user)
577+ let farmInterest = $t02953329632._1
578+ let boostInterest = $t02953329632._2
579+ let boostLPinterest = $t02953329632._3
580+ let claimAmount = $t02953329632._4
581+ let toTreasure = $t02953329632._5
582+ let userStakedAmount = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensStaked)), 0)
583+ let userLockedAmount = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensLocked)), 0)
584+ let userAmountVirtual = valueOrElse(getInteger(this, (((pool + "_") + user) + kUserShareTokensVirtual)), userStakedAmount)
585+ let userStakedAmountNew = (userStakedAmount - shareTokensWithdrawAmount)
586+ let availableFundsNew = (userAvailableSWOP(pool, i.originCaller) + claimAmount)
587+ let totalShareAmount = getTotalShareToken(pool)
588+ let totalShareVirtual = valueOrElse(getInteger(this, (pool + kShareTokensVirtual)), totalShareAmount)
589+ let totalShareAmountNew = (totalShareAmount - shareTokensWithdrawAmount)
590+ let totalShareVirtualNew = (totalShareVirtual - shareTokensWithdrawAmount)
591+ let userAmountVirtualNew = (userAmountVirtual - shareTokensWithdrawAmount)
592+ if ((shareTokensWithdrawAmount > userStakedAmount))
593+ then throw("Withdraw amount more then user locked amount")
594+ else if ((accountBalance(shareTokensId) > totalShareAmount))
595+ then throw("Balance of share-token is lower than totalAmount")
596+ else {
597+ let uplp = if ((getString(Address(fromBase58String(pool)), "version") == "3.0.0"))
598+ then invoke(lpFarmingAddress, "updateUserInterest", [pool, (userStakedAmount + userLockedAmount)], nil)
599+ else 0
600+ if ((uplp == uplp))
601+ then [IntegerEntry((((pool + "_") + user) + kFarmUserLastInterest), farmInterest), IntegerEntry((((pool + "_") + user) + kBoostUserLastInterest), boostInterest), IntegerEntry((((pool + "_") + user) + kBoostLPLastInterest), boostLPinterest), IntegerEntry((pool + kFarmLastInterest), farmInterest), IntegerEntry((pool + kBoostLastInterest), boostInterest), IntegerEntry((pool + kBoostLPLastInterest), boostLPinterest), IntegerEntry((pool + kLastInterestHeight), height), IntegerEntry((((pool + "_") + user) + kUserShareTokensStaked), userStakedAmountNew), IntegerEntry((((pool + "_") + user) + kUserShareTokensVirtual), userAmountVirtualNew), IntegerEntry((pool + kShareTotalShareTokens), totalShareAmountNew), IntegerEntry((pool + kShareTokensVirtual), totalShareVirtualNew), IntegerEntry((((pool + "_") + user) + kAvailableSWOP), availableFundsNew), Reissue(SWOP, toTreasure, true), ScriptTransfer(farmingTreasureAddr, toTreasure, SWOP), ScriptTransfer(i.caller, shareTokensWithdrawAmount, shareTokensId)]
602+ else throw("Strict value is not equal to itself.")
917603 }
918-
919- let $t02094921019 = {
920- let $l = newBalances
921- let $s = size($l)
922- let $acc0 = $Tuple2(nil, 0)
923- func $f0_1 ($a,$i) = if (($i >= $s))
924- then $a
925- else calcInvBalances($a, $l[$i])
926-
927- func $f0_2 ($a,$i) = if (($i >= $s))
928- then $a
929- else throw("List size exceeds 10")
930-
931- $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)
932- }
933- let invBalances = $t02094921019._1
934- let k = $t02094921019._2
935- let D2 = getDMem(invBalances, amp)
936- let mintAmount = fraction(shareSupply, (D2 - D0), D0)
937- $Tuple2(nil, mintAmount)
938- }
939- }
604+ })
940605
941606
942607
943-@Callable(msg)
944-func reissueShare (amount) = valueOrElse(isSelfCall(msg), [Reissue(shareAssetId, amount, true)])
608+@Callable(i)
609+func claim (pool) = valueOrElse(isActive(), {
610+ let shareTokensId = fromBase58String(getStringValue(value(addressFromString(pool)), "share_asset_id"))
611+ let user = toString(i.caller)
612+ let shareTokenLocked = getTotalShareToken(pool)
613+ let $t03230132400 = claimCalc(pool, user)
614+ let farmInterest = $t03230132400._1
615+ let boostInterest = $t03230132400._2
616+ let boostLPinterest = $t03230132400._3
617+ let claimAmount = $t03230132400._4
618+ let toTreasure = $t03230132400._5
619+ let availableFund = (userAvailableSWOP(pool, i.caller) + claimAmount)
620+ if ((availableFund == 0))
621+ then throw("You have 0 available SWOP")
622+ else if ((accountBalance(shareTokensId) > shareTokenLocked))
623+ then throw("Balance of share-token is lower than totalAmount")
624+ else $Tuple2([IntegerEntry((((pool + "_") + user) + kFarmUserLastInterest), farmInterest), IntegerEntry((((pool + "_") + user) + kBoostUserLastInterest), boostInterest), IntegerEntry((((pool + "_") + user) + kBoostLPLastInterest), boostLPinterest), IntegerEntry((pool + kFarmLastInterest), farmInterest), IntegerEntry((pool + kBoostLastInterest), boostInterest), IntegerEntry((pool + kBoostLPLastInterest), boostLPinterest), IntegerEntry((pool + kLastInterestHeight), height), IntegerEntry((((pool + "_") + user) + kAvailableSWOP), 0), Reissue(SWOP, (toTreasure + availableFund), true), ScriptTransfer(farmingTreasureAddr, toTreasure, SWOP), ScriptTransfer(i.caller, availableFund, SWOP)], availableFund)
625+ })
945626
946627
947628
948-@Callable(msg)
949-func getDy (assetFrom,assetTo,dx,userAddress) = {
950- let xp = _xp()
951- let fromIndex = valueOrErrorMessage(indexOf(assetIds, assetFrom), "unknown token in")
952- let toIndex = valueOrErrorMessage(indexOf(assetIds, assetTo), "unknown token out")
953- let x = (xp[fromIndex] + dx)
954- let y = getY(fromIndex, toIndex, x, xp)
955- let dy = ((xp[toIndex] - y) - 1)
956- let feeDiscount = calculateFeeDiscount(Address(fromBase58String(userAddress)))
957- let _fee = fraction(fraction(fee, feeDiscount, feeScale6, CEILING), dy, feeScale6)
958- $Tuple2(nil, $Tuple2((dy - _fee), _fee))
959- }
629+@Callable(i)
630+func claimAndStake (pool) = valueOrElse(isActive(), {
631+ let claimAmount = {
632+ let @ = invoke(this, "claim", [pool], nil)
633+ if ($isInstanceOf(@, "Int"))
634+ then @
635+ else throw(($getType(@) + " couldn't be cast to Int"))
636+ }
637+ if ((claimAmount == claimAmount))
638+ then {
639+ let stakeToGov = invoke(govAddress, "lockSWOPFromFarming", nil, [AttachedPayment(SWOP, claimAmount)])
640+ if ((stakeToGov == stakeToGov))
641+ then nil
642+ else throw("Strict value is not equal to itself.")
643+ }
644+ else throw("Strict value is not equal to itself.")
645+ })
960646
961647
962648
963-@Callable(msg)
964-func exchange (tokenOut,min_dy) = valueOrElse(isActive(), if ((size(msg.payments) != 1))
965- then throw("size(payments) != 1")
649+@Callable(i)
650+func claimAll (pools) = valueOrElse(isActive(), {
651+ func claimInv (claimTotal,pool) = {
652+ let claimAmount = {
653+ let @ = invoke(this, "claim", [pool], nil)
654+ if ($isInstanceOf(@, "Int"))
655+ then @
656+ else throw(($getType(@) + " couldn't be cast to Int"))
657+ }
658+ if ((claimAmount == claimAmount))
659+ then (claimTotal + claimAmount)
660+ else throw("Strict value is not equal to itself.")
661+ }
662+
663+ let claimTotal = {
664+ let $l = pools
665+ let $s = size($l)
666+ let $acc0 = 0
667+ func $f0_1 ($a,$i) = if (($i >= $s))
668+ then $a
669+ else claimInv($a, $l[$i])
670+
671+ func $f0_2 ($a,$i) = if (($i >= $s))
672+ then $a
673+ else throw("List size exceeds 60")
674+
675+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60)
676+ }
677+ if ((claimTotal == 0))
678+ then throw("You have 0 available SWOP")
679+ else [ScriptTransfer(i.caller, claimTotal, SWOP)]
680+ })
681+
682+
683+
684+@Callable(i)
685+func claimAllAndStake (pools) = valueOrElse(isActive(), {
686+ func claimInv (claimTotal,pool) = {
687+ let claimAmount = {
688+ let @ = invoke(this, "claim", [pool], nil)
689+ if ($isInstanceOf(@, "Int"))
690+ then @
691+ else throw(($getType(@) + " couldn't be cast to Int"))
692+ }
693+ if ((claimAmount == claimAmount))
694+ then (claimTotal + claimAmount)
695+ else throw("Strict value is not equal to itself.")
696+ }
697+
698+ let claimTotal = {
699+ let $l = pools
700+ let $s = size($l)
701+ let $acc0 = 0
702+ func $f0_1 ($a,$i) = if (($i >= $s))
703+ then $a
704+ else claimInv($a, $l[$i])
705+
706+ func $f0_2 ($a,$i) = if (($i >= $s))
707+ then $a
708+ else throw("List size exceeds 60")
709+
710+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60)
711+ }
712+ if ((claimTotal == 0))
713+ then throw("You have 0 available SWOP")
714+ else {
715+ let stakeToGov = invoke(govAddress, "lockSWOPFromFarming", nil, [AttachedPayment(SWOP, claimTotal)])
716+ if ((stakeToGov == stakeToGov))
717+ then nil
718+ else throw("Strict value is not equal to itself.")
719+ }
720+ })
721+
722+
723+
724+@Callable(i)
725+func updateUserBoostInterest (pool,user) = valueOrElse(isActive(), if ((i.caller != votingAddress))
726+ then throw("Only voiting can call this function")
966727 else {
967- let suspicious = checkSuspicious()
968- if (suspicious._1)
969- then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.caller, msg.payments))
970- else {
971- let payment = msg.payments[0]
972- let tokenIn = getStrAssetId(payment.assetId)
973- let tokenOutB58 = fromBase58String(tokenOut)
974- let dx = payment.amount
975- let fromIndex = valueOrErrorMessage(indexOf(assetIds, tokenIn), "unknown token in")
976- let toIndex = valueOrErrorMessage(indexOf(assetIds, tokenOut), "unknown token out")
977- let xp = _xp()
978- let x = (xp[fromIndex] + dx)
979- let y = getY(fromIndex, toIndex, x, xp)
980- let _dy = ((xp[toIndex] - y) - 1)
981- let feeDiscount = calculateFeeDiscount(msg.originCaller)
982- let _fee = fraction(_dy, fraction(fee, feeDiscount, feeScale6, CEILING), feeScale6)
983- let dy = (_dy - _fee)
984- let governanceFees = fraction(_fee, feeGovernance, feeScale6)
985- if (assert((dy >= min_dy)))
986- then throw("Exchange resulted in fewer coins than expected")
987- else {
988- func makeNewBalances (acc,tokenBalance) = {
989- let $t02306023086 = acc
990- let newBalances = $t02306023086._1
991- let i = $t02306023086._2
992- if ((i == fromIndex))
993- then $Tuple2((newBalances :+ (tokenBalance + dx)), (i + 1))
994- else if ((i == toIndex))
995- then $Tuple2((newBalances :+ (tokenBalance - _dy)), (i + 1))
996- else $Tuple2((newBalances :+ tokenBalance), (i + 1))
997- }
998-
999- let $t02333723398 = {
1000- let $l = xp
1001- let $s = size($l)
1002- let $acc0 = $Tuple2(nil, 0)
1003- func $f0_1 ($a,$i) = if (($i >= $s))
1004- then $a
1005- else makeNewBalances($a, $l[$i])
1006-
1007- func $f0_2 ($a,$i) = if (($i >= $s))
1008- then $a
1009- else throw("List size exceeds 10")
1010-
1011- $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)
1012- }
1013- let newBalances = $t02333723398._1
1014- let i = $t02333723398._2
1015- if (checkDAppThreshold(newBalances))
1016- then throw()
1017- else {
1018- let s = stake(payment.amount, getStrAssetId(payment.assetId))
1019- if ((s == s))
1020- then {
1021- let us = unstake(_dy, tokenOut)
1022- if ((us == us))
1023- then {
1024- let lpFees = (_fee - governanceFees)
1025- let airdrop = if ((lpFees > 0))
1026- then invoke(lpFarmingAddress, "airDrop", nil, [AttachedPayment(tokenOutB58, lpFees)])
1027- else 0
1028- if ((airdrop == airdrop))
1029- then $Tuple2([IntegerEntry((tokenIn + kAssetBalance), x), IntegerEntry((tokenOut + kAssetBalance), (xp[toIndex] - _dy)), ScriptTransfer(msg.caller, dy, tokenOutB58), ScriptTransfer(moneyBoxAddress, governanceFees, tokenOutB58)], [dy, tokenOutB58])
1030- else throw("Strict value is not equal to itself.")
1031- }
1032- else throw("Strict value is not equal to itself.")
1033- }
1034- else throw("Strict value is not equal to itself.")
1035- }
1036- }
1037- }
728+ let $t03478034879 = claimCalc(pool, user)
729+ let farmInterest = $t03478034879._1
730+ let boostInterest = $t03478034879._2
731+ let boostLPinterest = $t03478034879._3
732+ let claimAmount = $t03478034879._4
733+ let toTreasure = $t03478034879._5
734+ let availableFundsNew = (userAvailableSWOP(pool, i.originCaller) + claimAmount)
735+[IntegerEntry((((pool + "_") + user) + kFarmUserLastInterest), farmInterest), IntegerEntry((((pool + "_") + user) + kBoostUserLastInterest), boostInterest), IntegerEntry((((pool + "_") + user) + kBoostLPLastInterest), boostLPinterest), IntegerEntry((pool + kFarmLastInterest), farmInterest), IntegerEntry((pool + kBoostLastInterest), boostInterest), IntegerEntry((pool + kBoostLPLastInterest), boostLPinterest), IntegerEntry((pool + kLastInterestHeight), height), IntegerEntry((((pool + "_") + user) + kAvailableSWOP), availableFundsNew), Reissue(SWOP, toTreasure, true), ScriptTransfer(farmingTreasureAddr, toTreasure, SWOP)]
1038736 })
1039737
1040738
1041739
1042-@Callable(msg)
1043-func withdraw (minAmounts) = valueOrElse(isActive(), if ((size(msg.payments) != 1))
1044- then throw("size(payments) != 1")
1045- else {
1046- let pmtAmount = msg.payments[0].amount
1047- let pmtAssetId = msg.payments[0].assetId
1048- if ((shareAssetId != pmtAssetId))
1049- then throw("unknown payment token")
1050- else {
1051- let suspicious = checkSuspicious()
1052- if (suspicious._1)
1053- then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.originCaller, msg.payments))
1054- else {
1055- func calcScriptActions (acc,balance) = {
1056- let $t02468924717 = acc
1057- let scriptActions = $t02468924717._1
1058- let i = $t02468924717._2
1059- let wAmount = fraction(balance, pmtAmount, shareSupply)
1060- if (assert((wAmount >= minAmounts[i])))
1061- then throw("Withdrawal resulted in fewer coins than expected")
1062- else {
1063- let us = unstake(wAmount, assetIds[i])
1064- if ((us == us))
1065- then $Tuple2((scriptActions ++ [IntegerEntry((assetIds[i] + kAssetBalance), (balance - wAmount)), ScriptTransfer(msg.originCaller, wAmount, fromBase58String(assetIds[i]))]), (i + 1))
1066- else throw("Strict value is not equal to itself.")
1067- }
1068- }
1069-
1070- let $t02520725275 = {
1071- let $l = _xp()
1072- let $s = size($l)
1073- let $acc0 = $Tuple2(nil, 0)
1074- func $f0_1 ($a,$i) = if (($i >= $s))
1075- then $a
1076- else calcScriptActions($a, $l[$i])
1077-
1078- func $f0_2 ($a,$i) = if (($i >= $s))
1079- then $a
1080- else throw("List size exceeds 10")
1081-
1082- $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)
1083- }
1084- let scriptActions = $t02520725275._1
1085- let i = $t02520725275._2
1086- (scriptActions ++ [Burn(shareAssetId, pmtAmount), IntegerEntry(kShareAssetSupply, (shareSupply - pmtAmount))])
1087- }
1088- }
1089- })
1090-
1091-
1092-
1093-@Callable(msg)
1094-func withdrawWithUnlock (minAmounts,unlockAmount) = valueOrElse(isActive(), if ((0 >= unlockAmount))
1095- then throw("Unlock amount must be positive")
1096- else {
1097- let suspicious = checkSuspicious()
1098- if (suspicious._1)
1099- then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.caller, msg.payments))
1100- else {
1101- let pmtAmount = if ((size(msg.payments) > 0))
1102- then if ((size(msg.payments) != 1))
1103- then throw("size(payments) != 1")
1104- else {
1105- let pmtAssetId = msg.payments[0].assetId
1106- if ((shareAssetId != pmtAssetId))
1107- then throw("unknown payment token")
1108- else msg.payments[0].amount
1109- }
1110- else 0
1111- let unlock = invoke(farmingAddress, "withdrawShareTokens", [toString(this), unlockAmount], nil)
1112- if ((unlock == unlock))
1113- then {
1114- let withdrawAmount = (pmtAmount + unlockAmount)
1115- let inv = invoke(this, "withdraw", [minAmounts], [AttachedPayment(shareAssetId, withdrawAmount)])
1116- if ((inv == inv))
1117- then nil
1118- else throw("Strict value is not equal to itself.")
1119- }
1120- else throw("Strict value is not equal to itself.")
1121- }
1122- })
1123-
1124-
1125-
1126-@Callable(msg)
1127-func calcWithdrawOneCoin (tokenAmount,tokenOut,user) = if ((0 >= tokenAmount))
1128- then throw("Amount must be positive")
1129- else {
1130- let i = valueOrErrorMessage(indexOf(assetIds, tokenOut), "unknown token out")
1131- $Tuple2(nil, _calcWithdrawOneCoin(_xp(), tokenAmount, i, Address(fromBase58String(user)))._1)
1132- }
1133-
1134-
1135-
1136-@Callable(msg)
1137-func withdrawOneCoin (tokenOut,minAmount) = valueOrElse(isActive(), if ((size(msg.payments) != 1))
1138- then throw("size(payments) != 1")
1139- else {
1140- let suspicious = checkSuspicious()
1141- if (suspicious._1)
1142- then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.originCaller, msg.payments))
1143- else {
1144- let pmtAmount = msg.payments[0].amount
1145- let pmtAssetId = msg.payments[0].assetId
1146- if ((pmtAssetId != shareAssetId))
1147- then throw("unknown token")
1148- else {
1149- let outIndex = valueOrErrorMessage(indexOf(assetIds, tokenOut), "unknown token out")
1150- let tokenOutB58 = fromBase58String(tokenOut)
1151- let xp = _xp()
1152- let $t02730727389 = _calcWithdrawOneCoin(xp, pmtAmount, outIndex, msg.originCaller)
1153- let dy = $t02730727389._1
1154- let dy_fee = $t02730727389._2
1155- if (assert((dy >= minAmount)))
1156- then throw("Not enough coins removed")
1157- else {
1158- let governanceFees = fraction(dy_fee, feeGovernance, feeScale6)
1159- let dy_and_fee = (dy + dy_fee)
1160- func makeNewBalances (acc,tokenBalance) = {
1161- let $t02764727673 = acc
1162- let newBalances = $t02764727673._1
1163- let i = $t02764727673._2
1164- if ((i == outIndex))
1165- then $Tuple2((newBalances :+ (tokenBalance - dy_and_fee)), (i + 1))
1166- else $Tuple2((newBalances :+ tokenBalance), (i + 1))
1167- }
1168-
1169- let $t02784027901 = {
1170- let $l = xp
1171- let $s = size($l)
1172- let $acc0 = $Tuple2(nil, 0)
1173- func $f0_1 ($a,$i) = if (($i >= $s))
1174- then $a
1175- else makeNewBalances($a, $l[$i])
1176-
1177- func $f0_2 ($a,$i) = if (($i >= $s))
1178- then $a
1179- else throw("List size exceeds 10")
1180-
1181- $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)
1182- }
1183- let newBalances = $t02784027901._1
1184- let v = $t02784027901._2
1185- if (checkDAppThreshold(newBalances))
1186- then throw()
1187- else {
1188- let us = unstake(dy_and_fee, tokenOut)
1189- if ((us == us))
1190- then {
1191- let lpFees = (dy_fee - governanceFees)
1192- let airdrop = if ((lpFees > 0))
1193- then invoke(lpFarmingAddress, "airDrop", nil, [AttachedPayment(tokenOutB58, lpFees)])
1194- else 0
1195- if ((airdrop == airdrop))
1196- 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))]
1197- else throw("Strict value is not equal to itself.")
1198- }
1199- else throw("Strict value is not equal to itself.")
1200- }
1201- }
1202- }
1203- }
1204- })
1205-
1206-
1207-
1208-@Callable(msg)
1209-func withdrawOneCoinWithUnlock (tokenOut,minAmount,unlockAmount) = valueOrElse(isActive(), if ((0 >= unlockAmount))
1210- then throw("Unlock amount must be positive")
1211- else {
1212- let suspicious = checkSuspicious()
1213- if (suspicious._1)
1214- then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.caller, msg.payments))
1215- else {
1216- let pmtAmount = if ((size(msg.payments) > 0))
1217- then if ((size(msg.payments) != 1))
1218- then throw("size(payments) != 1")
1219- else {
1220- let pmtAssetId = msg.payments[0].assetId
1221- if ((shareAssetId != pmtAssetId))
1222- then throw("unknown payment token")
1223- else msg.payments[0].amount
1224- }
1225- else 0
1226- let unlock = invoke(farmingAddress, "withdrawShareTokens", [toString(this), unlockAmount], nil)
1227- if ((unlock == unlock))
1228- then {
1229- let withdrawAmount = (pmtAmount + unlockAmount)
1230- let inv = invoke(this, "withdrawOneCoin", [tokenOut, minAmount], [AttachedPayment(shareAssetId, withdrawAmount)])
1231- if ((inv == inv))
1232- then nil
1233- else throw("Strict value is not equal to itself.")
1234- }
1235- else throw("Strict value is not equal to itself.")
1236- }
1237- })
1238-
1239-
1240-
1241-@Callable(msg)
1242-func A () = $Tuple2(nil, _A())
1243-
1244-
1245-
1246-@Callable(msg)
1247-func getVirtualPrice () = {
1248- let D = get_D(_xp(), _A())
1249- $Tuple2(nil, fraction(D, PRECISION, shareSupply))
1250- }
1251-
1252-
1253-
1254-@Callable(msg)
1255-func calcTokenAmount (amounts,deposit) = {
1256- let amp = _A()
1257- let balances = _xp()
1258- let D0 = getDMem(balances, amp)
1259- func calcNewBalances (acc,balance) = {
1260- let $t02991829944 = acc
1261- let newBalances = $t02991829944._1
1262- let i = $t02991829944._2
1263- let newBalance = (balance + (if (deposit)
1264- then amounts[i]
1265- else -(amounts[i])))
1266- $Tuple2((newBalances :+ newBalance), (i + 1))
1267- }
1268-
1269- let newBalances = ( let $l = balances
1270- let $s = size($l)
1271- let $acc0 = $Tuple2(nil, 0)
1272- func $f0_1 ($a,$i) = if (($i >= $s))
1273- then $a
1274- else calcNewBalances($a, $l[$i])
1275-
1276- func $f0_2 ($a,$i) = if (($i >= $s))
1277- then $a
1278- else throw("List size exceeds 10")
1279-
1280- $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
1281- let D1 = getDMem(newBalances, amp)
1282- let diff = if (deposit)
1283- then (D1 - D0)
1284- else (D0 - D1)
1285- $Tuple2(nil, fraction(diff, shareSupply, D0))
1286- }
1287-
1288-
1289-
1290-@Callable(msg)
1291-func rampA (_futureA,_futureTime) = valueOrElse(isActive(), valueOrElse(isAdminCall(msg), if (assert((blockTimestamp >= (initial_A_time + MIN_RAMP_TIME))))
1292- then throw("too often")
1293- else if (assert((_futureTime >= (blockTimestamp + MIN_RAMP_TIME))))
1294- then throw("insufficient time")
1295- else {
1296- let _initial_A = _A()
1297- if (assert(if ((_futureA > 0))
1298- then (MAX_A > _futureA)
1299- else false))
1300- then throw("out of base range")
1301- else if (assert(if (if ((_futureA >= _initial_A))
1302- then ((_initial_A * MAX_A_CHANGE) >= _futureA)
1303- else false)
1304- then true
1305- else if ((_initial_A > _futureA))
1306- then ((_futureA * MAX_A_CHANGE) >= _initial_A)
1307- else false))
1308- then throw("out of range")
1309- else [IntegerEntry("initial_A", _initial_A), IntegerEntry("future_A", _futureA), IntegerEntry("initial_A_time", blockTimestamp), IntegerEntry("future_A_time", _futureTime)]
1310- }))
1311-
1312-
1313-
1314-@Callable(msg)
1315-func stopRampA () = valueOrElse(isActive(), valueOrElse(isAdminCall(msg), {
1316- let currentA = _A()
1317-[IntegerEntry("initial_A", currentA), IntegerEntry("future_A", currentA), IntegerEntry("initial_A_time", blockTimestamp), IntegerEntry("future_A_time", blockTimestamp)]
1318- }))
1319-
1320-
1321-
1322-@Callable(msg)
1323-func shutdown () = valueOrElse(isAdminCall(msg), if (!(active))
740+@Callable(i)
741+func shutdown () = valueOrElse(isAdminCall(i), if (!(active))
1324742 then throw(("DApp is already suspended. Cause: " + valueOrElse(getString(this, kCause), "the cause wasn't specified")))
1325743 else suspend("Paused by admin"))
1326744
1327745
1328746
1329-@Callable(msg)
1330-func activate () = valueOrElse(isAdminCall(msg), if (active)
1331- then throwIsActive()
747+@Callable(i)
748+func activate () = valueOrElse(isAdminCall(i), if (active)
749+ then throw("DApp is already active")
1332750 else [BooleanEntry(kActive, true), DeleteEntry(kCause)])
1333751
1334752
1335-
1336-@Callable(msg)
1337-func takeIntoAccountExtraFunds () = valueOrElse(isActive(), if ((msg.caller != moneyBoxAddress))
1338- then throw("Only the wallet can call this function")
1339- else {
1340- let balances = _xp()
1341- func takeExtraFunds (acc,assetId) = {
1342- let $t03228632304 = acc
1343- let sum = $t03228632304._1
1344- let i = $t03228632304._2
1345- let tokenB58 = fromBase58String(assetId)
1346- let rBalance = (assetBalance(this, tokenB58) + stakedAmount(tokenB58))
1347- let enrollAmount = (rBalance - balances[i])
1348- if ((0 > enrollAmount))
1349- then suspend(("Enroll amount negative for asset" + assetId))
1350- else {
1351- let airdrop = if ((enrollAmount > 0))
1352- then invoke(lpFarmingAddress, "airDrop", nil, [AttachedPayment(tokenB58, enrollAmount)])
1353- else 0
1354- if ((airdrop == airdrop))
1355- then $Tuple2((sum + enrollAmount), (i + 1))
1356- else throw("Strict value is not equal to itself.")
1357- }
1358- }
1359-
1360- let k = {
1361- let $l = assetIds
1362- let $s = size($l)
1363- let $acc0 = $Tuple2(0, 0)
1364- func $f0_1 ($a,$i) = if (($i >= $s))
1365- then $a
1366- else takeExtraFunds($a, $l[$i])
1367-
1368- func $f0_2 ($a,$i) = if (($i >= $s))
1369- then $a
1370- else throw("List size exceeds 10")
1371-
1372- $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)
1373- }
1374- if ((k._1 == 0))
1375- then throw("No money to take")
1376- else nil
1377- })
1378-
1379-
1380753 @Verifier(tx)
1381-func verify () = {
1382- let multiSignedByAdmins = {
754+func verify () = match tx {
755+ case _ =>
1383756 let adminPubKey1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
1384757 then 1
1385758 else 0
1386759 let adminPubKey2Signed = if (sigVerify(tx.bodyBytes, tx.proofs[1], adminPubKey2))
1387760 then 1
1388761 else 0
1389762 let adminPubKey3Signed = if (sigVerify(tx.bodyBytes, tx.proofs[2], adminPubKey3))
1390763 then 1
1391764 else 0
1392765 (((adminPubKey1Signed + adminPubKey2Signed) + adminPubKey3Signed) >= 2)
1393- }
1394- match tx {
1395- case inv: InvokeScriptTransaction =>
1396- let callTakeIntoAccount = if ((inv.dApp == this))
1397- then (inv.function == "takeIntoAccountExtraFunds")
1398- else false
1399- let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
1400- then true
1401- else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey2))
1402- then true
1403- else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey3))
1404- then true
1405- else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKeyInvoke)
1406- if (if (callTakeIntoAccount)
1407- then signedByAdmin
1408- else false)
1409- then true
1410- else multiSignedByAdmins
1411- case _ =>
1412- multiSignedByAdmins
1413- }
1414- }
766+}
1415767

github/deemru/w8io/169f3d6 
164.28 ms