tx · 3TKVtwjQqAUdiMcEdopszTpRJfT4huFU7sycchqExLZa

3N1b5y6ncRc2X5Mq5ogeT2FpBYANX2ShrjD:  -0.02800000 Waves

2022.08.26 12:38 [2201279] smart account 3N1b5y6ncRc2X5Mq5ogeT2FpBYANX2ShrjD > SELF 0.00000000 Waves

{ "type": 13, "id": "3TKVtwjQqAUdiMcEdopszTpRJfT4huFU7sycchqExLZa", "fee": 2800000, "feeAssetId": null, "timestamp": 1661506721815, "version": 2, "chainId": 84, "sender": "3N1b5y6ncRc2X5Mq5ogeT2FpBYANX2ShrjD", "senderPublicKey": "DYg41vAWoC1qYkgSYQAH1gjWznvc2vreaYUfoHmjcQVt", "proofs": [ "3maUXivg8pRgN2ZnbHzXdGLCKh8kfKywVpP19ZHg3Q7JCP5ZCDeJE5XwNhEVaEdkLL76bh1Yw6VYij83MVgAR3ES" ], "script": "base64:BgJRCAISBAoCEQESBQoDCAEEEgQKAgEEEgYKBAgIAQgSBAoCCAESBAoCEQESBAoCAQESBQoDCAEBEgASABIECgIRBBIECgIBARIAEgASABIDCgEBVgAJUFJFQ0lTSU9OAMCEPQAFTUFYX0EAwIQ9AAxNQVhfQV9DSEFOR0UACgANTUlOX1JBTVBfVElNRQkAaQIAgKMFADwAB2tBc3NldHMCCWFzc2V0X2lkcwANa0Fzc2V0QmFsYW5jZQIIX2JhbGFuY2UAB2tBY3RpdmUCBmFjdGl2ZQAGa0NhdXNlAg5zaHV0ZG93bl9jYXVzZQANa1NoYXJlQXNzZXRJZAIOc2hhcmVfYXNzZXRfaWQAEWtTaGFyZUFzc2V0U3VwcGx5AhJzaGFyZV9hc3NldF9zdXBwbHkABGtGZWUCCmNvbW1pc3Npb24ADGtVU0ROQWRkcmVzcwIYc3Rha2luZ191c2RubnNidF9hZGRyZXNzAAprRGlzY291bnRzAglkaXNjb3VudHMAD2tEaXNjb3VudFZhbHVlcwIPZGlzY291bnRfdmFsdWVzAA5rVXNlclN3b3BJbkdvdgIMX1NXT1BfYW1vdW50AA1rRmlyc3RIYXJ2ZXN0Ag1maXJzdF9oYXJ2ZXN0ABNrRmlyc3RIYXJ2ZXN0SGVpZ2h0AhRmaXJzdF9oYXJ2ZXN0X2hlaWdodAALa1NoYXJlTGltaXQCHHNoYXJlX2xpbWl0X29uX2ZpcnN0X2hhcnZlc3QAC2tCYXNlUGVyaW9kAgtiYXNlX3BlcmlvZAANa1BlcmlvZExlbmd0aAINcGVyaW9kX2xlbmd0aAAMa1N0YXJ0SGVpZ2h0AgxzdGFydF9oZWlnaHQADWtBZG1pblB1YktleTECC2FkbWluX3B1Yl8xAA1rQWRtaW5QdWJLZXkyAgthZG1pbl9wdWJfMgANa0FkbWluUHViS2V5MwILYWRtaW5fcHViXzMAEmtBZG1pbkludm9rZVB1YktleQIQYWRtaW5faW52b2tlX3B1YgAQa01vbmV5Qm94QWRkcmVzcwIRbW9uZXlfYm94X2FkZHJlc3MAC2tHb3ZBZGRyZXNzAhJnb3Zlcm5hbmNlX2FkZHJlc3MADmtWb3RpbmdBZGRyZXNzAg52b3RpbmdfYWRkcmVzcwAPa0Zhcm1pbmdBZGRyZXNzAg9mYXJtaW5nX2FkZHJlc3MABm9yYWNsZQkBB0FkZHJlc3MBARoBVOlFqh6QLzqu8boO5i6akl8amITh82KzCAETZ2V0QmFzZTU4RnJvbU9yYWNsZQEDa2V5BAckbWF0Y2gwCQCdCAIFBm9yYWNsZQUDa2V5AwkAAQIFByRtYXRjaDACBlN0cmluZwQGc3RyaW5nBQckbWF0Y2gwCQDZBAEFBnN0cmluZwQHbm90aGluZwUHJG1hdGNoMAkAAgEJAKwCAgUDa2V5AghpcyBlbXB0eQAMYWRtaW5QdWJLZXkxCQETZ2V0QmFzZTU4RnJvbU9yYWNsZQEFDWtBZG1pblB1YktleTEADGFkbWluUHViS2V5MgkBE2dldEJhc2U1OEZyb21PcmFjbGUBBQ1rQWRtaW5QdWJLZXkyAAxhZG1pblB1YktleTMJARNnZXRCYXNlNThGcm9tT3JhY2xlAQUNa0FkbWluUHViS2V5MwARYWRtaW5QdWJLZXlJbnZva2UJARNnZXRCYXNlNThGcm9tT3JhY2xlAQUSa0FkbWluSW52b2tlUHViS2V5AA9tb25leUJveEFkZHJlc3MJAQdBZGRyZXNzAQkBE2dldEJhc2U1OEZyb21PcmFjbGUBBRBrTW9uZXlCb3hBZGRyZXNzAApnb3ZBZGRyZXNzCQEHQWRkcmVzcwEJARNnZXRCYXNlNThGcm9tT3JhY2xlAQULa0dvdkFkZHJlc3MAEnN0YWtpbmdVU0ROQWRkcmVzcwkBB0FkZHJlc3MBCQETZ2V0QmFzZTU4RnJvbU9yYWNsZQEFDGtVU0ROQWRkcmVzcwANdm90aW5nQWRkcmVzcwkBB0FkZHJlc3MBCQETZ2V0QmFzZTU4RnJvbU9yYWNsZQEFDmtWb3RpbmdBZGRyZXNzAA5mYXJtaW5nQWRkcmVzcwkBB0FkZHJlc3MBCQETZ2V0QmFzZTU4RnJvbU9yYWNsZQEFD2tGYXJtaW5nQWRkcmVzcwASY2FwTW9uZXlCb3hBZGRyZXNzCQEHQWRkcmVzcwEBGgFU6UWqHpAvOq7xug7mLpqSXxqYhOHzYrMIAARVU0ROASBvJKPKqzDcUimY6CxhWu5afyNNwi11u+mdqlTg0tAHwQANc3Rha2luZ0Fzc2V0cwkAzAgCCQDYBAEFBFVTRE4FA25pbAAKYmFzZVBlcmlvZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFDXZvdGluZ0FkZHJlc3MFC2tCYXNlUGVyaW9kAhFFbXB0eSBrQmFzZVBlcmlvZAALc3RhcnRIZWlnaHQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQ12b3RpbmdBZGRyZXNzBQxrU3RhcnRIZWlnaHQCEkVtcHR5IGtTdGFydEhlaWdodAAMcGVyaW9kTGVuZ3RoCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUNdm90aW5nQWRkcmVzcwUNa1BlcmlvZExlbmd0aAITRW1wdHkga1BlcmlvZExlbmd0aAAVZmlyc3RIYXJ2ZXN0RW5kUGVyaW9kCQBkAgkAZAIFCmJhc2VQZXJpb2QJAGkCCQBlAgUGaGVpZ2h0BQtzdGFydEhlaWdodAUMcGVyaW9kTGVuZ3RoAAMABmFjdGl2ZQkBEUBleHRyTmF0aXZlKDEwNTEpAgUEdGhpcwUHa0FjdGl2ZQAMc2hhcmVBc3NldElkCQDZBAEJARFAZXh0ck5hdGl2ZSgxMDUzKQIFBHRoaXMFDWtTaGFyZUFzc2V0SWQAC3NoYXJlU3VwcGx5CQERQGV4dHJOYXRpdmUoMTA1MCkCBQR0aGlzBRFrU2hhcmVBc3NldFN1cHBseQAJZmVlU2NhbGU2AMCEPQADZmVlCQERQGV4dHJOYXRpdmUoMTA1MCkCBQR0aGlzBQRrRmVlAA1mZWVHb3Zlcm5hbmNlCQBrAwAoBQlmZWVTY2FsZTYAZAAJaW5pdGlhbF9BCQERQGV4dHJOYXRpdmUoMTA1MCkCBQR0aGlzAglpbml0aWFsX0EACGZ1dHVyZV9BCQERQGV4dHJOYXRpdmUoMTA1MCkCBQR0aGlzAghmdXR1cmVfQQAOaW5pdGlhbF9BX3RpbWUJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwIOaW5pdGlhbF9BX3RpbWUAAAANZnV0dXJlX0FfdGltZQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzAg1mdXR1cmVfQV90aW1lAAAACGFzc2V0SWRzCQC1CQIJARFAZXh0ck5hdGl2ZSgxMDUzKQIFBHRoaXMFB2tBc3NldHMCASwABm5Db2lucwkAkAMBBQhhc3NldElkcwEHc3VzcGVuZAEFY2F1c2UJAMwIAgkBDEJvb2xlYW5FbnRyeQIFB2tBY3RpdmUHCQDMCAIJAQtTdHJpbmdFbnRyeQIFBmtDYXVzZQUFY2F1c2UFA25pbAENdGhyb3dJc0FjdGl2ZQAJAAIBAhZEQXBwIGlzIGFscmVhZHkgYWN0aXZlAQhpc0FjdGl2ZQADBQZhY3RpdmUFBHVuaXQJAAIBAh9EQXBwIGlzIGluYWN0aXZlIGF0IHRoaXMgbW9tZW50AQtpc0FkbWluQ2FsbAEBaQMJAQ9jb250YWluc0VsZW1lbnQCCQDMCAIFDGFkbWluUHViS2V5MQkAzAgCBQxhZG1pblB1YktleTIJAMwIAgUMYWRtaW5QdWJLZXkzBQNuaWwIBQFpD2NhbGxlclB1YmxpY0tleQUEdW5pdAkAAgECIU9ubHkgYWRtaW4gY2FuIGNhbGwgdGhpcyBmdW5jdGlvbgAEYmlnMgkAtgIBAAIADmJsb2NrVGltZXN0YW1wBQZoZWlnaHQBBmFzc2VydAEBYQMFAWEHBgEUY2FsY3VsYXRlRmVlRGlzY291bnQBCHVzZXJBZGRyBApzd29wQW1vdW50CQELdmFsdWVPckVsc2UCCQCaCAIFCmdvdkFkZHJlc3MJAKwCAgkApQgBBQh1c2VyQWRkcgUOa1VzZXJTd29wSW5Hb3YAAAQOZGlzY291bnRWYWx1ZXMJALUJAgkBEUBleHRyTmF0aXZlKDEwNTMpAgUGb3JhY2xlBQ9rRGlzY291bnRWYWx1ZXMCASwECWRpc2NvdW50cwkAtQkCCQERQGV4dHJOYXRpdmUoMTA1MykCBQZvcmFjbGUFCmtEaXNjb3VudHMCASwDAwkAZwIFCnN3b3BBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5kaXNjb3VudFZhbHVlcwAACQBmAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDmRpc2NvdW50VmFsdWVzAAEFCnN3b3BBbW91bnQHCQBlAgUJZmVlU2NhbGU2CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUJZGlzY291bnRzAAADAwkAZwIFCnN3b3BBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5kaXNjb3VudFZhbHVlcwABCQBmAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDmRpc2NvdW50VmFsdWVzAAIFCnN3b3BBbW91bnQHCQBlAgUJZmVlU2NhbGU2CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUJZGlzY291bnRzAAEDAwkAZwIFCnN3b3BBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5kaXNjb3VudFZhbHVlcwACCQBmAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDmRpc2NvdW50VmFsdWVzAAMFCnN3b3BBbW91bnQHCQBlAgUJZmVlU2NhbGU2CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUJZGlzY291bnRzAAIDAwkAZwIFCnN3b3BBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5kaXNjb3VudFZhbHVlcwADCQBmAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDmRpc2NvdW50VmFsdWVzAAQFCnN3b3BBbW91bnQHCQBlAgUJZmVlU2NhbGU2CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUJZGlzY291bnRzAAMDCQBnAgUKc3dvcEFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDmRpc2NvdW50VmFsdWVzAAQJAGUCBQlmZWVTY2FsZTYJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQlkaXNjb3VudHMABAUJZmVlU2NhbGU2AQJfQQAEAnQxBQ1mdXR1cmVfQV90aW1lBAJBMQUIZnV0dXJlX0EDCQBmAgUCdDEFDmJsb2NrVGltZXN0YW1wBAJBMAUJaW5pdGlhbF9BBAJ0MAUOaW5pdGlhbF9BX3RpbWUDCQBmAgUCQTEFAkEwCQBkAgUCQTAJAGkCCQBoAgkAZQIFAkExBQJBMAkAZQIFDmJsb2NrVGltZXN0YW1wBQJ0MAkAZQIFAnQxBQJ0MAkAZQIFAkEwCQBpAgkAaAIJAGUCBQJBMAUCQTEJAGUCBQ5ibG9ja1RpbWVzdGFtcAUCdDAJAGUCBQJ0MQUCdDAFAkExAQNfeHAACgENYXNzZXRCYWxhbmNlcwIDYWNjB2Fzc2V0SWQJAM0IAgUDYWNjCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAKwCAgUHYXNzZXRJZAUNa0Fzc2V0QmFsYW5jZQAACgACJGwFCGFzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNj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BQdhc3NldElkAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAmlkBQckbWF0Y2gwCQDYBAEFAmlkAwkAAQIFByRtYXRjaDACBFVuaXQEBXdhdmVzBQckbWF0Y2gwAgVXQVZFUwkAAgECC01hdGNoIGVycm9yARhjYWxjU3Rha2luZ0Z1bmNBbmRBZGRyZXMCBXN0YWtlB2Fzc2V0SWQDBQVzdGFrZQkAlAoCAgxsb2NrTmV1dHJpbm8FEnN0YWtpbmdVU0ROQWRkcmVzcwkAlAoCAg51bmxvY2tOZXV0cmlubwUSc3Rha2luZ1VTRE5BZGRyZXNzARFjYWxjU3Rha2luZ1BhcmFtcwMFc3Rha2UGYW1vdW50B2Fzc2V0SWQDBQVzdGFrZQQNJHQwMTA5MjkxMDk5NQkBGGNhbGNTdGFraW5nRnVuY0FuZEFkZHJlcwIFBXN0YWtlBQdhc3NldElkBARjYWxsCAUNJHQwMTA5MjkxMDk5NQJfMQQLc3Rha2luZ0FkZHIIBQ0kdDAxMDkyOTEwOTk1Al8yCQCWCgQFBGNhbGwFC3N0YWtpbmdBZGRyBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFB2Fzc2V0SWQFBmFtb3VudAUDbmlsBA0kdDAxMTA4MTExMTQ3CQEYY2FsY1N0YWtpbmdGdW5jQW5kQWRkcmVzAgUFc3Rha2UFB2Fzc2V0SWQEBGNhbGwIBQ0kdDAxMTA4MTExMTQ3Al8xBAtzdGFraW5nQWRkcggFDSR0MDExMDgxMTExNDcCXzIJAJYKBAUEY2FsbAULc3Rha2luZ0FkZHIJAMwIAgUGYW1vdW50CQDMCAIJANgEAQUHYXNzZXRJZAUDbmlsBQNuaWwBBXN0YWtlAgZhbW91bnQNYXNzZXRJZFN0cmluZwMJAQ9jb250YWluc0VsZW1lbnQCBQ1zdGFraW5nQXNzZXRzBQ1hc3NldElkU3RyaW5nBA0kdDAxMTMzNDExNDM2CQERY2FsY1N0YWtpbmdQYXJhbXMDBgUGYW1vdW50CQDZBAEFDWFzc2V0SWRTdHJpbmcEBGNhbGwIBQ0kdDAxMTMzNDExNDM2Al8xBARhZGRyCAUNJHQwMTEzMzQxMTQzNgJfMgQGcGFyYW1zCAUNJHQwMTEzMzQxMTQzNgJfMwQIcGF5bWVudHMIBQ0kdDAxMTMzNDExNDM2Al80CQD8BwQFBGFkZHIFBGNhbGwFBnBhcmFtcwUIcGF5bWVudHMAAAEHdW5zdGFrZQIGYW1vdW50DWFzc2V0SWRTdHJpbmcDCQEPY29udGFpbnNFbGVtZW50AgUNc3Rha2luZ0Fzc2V0cwUNYXNzZXRJZFN0cmluZwQNJHQwMTE2MjExMTcyNAkBEWNhbGNTdGFraW5nUGFyYW1zAwcFBmFtb3VudAkA2QQBBQ1hc3NldElkU3RyaW5nBARjYWxsCAUNJHQwMTE2MjExMTcyNAJfMQQEYWRkcggFDSR0MDExNjIxMTE3MjQCXzIEBnBhcmFtcwgFDSR0MDExNjIxMTE3MjQCXzMECHBheW1lbnRzCAUNJHQwMTE2MjExMTcyNAJfNAkA/AcEBQRhZGRyBQRjYWxsBQZwYXJhbXMFCHBheW1lbnRzAAABDHN0YWtlZEFtb3VudAEHYXNzZXRJZAQWc3Rha2VkQW1vdW50Q2FsY3VsYXRlZAQHJG1hdGNoMAUHYXNzZXRJZAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBANhSWQFByRtYXRjaDADCQAAAgUDYUlkBQRVU0ROCQCaCAIFEnN0YWtpbmdVU0ROQWRkcmVzcwkArAICCQCsAgIJAKwCAgIMcnBkX2JhbGFuY2VfCQDYBAEFA2FJZAIBXwkApQgBBQR0aGlzAAADCQABAgUHJG1hdGNoMAIEVW5pdAAACQACAQILTWF0Y2ggZXJyb3IEByRtYXRjaDAFFnN0YWtlZEFtb3VudENhbGN1bGF0ZWQDCQABAgUHJG1hdGNoMAIDSW50BAFpBQckbWF0Y2gwBQFpAAABD2NoZWNrU3VzcGljaW91cwAEEGNvbnRyYWN0QmFsYW5jZXMJAQNfeHAACgEMY2hlY2tCYWxhbmNlAgNhY2MHYXNzZXRJZAQNJHQwMTIzMzUxMjM2MAUDYWNjBApzdXNwaWNpb3VzCAUNJHQwMTIzMzUxMjM2MAJfMQQBaQgFDSR0MDEyMzM1MTIzNjACXzIDBQpzdXNwaWNpb3VzCQCUCgIFCnN1c3BpY2lvdXMFAWkECGFCYWxhbmNlCQBkAgkA8AcCBQR0aGlzCQDZBAEFB2Fzc2V0SWQJAQxzdGFrZWRBbW91bnQBCQDZBAEFB2Fzc2V0SWQDCQBmAgkAkQMCBRBjb250cmFjdEJhbGFuY2VzBQFpBQhhQmFsYW5jZQkAlAoCBgUBaQkAlAoCBwkAZAIFAWkAAQoAAiRsBQhhc3NldElkcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgcAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEMY2hlY2tCYWxhbmNlAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxNQkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwERc3VzcGVuZFN1c3BpY2lvdXMBAWkJAQdzdXNwZW5kAQkArAICAh1TdXNwaWNpb3VzIHN0YXRlIHdpdGggYXNzZXQ6IAkAkQMCBQhhc3NldElkcwUBaQEOcmV0dXJuUGF5bWVudHMCBmNhbGxlcghwYXltZW50cwoBDXBhcnNlUGF5bWVudHMCA2FjYwdwYXltZW50CQDNCAIFA2FjYwkBDlNjcmlwdFRyYW5zZmVyAwUGY2FsbGVyCAUHcGF5bWVudAZhbW91bnQIBQdwYXltZW50B2Fzc2V0SWQKAAIkbAUIcGF5bWVudHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBDXBhcnNlUGF5bWVudHMCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDE1CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPEANtc2cBAUQCAnhwA2FtcAQBRAkBDmdldF9EX2ludGVybmFsAgUCeHAFA2FtcAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCAgFEBQFEBQNuaWwFAUQDbXNnAQRpbml0AwVjb2lucwJfQQxmaXJzdEhhcnZlc3QDCQEBIQEJAJ4IAQUEdGhpcwkAAgECE0FscmVhZHkgaW5pdGlhbGl6ZWQECXNoYXJlTmFtZQILc19NdWx0aV9VU0QEEHNoYXJlRGVzY3JpcHRpb24JAKwCAgJCU2hhcmVUb2tlbiBvZiBTd29wRmkgcHJvdG9jb2wgZm9yIE11bHRpU3RhYmxlIFVTRCBwb29sIGF0IGFkZHJlc3MgCQClCAEFBHRoaXMECmlzc3VlVG9rZW4JAMIIBQUJc2hhcmVOYW1lBRBzaGFyZURlc2NyaXB0aW9uAAAABgYEB3Rva2VuSWQJALgIAQUKaXNzdWVUb2tlbgQJYmFzZUVudHJ5CQDMCAIJAQtTdHJpbmdFbnRyeQIFB2tBc3NldHMFBWNvaW5zCQDMCAIJAQxJbnRlZ2VyRW50cnkCAglpbml0aWFsX0EFAl9BCQDMCAIJAQxJbnRlZ2VyRW50cnkCAghmdXR1cmVfQQUCX0EJAMwIAgkBDEludGVnZXJFbnRyeQIFBGtGZWUJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBm9yYWNsZQINYmFzZV9mZWVfZmxhdAkAzAgCCQELU3RyaW5nRW50cnkCBQ1rU2hhcmVBc3NldElkCQDYBAEFB3Rva2VuSWQJAMwIAgkBDEludGVnZXJFbnRyeQIFEWtTaGFyZUFzc2V0U3VwcGx5AAAJAMwIAgkBDEJvb2xlYW5FbnRyeQIFB2tBY3RpdmUGCQDMCAIFCmlzc3VlVG9rZW4FA25pbAMFDGZpcnN0SGFydmVzdAkAzggCBQliYXNlRW50cnkJAMwIAgkBDEJvb2xlYW5FbnRyeQIFDWtGaXJzdEhhcnZlc3QFDGZpcnN0SGFydmVzdAkAzAgCCQEMSW50ZWdlckVudHJ5AgUTa0ZpcnN0SGFydmVzdEhlaWdodAkAZAIFC3N0YXJ0SGVpZ2h0CQBoAgUVZmlyc3RIYXJ2ZXN0RW5kUGVyaW9kBQxwZXJpb2RMZW5ndGgFA25pbAUJYmFzZUVudHJ5A21zZwEMYWRkTGlxdWlkaXR5Ag1taW5NaW50QW1vdW50DHN0YWtlRmFybWluZwkBC3ZhbHVlT3JFbHNlAgkBCGlzQWN0aXZlAAQDYW1wCQECX0EABAJ4cAkBA194cAAEAkQwAwkAAAIFC3NoYXJlU3VwcGx5AAAAAAkBB2dldERNZW0CBQJ4cAUDYW1wBAhwYXltZW50cwgFA21zZwhwYXltZW50cwQBbgkAkAMBBQhwYXltZW50cwoBDXZhbGlkUGF5bWVudHMBAW4DCQBmAgUBbgUGbkNvaW5zCQACAQkArAICAhBwYXltZW50cyBzaXplID4gCQCkAwEFBm5Db2lucwMJAGYCAAEFAW4JAAIBAhFwYXltZW50cyBzaXplIDwgMQMDCQAAAgULc2hhcmVTdXBwbHkAAAkBAiE9AgUGbkNvaW5zBQFuBwkAAgECImluaXRpYWwgZGVwb3NpdCByZXF1aXJlcyBhbGwgY29pbnMKAQxwYXltYW50VmFsaWQCA2FjYwdwYXltZW50AwkBD2NvbnRhaW5zRWxlbWVudAIFCGFzc2V0SWRzCQENZ2V0U3RyQXNzZXRJZAEIBQdwYXltZW50B2Fzc2V0SWQGCQACAQIYSW52YWxpZCBhc3NldCBpbiBwYXltZW50CgACJGwFCHBheW1lbnRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAcKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBDHBheW1hbnRWYWxpZAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTUJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8DCQEBIQEJAQ12YWxpZFBheW1lbnRzAQUBbgkBBXRocm93AAQKc3VzcGljaW91cwkBD2NoZWNrU3VzcGljaW91cwADCAUKc3VzcGljaW91cwJfMQkAzggCCQERc3VzcGVuZFN1c3BpY2lvdXMBCAUKc3VzcGljaW91cwJfMgkBDnJldHVyblBheW1lbnRzAggFA21zZwZjYWxsZXIFCHBheW1lbnRzBAxwYXltZW50c1NpemUJAJADAQUIcGF5bWVudHMKAQ1wYXJzZVBheW1lbnRzAgNhY2MHYXNzZXRJZAQNJHQwMTUzOTcxNTQyNgUDYWNjBAtuZXdCYWxhbmNlcwgFDSR0MDE1Mzk3MTU0MjYCXzEEAWkIBQ0kdDAxNTM5NzE1NDI2Al8yBAFqCAUNJHQwMTUzOTcxNTQyNgJfMwMDCQBmAgUMcGF5bWVudHNTaXplBQFqCQAAAgkBDWdldFN0ckFzc2V0SWQBCAkAkQMCBQhwYXltZW50cwUBagdhc3NldElkBQdhc3NldElkBwQBcwkBBXN0YWtlAggJAJEDAgUIcGF5bWVudHMFAWoGYW1vdW50CQENZ2V0U3RyQXNzZXRJZAEICQCRAwIFCHBheW1lbnRzBQFqB2Fzc2V0SWQDCQAAAgUBcwUBcwkAlQoDCQDNCAIFC25ld0JhbGFuY2VzCQBkAgkAkQMCBQJ4cAUBaQgJAJEDAgUIcGF5bWVudHMFAWoGYW1vdW50CQBkAgUBaQABCQBkAgUBagABCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQCVCgMJAM0IAgULbmV3QmFsYW5jZXMJAJEDAgUCeHAFAWkJAGQCBQFpAAEFAWoEDSR0MDE1NzMyMTU4MTgKAAIkbAUIYXNzZXRJZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCVCgMFA25pbAAAAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBDXBhcnNlUGF5bWVudHMCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDE1CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPBAtuZXdCYWxhbmNlcwgFDSR0MDE1NzMyMTU4MTgCXzEEAWsIBQ0kdDAxNTczMjE1ODE4Al8yBA5wYXJzZWRQYXltZW50cwgFDSR0MDE1NzMyMTU4MTgCXzMDCQBmAgkAZQIFDHBheW1lbnRzU2l6ZQABBQ5wYXJzZWRQYXltZW50cwkAAgECF0luY29yZWN0IHBheW1lbnRzIG9yZGVyBAJEMQkBB2dldERNZW0CBQtuZXdCYWxhbmNlcwUDYW1wAwkBBmFzc2VydAEJAGYCBQJEMQUCRDAJAAIBAgdEMSA+IEQwBAtmZWVEaXNjb3VudAkBFGNhbGN1bGF0ZUZlZURpc2NvdW50AQgFA21zZwZjYWxsZXIKARFjYWxjU2NyaXB0QWN0aW9ucwIDYWNjCm5ld0JhbGFuY2UEDSR0MDE2MTY1MTYyMDYFA2FjYwQLaW52QmFsYW5jZXMIBQ0kdDAxNjE2NTE2MjA2Al8xBA1zY3JpcHRBY3Rpb25zCAUNJHQwMTYxNjUxNjIwNgJfMgQBaQgFDSR0MDE2MTY1MTYyMDYCXzMDCQBmAgULc2hhcmVTdXBwbHkAAAQEX2ZlZQkAaQIJAGgCCQBuBAUDZmVlBQtmZWVEaXNjb3VudAUJZmVlU2NhbGU2BQdDRUlMSU5HBQZuQ29pbnMJAGgCAAQJAGUCBQZuQ29pbnMAAQQEZmVlcwQMaWRlYWxCYWxhbmNlCQBrAwUCRDEJAJEDAgUCeHAFAWkFAkQwBApkaWZmZXJlbmNlAwkAZgIFDGlkZWFsQmFsYW5jZQUKbmV3QmFsYW5jZQkAZQIFDGlkZWFsQmFsYW5jZQUKbmV3QmFsYW5jZQkAZQIFCm5ld0JhbGFuY2UFDGlkZWFsQmFsYW5jZQkAawMFBF9mZWUFCmRpZmZlcmVuY2UFCWZlZVNjYWxlNgQOZ292ZXJuYW5jZUZlZXMJAGsDBQRmZWVzBQ1mZWVHb3Zlcm5hbmNlBQlmZWVTY2FsZTYEDGZpbmFsQmFsYW5jZQkAZQIFCm5ld0JhbGFuY2UFDmdvdmVybmFuY2VGZWVzBBBpbnZhcmlhbnRCYWxhbmNlCQBlAgUKbmV3QmFsYW5jZQUEZmVlcwQCdXMJAQd1bnN0YWtlAgUEZmVlcwkAkQMCBQhhc3NldElkcwUBaQMJAAACBQJ1cwUCdXMJAJUKAwkAzQgCBQtpbnZCYWxhbmNlcwUQaW52YXJpYW50QmFsYW5jZQkAzggCBQ1zY3JpcHRBY3Rpb25zCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFEmNhcE1vbmV5Qm94QWRkcmVzcwkAZQIFBGZlZXMFDmdvdmVybmFuY2VGZWVzCQDZBAEJAJEDAgUIYXNzZXRJZHMFAWkJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUPbW9uZXlCb3hBZGRyZXNzBQ5nb3Zlcm5hbmNlRmVlcwkA2QQBCQCRAwIFCGFzc2V0SWRzBQFpCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAJEDAgUIYXNzZXRJZHMFAWkFDWtBc3NldEJhbGFuY2UFDGZpbmFsQmFsYW5jZQUDbmlsCQBkAgUBaQABCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQCVCgMJAM0IAgULaW52QmFsYW5jZXMFCm5ld0JhbGFuY2UJAM0IAgUNc2NyaXB0QWN0aW9ucwkBDEludGVnZXJFbnRyeQIJAKwCAgkAkQMCBQhhc3NldElkcwUBaQUNa0Fzc2V0QmFsYW5jZQUKbmV3QmFsYW5jZQkAZAIFAWkAAQQNJHQwMTc1NDMxNzYzMQoAAiRsBQtuZXdCYWxhbmNlcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJUKAwUDbmlsBQNuaWwAAAoBBSRmMV8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQERY2FsY1NjcmlwdEFjdGlvbnMCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjFfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDE1CQEFJGYxXzICCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPBAtpbnZCYWxhbmNlcwgFDSR0MDE3NTQzMTc2MzECXzEEDXNjcmlwdEFjdGlvbnMIBQ0kdDAxNzU0MzE3NjMxAl8yBAJEMgkBB2dldERNZW0CBQtpbnZCYWxhbmNlcwUDYW1wBAttaW50X2Ftb3VudAMJAAACBQtzaGFyZVN1cHBseQAABQJEMQkAawMFC3NoYXJlU3VwcGx5CQBlAgUCRDIFAkQwBQJEMAMJAQZhc3NlcnQBCQBnAgULbWludF9hbW91bnQFDW1pbk1pbnRBbW91bnQJAAIBAhRTbGlwcGFnZSBzY3Jld2VkIHlvdQMFDHN0YWtlRmFybWluZwQCcmUJAQdSZWlzc3VlAwUMc2hhcmVBc3NldElkBQttaW50X2Ftb3VudAYDCQAAAgUCcmUFAnJlBAFzCQD8BwQFDmZhcm1pbmdBZGRyZXNzAg9sb2NrU2hhcmVUb2tlbnMJAMwIAgkApQgBCAUDbXNnBmNhbGxlcgUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQxzaGFyZUFzc2V0SWQFC21pbnRfYW1vdW50BQNuaWwDCQAAAgUBcwUBcwUNc2NyaXB0QWN0aW9ucwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAzggCBQ1zY3JpcHRBY3Rpb25zCQDMCAIJAQdSZWlzc3VlAwUMc2hhcmVBc3NldElkBQttaW50X2Ftb3VudAYJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFA21zZwZjYWxsZXIFC21pbnRfYW1vdW50BQxzaGFyZUFzc2V0SWQJAMwIAgkBDEludGVnZXJFbnRyeQIFEWtTaGFyZUFzc2V0U3VwcGx5CQBkAgULc2hhcmVTdXBwbHkFC21pbnRfYW1vdW50BQNuaWwDbXNnAQVnZXREeQQJYXNzZXRGcm9tB2Fzc2V0VG8CZHgLdXNlckFkZHJlc3MEAnhwCQEDX3hwAAQJZnJvbUluZGV4CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAM8IAgUIYXNzZXRJZHMFCWFzc2V0RnJvbQIQdW5rbm93biB0b2tlbiBpbgQHdG9JbmRleAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDPCAIFCGFzc2V0SWRzBQdhc3NldFRvAhF1bmtub3duIHRva2VuIG91dAQBeAkAZAIJAJEDAgUCeHAFCWZyb21JbmRleAUCZHgEAXkJAQRnZXRZBAUJZnJvbUluZGV4BQd0b0luZGV4BQF4BQJ4cAQCZHkJAGUCCQBlAgkAkQMCBQJ4cAUHdG9JbmRleAUBeQABBAtmZWVEaXNjb3VudAkBFGNhbGN1bGF0ZUZlZURpc2NvdW50AQkBB0FkZHJlc3MBCQDZBAEFC3VzZXJBZGRyZXNzBARfZmVlCQBrAwkAbgQFA2ZlZQULZmVlRGlzY291bnQFCWZlZVNjYWxlNgUHQ0VJTElORwUCZHkFCWZlZVNjYWxlNgkAlAoCBQNuaWwJAGUCBQJkeQUEX2ZlZQNtc2cBCGV4Y2hhbmdlAgh0b2tlbk91dAZtaW5fZHkJAQt2YWx1ZU9yRWxzZQIJAQhpc0FjdGl2ZQADCQECIT0CCQCQAwEIBQNtc2cIcGF5bWVudHMAAQkAAgECE3NpemUocGF5bWVudHMpICE9IDEECnN1c3BpY2lvdXMJAQ9jaGVja1N1c3BpY2lvdXMAAwgFCnN1c3BpY2lvdXMCXzEJAM4IAgkBEXN1c3BlbmRTdXNwaWNpb3VzAQgFCnN1c3BpY2lvdXMCXzIJAQ5yZXR1cm5QYXltZW50cwIIBQNtc2cGY2FsbGVyCAUDbXNnCHBheW1lbnRzBAdwYXltZW50CQCRAwIIBQNtc2cIcGF5bWVudHMAAAQHdG9rZW5JbgkBDWdldFN0ckFzc2V0SWQBCAUHcGF5bWVudAdhc3NldElkBAt0b2tlbk91dEI1OAkA2QQBBQh0b2tlbk91dAQCZHgIBQdwYXltZW50BmFtb3VudAQJZnJvbUluZGV4CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAM8IAgUIYXNzZXRJZHMFB3Rva2VuSW4CEHVua25vd24gdG9rZW4gaW4EB3RvSW5kZXgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAzwgCBQhhc3NldElkcwUIdG9rZW5PdXQCEXVua25vd24gdG9rZW4gb3V0BAJ4cAkBA194cAAEAXgJAGQCCQCRAwIFAnhwBQlmcm9tSW5kZXgFAmR4BAF5CQEEZ2V0WQQFCWZyb21JbmRleAUHdG9JbmRleAUBeAUCeHAEA19keQkAZQIJAGUCCQCRAwIFAnhwBQd0b0luZGV4BQF5AAEEC2ZlZURpc2NvdW50CQEUY2FsY3VsYXRlRmVlRGlzY291bnQBCAUDbXNnBmNhbGxlcgQEX2ZlZQkAawMFA19keQkAbgQFA2ZlZQULZmVlRGlzY291bnQFCWZlZVNjYWxlNgUHQ0VJTElORwUJZmVlU2NhbGU2BAJkeQkAZQIFA19keQUEX2ZlZQMJAQZhc3NlcnQBCQBnAgUCZHkFBm1pbl9keQkAAgECLkV4Y2hhbmdlIHJlc3VsdGVkIGluIGZld2VyIGNvaW5zIHRoYW4gZXhwZWN0ZWQEDmdvdmVybmFuY2VGZWVzCQBrAwUEX2ZlZQUNZmVlR292ZXJuYW5jZQUJZmVlU2NhbGU2BAFzCQEFc3Rha2UCCAUHcGF5bWVudAZhbW91bnQJAQ1nZXRTdHJBc3NldElkAQgFB3BheW1lbnQHYXNzZXRJZAMJAAACBQFzBQFzBAJ1cwkBB3Vuc3Rha2UCCQBkAgUCZHkFBF9mZWUFCHRva2VuT3V0AwkAAAIFAnVzBQJ1cwkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFB3Rva2VuSW4FDWtBc3NldEJhbGFuY2UFAXgJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUIdG9rZW5PdXQFDWtBc3NldEJhbGFuY2UJAGUCCQBlAgkAkQMCBQJ4cAUHdG9JbmRleAUCZHkFDmdvdmVybmFuY2VGZWVzCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQNtc2cGY2FsbGVyBQJkeQULdG9rZW5PdXRCNTgJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUPbW9uZXlCb3hBZGRyZXNzBQ5nb3Zlcm5hbmNlRmVlcwULdG9rZW5PdXRCNTgJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUPbW9uZXlCb3hBZGRyZXNzCQBlAgUEX2ZlZQUOZ292ZXJuYW5jZUZlZXMFC3Rva2VuT3V0QjU4BQNuaWwJAJQKAgUCZHkFC3Rva2VuT3V0QjU4CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuA21zZwEId2l0aGRyYXcCCm1pbkFtb3VudHMMdW5sb2NrQW1vdW50CQELdmFsdWVPckVsc2UCCQEIaXNBY3RpdmUAAwkBAiE9AgkAkAMBCAUDbXNnCHBheW1lbnRzAAEJAAIBAhNzaXplKHBheW1lbnRzKSAhPSAxBApzdXNwaWNpb3VzCQEPY2hlY2tTdXNwaWNpb3VzAAMIBQpzdXNwaWNpb3VzAl8xCQDOCAIJARFzdXNwZW5kU3VzcGljaW91cwEIBQpzdXNwaWNpb3VzAl8yCQEOcmV0dXJuUGF5bWVudHMCCAUDbXNnBmNhbGxlcggFA21zZwhwYXltZW50cwQHcGF5bWVudAkAkQMCCAUDbXNnCHBheW1lbnRzAAAEB3Rva2VuSW4IBQdwYXltZW50B2Fzc2V0SWQDCQECIT0CBQd0b2tlbkluBQxzaGFyZUFzc2V0SWQJAAIBAg11bmtub3duIHRva2VuBAdfYW1vdW50CAUHcGF5bWVudAZhbW91bnQEDHRvdGFsX3N1cHBseQULc2hhcmVTdXBwbHkEBnVubG9jawMJAGYCBQx1bmxvY2tBbW91bnQAAAkA/AcEBQ5mYXJtaW5nQWRkcmVzcwITd2l0aGRyYXdTaGFyZVRva2VucwkAzAgCCQClCAEIBQNtc2cGY2FsbGVyCQDMCAIFDHVubG9ja0Ftb3VudAUDbmlsBQNuaWwAAAMJAAACBQZ1bmxvY2sFBnVubG9jawQOd2l0aGRyYXdBbW91bnQJAGQCBQdfYW1vdW50BQx1bmxvY2tBbW91bnQKARFjYWxjU2NyaXB0QWN0aW9ucwIDYWNjB2JhbGFuY2UEDSR0MDIxNDE1MjE0NDMFA2FjYwQNc2NyaXB0QWN0aW9ucwgFDSR0MDIxNDE1MjE0NDMCXzEEAWkIBQ0kdDAyMTQxNTIxNDQzAl8yBAd3QW1vdW50CQBrAwUHYmFsYW5jZQUOd2l0aGRyYXdBbW91bnQFDHRvdGFsX3N1cHBseQMJAQZhc3NlcnQBCQBnAgUHd0Ftb3VudAkAkQMCBQptaW5BbW91bnRzBQFpCQACAQIwV2l0aGRyYXdhbCByZXN1bHRlZCBpbiBmZXdlciBjb2lucyB0aGFuIGV4cGVjdGVkBAJ1cwkBB3Vuc3Rha2UCBQd3QW1vdW50CQCRAwIFCGFzc2V0SWRzBQFpAwkAAAIFAnVzBQJ1cwkAlAoCCQDOCAIFDXNjcmlwdEFjdGlvbnMJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkAkQMCBQhhc3NldElkcwUBaQUNa0Fzc2V0QmFsYW5jZQkAZQIFB2JhbGFuY2UFB3dBbW91bnQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFA21zZwZjYWxsZXIFB3dBbW91bnQJANkEAQkAkQMCBQhhc3NldElkcwUBaQUDbmlsCQBkAgUBaQABCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBA0kdDAyMTkzMzIyMDAxCgACJGwJAQNfeHAACgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlAoCBQNuaWwAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQERY2FsY1NjcmlwdEFjdGlvbnMCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDE1CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPBA1zY3JpcHRBY3Rpb25zCAUNJHQwMjE5MzMyMjAwMQJfMQQBaQgFDSR0MDIxOTMzMjIwMDECXzIJAM4IAgUNc2NyaXB0QWN0aW9ucwkAzAgCCQEEQnVybgIFDHNoYXJlQXNzZXRJZAUOd2l0aGRyYXdBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIFEWtTaGFyZUFzc2V0U3VwcGx5CQBlAgULc2hhcmVTdXBwbHkFDndpdGhkcmF3QW1vdW50BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4DbXNnARNjYWxjV2l0aGRyYXdPbmVDb2luAgxfdG9rZW5BbW91bnQBaQkAlAoCBQNuaWwICQEUX2NhbGNXaXRoZHJhd09uZUNvaW4ECQEDX3hwAAUMX3Rva2VuQW1vdW50BQFpCAUDbXNnBmNhbGxlcgJfMQNtc2cBD3dpdGhkcmF3T25lQ29pbgMIdG9rZW5PdXQJbWluQW1vdW50DHVubG9ja0Ftb3VudAkBC3ZhbHVlT3JFbHNlAgkBCGlzQWN0aXZlAAMJAQIhPQIJAJADAQgFA21zZwhwYXltZW50cwABCQACAQITc2l6ZShwYXltZW50cykgIT0gMQQKc3VzcGljaW91cwkBD2NoZWNrU3VzcGljaW91cwADCAUKc3VzcGljaW91cwJfMQkAzggCCQERc3VzcGVuZFN1c3BpY2lvdXMBCAUKc3VzcGljaW91cwJfMgkBDnJldHVyblBheW1lbnRzAggFA21zZwZjYWxsZXIIBQNtc2cIcGF5bWVudHMEB3BheW1lbnQJAJEDAggFA21zZwhwYXltZW50cwAABAd0b2tlbkluCAUHcGF5bWVudAdhc3NldElkAwkBAiE9AgUHdG9rZW5JbgUMc2hhcmVBc3NldElkCQACAQINdW5rbm93biB0b2tlbgQBaQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDPCAIFCGFzc2V0SWRzBQh0b2tlbk91dAIRdW5rbm93biB0b2tlbiBvdXQEDF90b2tlbkFtb3VudAgFB3BheW1lbnQGYW1vdW50BAZ1bmxvY2sDCQBmAgUMdW5sb2NrQW1vdW50AAAJAPwHBAUOZmFybWluZ0FkZHJlc3MCE3dpdGhkcmF3U2hhcmVUb2tlbnMJAMwIAgkApQgBCAUDbXNnBmNhbGxlcgkAzAgCBQx1bmxvY2tBbW91bnQFA25pbAUDbmlsAAADCQAAAgUGdW5sb2NrBQZ1bmxvY2sEDndpdGhkcmF3QW1vdW50CQBkAgUMX3Rva2VuQW1vdW50BQx1bmxvY2tBbW91bnQEAnhwCQEDX3hwAAQNJHQwMjMxMDgyMzE4MgkBFF9jYWxjV2l0aGRyYXdPbmVDb2luBAUCeHAFDndpdGhkcmF3QW1vdW50BQFpCAUDbXNnBmNhbGxlcgQCZHkIBQ0kdDAyMzEwODIzMTgyAl8xBAZkeV9mZWUIBQ0kdDAyMzEwODIzMTgyAl8yAwkBBmFzc2VydAEJAGcCBQJkeQUJbWluQW1vdW50CQACAQIYTm90IGVub3VnaCBjb2lucyByZW1vdmVkBA5nb3Zlcm5hbmNlRmVlcwkAawMFBmR5X2ZlZQUNZmVlR292ZXJuYW5jZQUJZmVlU2NhbGU2BApkeV9hbmRfZmVlCQBkAgUCZHkFBmR5X2ZlZQQCdXMJAQd1bnN0YWtlAgUKZHlfYW5kX2ZlZQUIdG9rZW5PdXQDCQAAAgUCdXMFAnVzCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQNtc2cGY2FsbGVyBQJkeQkA2QQBBQh0b2tlbk91dAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCRAwIFCGFzc2V0SWRzBQFpBQ1rQXNzZXRCYWxhbmNlCQBlAgkAkQMCBQJ4cAUBaQUKZHlfYW5kX2ZlZQkAzAgCCQEEQnVybgIFDHNoYXJlQXNzZXRJZAUOd2l0aGRyYXdBbW91bnQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUPbW9uZXlCb3hBZGRyZXNzBQ5nb3Zlcm5hbmNlRmVlcwkA2QQBBQh0b2tlbk91dAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBRJjYXBNb25leUJveEFkZHJlc3MJAGUCBQZkeV9mZWUFDmdvdmVybmFuY2VGZWVzCQDZBAEFCHRva2VuT3V0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBRFrU2hhcmVBc3NldFN1cHBseQkAZQIFC3NoYXJlU3VwcGx5BQ53aXRoZHJhd0Ftb3VudAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuA21zZwEBQQAJAJQKAgUDbmlsCQECX0EAA21zZwEPZ2V0VmlydHVhbFByaWNlAAQBRAkBBWdldF9EAgkBA194cAAJAQJfQQAJAJQKAgUDbmlsCQBrAwUBRAUJUFJFQ0lTSU9OBQtzaGFyZVN1cHBseQNtc2cBD2NhbGNUb2tlbkFtb3VudAIHYW1vdW50cwdkZXBvc2l0BANhbXAJAQJfQQAECGJhbGFuY2VzCQEDX3hwAAQCRDAJAQdnZXRETWVtAgUIYmFsYW5jZXMFA2FtcAoBD2NhbGNOZXdCYWxhbmNlcwIDYWNjB2JhbGFuY2UEDSR0MDI0MjYxMjQyODcFA2FjYwQLbmV3QmFsYW5jZXMIBQ0kdDAyNDI2MTI0Mjg3Al8xBAFpCAUNJHQwMjQyNjEyNDI4NwJfMgQKbmV3QmFsYW5jZQkAZAIFB2JhbGFuY2UDBQdkZXBvc2l0CQCRAwIFB2Ftb3VudHMFAWkJAQEtAQkAkQMCBQdhbW91bnRzBQFpCQCUCgIJAM0IAgULbmV3QmFsYW5jZXMFCm5ld0JhbGFuY2UJAGQCBQFpAAEEC25ld0JhbGFuY2VzCAoAAiRsBQhiYWxhbmNlcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgUDbmlsAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBD2NhbGNOZXdCYWxhbmNlcwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTUJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8CXzEEAkQxCQEHZ2V0RE1lbQIFC25ld0JhbGFuY2VzBQNhbXAEBGRpZmYDBQdkZXBvc2l0CQBlAgUCRDEFAkQwCQBlAgUCRDAFAkQxCQCUCgIFA25pbAkAawMFBGRpZmYFC3NoYXJlU3VwcGx5BQJEMANtc2cBBXJhbXBBAghfZnV0dXJlQQtfZnV0dXJlVGltZQkBC3ZhbHVlT3JFbHNlAgkBCGlzQWN0aXZlAAkBC3ZhbHVlT3JFbHNlAgkBC2lzQWRtaW5DYWxsAQUDbXNnAwkBBmFzc2VydAEJAGcCBQ5ibG9ja1RpbWVzdGFtcAkAZAIFDmluaXRpYWxfQV90aW1lBQ1NSU5fUkFNUF9USU1FCQACAQIJdG9vIG9mdGVuAwkBBmFzc2VydAEJAGcCBQtfZnV0dXJlVGltZQkAZAIFDmJsb2NrVGltZXN0YW1wBQ1NSU5fUkFNUF9USU1FCQACAQIRaW5zdWZmaWNpZW50IHRpbWUECl9pbml0aWFsX0EJAQJfQQADCQEGYXNzZXJ0AQMJAGYCBQhfZnV0dXJlQQAACQBmAgUFTUFYX0EFCF9mdXR1cmVBBwkAAgECEW91dCBvZiBiYXNlIHJhbmdlAwkBBmFzc2VydAEDAwkAZwIFCF9mdXR1cmVBBQpfaW5pdGlhbF9BCQBnAgkAaAIFCl9pbml0aWFsX0EFDE1BWF9BX0NIQU5HRQUIX2Z1dHVyZUEHBgMJAGYCBQpfaW5pdGlhbF9BBQhfZnV0dXJlQQkAZwIJAGgCBQhfZnV0dXJlQQUMTUFYX0FfQ0hBTkdFBQpfaW5pdGlhbF9BBwkAAgECDG91dCBvZiByYW5nZQkAzAgCCQEMSW50ZWdlckVudHJ5AgIJaW5pdGlhbF9BBQpfaW5pdGlhbF9BCQDMCAIJAQxJbnRlZ2VyRW50cnkCAghmdXR1cmVfQQUIX2Z1dHVyZUEJAMwIAgkBDEludGVnZXJFbnRyeQICDmluaXRpYWxfQV90aW1lBQ5ibG9ja1RpbWVzdGFtcAkAzAgCCQEMSW50ZWdlckVudHJ5AgINZnV0dXJlX0FfdGltZQULX2Z1dHVyZVRpbWUFA25pbANtc2cBCXN0b3BSYW1wQQAJAQt2YWx1ZU9yRWxzZQIJAQhpc0FjdGl2ZQAJAQt2YWx1ZU9yRWxzZQIJAQtpc0FkbWluQ2FsbAEFA21zZwQIY3VycmVudEEJAQJfQQAJAMwIAgkBDEludGVnZXJFbnRyeQICCWluaXRpYWxfQQUIY3VycmVudEEJAMwIAgkBDEludGVnZXJFbnRyeQICCGZ1dHVyZV9BBQhjdXJyZW50QQkAzAgCCQEMSW50ZWdlckVudHJ5AgIOaW5pdGlhbF9BX3RpbWUFDmJsb2NrVGltZXN0YW1wCQDMCAIJAQxJbnRlZ2VyRW50cnkCAg1mdXR1cmVfQV90aW1lBQ5ibG9ja1RpbWVzdGFtcAUDbmlsA21zZwEIc2h1dGRvd24ACQELdmFsdWVPckVsc2UCCQELaXNBZG1pbkNhbGwBBQNtc2cDCQEBIQEFBmFjdGl2ZQkAAgEJAKwCAgIiREFwcCBpcyBhbHJlYWR5IHN1c3BlbmRlZC4gQ2F1c2U6IAkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQZrQ2F1c2UCGnRoZSBjYXVzZSB3YXNuJ3Qgc3BlY2lmaWVkCQEHc3VzcGVuZAECD1BhdXNlZCBieSBhZG1pbgNtc2cBCGFjdGl2YXRlAAkBC3ZhbHVlT3JFbHNlAgkBC2lzQWRtaW5DYWxsAQUDbXNnAwUGYWN0aXZlCQENdGhyb3dJc0FjdGl2ZQAJAMwIAgkBDEJvb2xlYW5FbnRyeQIFB2tBY3RpdmUGCQDMCAIJAQtEZWxldGVFbnRyeQEFBmtDYXVzZQUDbmlsA21zZwEYa2VlcExpbWl0Rm9yRmlyc3RIYXJ2ZXN0AQpzaGFyZUxpbWl0CQELdmFsdWVPckVsc2UCCQEIaXNBY3RpdmUACQELdmFsdWVPckVsc2UCCQELaXNBZG1pbkNhbGwBBQNtc2cJAMwIAgkBDEludGVnZXJFbnRyeQIFC2tTaGFyZUxpbWl0BQpzaGFyZUxpbWl0BQNuaWwBAnR4AQZ2ZXJpZnkABBNtdWx0aVNpZ25lZEJ5QWRtaW5zBBJhZG1pblB1YktleTFTaWduZWQDCQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwAABQxhZG1pblB1YktleTEAAQAABBJhZG1pblB1YktleTJTaWduZWQDCQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwABBQxhZG1pblB1YktleTIAAQAABBJhZG1pblB1YktleTNTaWduZWQDCQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwACBQxhZG1pblB1YktleTMAAQAACQBnAgkAZAIJAGQCBRJhZG1pblB1YktleTFTaWduZWQFEmFkbWluUHViS2V5MlNpZ25lZAUSYWRtaW5QdWJLZXkzU2lnbmVkAAIEByRtYXRjaDAFAnR4AwkAAQIFByRtYXRjaDACF0ludm9rZVNjcmlwdFRyYW5zYWN0aW9uBANpbnYFByRtYXRjaDAEE2NhbGxUYWtlSW50b0FjY291bnQDCQAAAggFA2ludgRkQXBwBQR0aGlzCQAAAggFA2ludghmdW5jdGlvbgIZdGFrZUludG9BY2NvdW50RXh0cmFGdW5kcwcEDXNpZ25lZEJ5QWRtaW4DAwMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAFDGFkbWluUHViS2V5MQYJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAFDGFkbWluUHViS2V5MgYJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAFDGFkbWluUHViS2V5MwYJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAFEWFkbWluUHViS2V5SW52b2tlAwMFE2NhbGxUYWtlSW50b0FjY291bnQFDXNpZ25lZEJ5QWRtaW4HBgUTbXVsdGlTaWduZWRCeUFkbWlucwUTbXVsdGlTaWduZWRCeUFkbWluc19hFKI=", "height": 2201279, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: none Next: GEaeM9fCm1rGRt7K8hVLSwgYbyDeW8CePU4TeMpfMnsh Full:
OldNewDifferences
1-# no script
1+{-# STDLIB_VERSION 6 #-}
2+{-# SCRIPT_TYPE ACCOUNT #-}
3+{-# CONTENT_TYPE DAPP #-}
4+let PRECISION = 1000000
5+
6+let MAX_A = 1000000
7+
8+let MAX_A_CHANGE = 10
9+
10+let MIN_RAMP_TIME = (86400 / 60)
11+
12+let kAssets = "asset_ids"
13+
14+let kAssetBalance = "_balance"
15+
16+let kActive = "active"
17+
18+let kCause = "shutdown_cause"
19+
20+let kShareAssetId = "share_asset_id"
21+
22+let kShareAssetSupply = "share_asset_supply"
23+
24+let kFee = "commission"
25+
26+let kUSDNAddress = "staking_usdnnsbt_address"
27+
28+let kDiscounts = "discounts"
29+
30+let kDiscountValues = "discount_values"
31+
32+let kUserSwopInGov = "_SWOP_amount"
33+
34+let kFirstHarvest = "first_harvest"
35+
36+let kFirstHarvestHeight = "first_harvest_height"
37+
38+let kShareLimit = "share_limit_on_first_harvest"
39+
40+let kBasePeriod = "base_period"
41+
42+let kPeriodLength = "period_length"
43+
44+let kStartHeight = "start_height"
45+
46+let kAdminPubKey1 = "admin_pub_1"
47+
48+let kAdminPubKey2 = "admin_pub_2"
49+
50+let kAdminPubKey3 = "admin_pub_3"
51+
52+let kAdminInvokePubKey = "admin_invoke_pub"
53+
54+let kMoneyBoxAddress = "money_box_address"
55+
56+let kGovAddress = "governance_address"
57+
58+let kVotingAddress = "voting_address"
59+
60+let kFarmingAddress = "farming_address"
61+
62+let oracle = Address(base58'3NBBWfzZtZtszaXbitTKnrB2xXwv26Bn7H9')
63+
64+func getBase58FromOracle (key) = match getString(oracle, key) {
65+ case string: String =>
66+ fromBase58String(string)
67+ case nothing =>
68+ throw((key + "is empty"))
69+}
70+
71+
72+let adminPubKey1 = getBase58FromOracle(kAdminPubKey1)
73+
74+let adminPubKey2 = getBase58FromOracle(kAdminPubKey2)
75+
76+let adminPubKey3 = getBase58FromOracle(kAdminPubKey3)
77+
78+let adminPubKeyInvoke = getBase58FromOracle(kAdminInvokePubKey)
79+
80+let moneyBoxAddress = Address(getBase58FromOracle(kMoneyBoxAddress))
81+
82+let govAddress = Address(getBase58FromOracle(kGovAddress))
83+
84+let stakingUSDNAddress = Address(getBase58FromOracle(kUSDNAddress))
85+
86+let votingAddress = Address(getBase58FromOracle(kVotingAddress))
87+
88+let farmingAddress = Address(getBase58FromOracle(kFarmingAddress))
89+
90+let capMoneyBoxAddress = Address(base58'3NBBWfzZtZtszaXbitTKnrB2xXwv26Bn7H9')
91+
92+let USDN = base58'8UrfDVd5GreeUwm7uPk7eYz1eMv376kzR52C6sANPkwS'
93+
94+let stakingAssets = [toBase58String(USDN)]
95+
96+let basePeriod = valueOrErrorMessage(getInteger(votingAddress, kBasePeriod), "Empty kBasePeriod")
97+
98+let startHeight = valueOrErrorMessage(getInteger(votingAddress, kStartHeight), "Empty kStartHeight")
99+
100+let periodLength = valueOrErrorMessage(getInteger(votingAddress, kPeriodLength), "Empty kPeriodLength")
101+
102+let firstHarvestEndPeriod = ((basePeriod + ((height - startHeight) / periodLength)) + 3)
103+
104+let active = getBooleanValue(this, kActive)
105+
106+let shareAssetId = fromBase58String(getStringValue(this, kShareAssetId))
107+
108+let shareSupply = getIntegerValue(this, kShareAssetSupply)
109+
110+let feeScale6 = 1000000
111+
112+let fee = getIntegerValue(this, kFee)
113+
114+let feeGovernance = fraction(40, feeScale6, 100)
115+
116+let initial_A = getIntegerValue(this, "initial_A")
117+
118+let future_A = getIntegerValue(this, "future_A")
119+
120+let initial_A_time = valueOrElse(getInteger(this, "initial_A_time"), 0)
121+
122+let future_A_time = valueOrElse(getInteger(this, "future_A_time"), 0)
123+
124+let assetIds = split(getStringValue(this, kAssets), ",")
125+
126+let nCoins = size(assetIds)
127+
128+func suspend (cause) = [BooleanEntry(kActive, false), StringEntry(kCause, cause)]
129+
130+
131+func throwIsActive () = throw("DApp is already active")
132+
133+
134+func isActive () = if (active)
135+ then unit
136+ else throw("DApp is inactive at this moment")
137+
138+
139+func isAdminCall (i) = if (containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey))
140+ then unit
141+ else throw("Only admin can call this function")
142+
143+
144+let big2 = toBigInt(2)
145+
146+let blockTimestamp = height
147+
148+func assert (a) = if (a)
149+ then false
150+ else true
151+
152+
153+func calculateFeeDiscount (userAddr) = {
154+ let swopAmount = valueOrElse(getInteger(govAddress, (toString(userAddr) + kUserSwopInGov)), 0)
155+ let discountValues = split(getStringValue(oracle, kDiscountValues), ",")
156+ let discounts = split(getStringValue(oracle, kDiscounts), ",")
157+ if (if ((swopAmount >= parseIntValue(discountValues[0])))
158+ then (parseIntValue(discountValues[1]) > swopAmount)
159+ else false)
160+ then (feeScale6 - parseIntValue(discounts[0]))
161+ else if (if ((swopAmount >= parseIntValue(discountValues[1])))
162+ then (parseIntValue(discountValues[2]) > swopAmount)
163+ else false)
164+ then (feeScale6 - parseIntValue(discounts[1]))
165+ else if (if ((swopAmount >= parseIntValue(discountValues[2])))
166+ then (parseIntValue(discountValues[3]) > swopAmount)
167+ else false)
168+ then (feeScale6 - parseIntValue(discounts[2]))
169+ else if (if ((swopAmount >= parseIntValue(discountValues[3])))
170+ then (parseIntValue(discountValues[4]) > swopAmount)
171+ else false)
172+ then (feeScale6 - parseIntValue(discounts[3]))
173+ else if ((swopAmount >= parseIntValue(discountValues[4])))
174+ then (feeScale6 - parseIntValue(discounts[4]))
175+ else feeScale6
176+ }
177+
178+
179+func _A () = {
180+ let t1 = future_A_time
181+ let A1 = future_A
182+ if ((t1 > blockTimestamp))
183+ then {
184+ let A0 = initial_A
185+ let t0 = initial_A_time
186+ if ((A1 > A0))
187+ then (A0 + (((A1 - A0) * (blockTimestamp - t0)) / (t1 - t0)))
188+ else (A0 - (((A0 - A1) * (blockTimestamp - t0)) / (t1 - t0)))
189+ }
190+ else A1
191+ }
192+
193+
194+func _xp () = {
195+ func assetBalances (acc,assetId) = (acc :+ valueOrElse(getInteger(this, (assetId + kAssetBalance)), 0))
196+
197+ let $l = assetIds
198+ let $s = size($l)
199+ let $acc0 = nil
200+ func $f0_1 ($a,$i) = if (($i >= $s))
201+ then $a
202+ else assetBalances($a, $l[$i])
203+
204+ func $f0_2 ($a,$i) = if (($i >= $s))
205+ then $a
206+ else throw("List size exceeds 15")
207+
208+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15)
209+ }
210+
211+
212+func _xp_mem (xp) = xp
213+
214+
215+func sumList (acc,element) = (acc + element)
216+
217+
218+func get_D (xp,amp) = {
219+ let @ = invoke(this, "D", [xp, amp], nil)
220+ if ($isInstanceOf(@, "Int"))
221+ then @
222+ else throw(($getType(invoke(this, "D", [xp, amp], nil)) + " couldn't be cast to Int"))
223+ }
224+
225+
226+func get_D_internal (xp,amp) = {
227+ let S = {
228+ let $l = xp
229+ let $s = size($l)
230+ let $acc0 = 0
231+ func $f0_1 ($a,$i) = if (($i >= $s))
232+ then $a
233+ else sumList($a, $l[$i])
234+
235+ func $f0_2 ($a,$i) = if (($i >= $s))
236+ then $a
237+ else throw("List size exceeds 15")
238+
239+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15)
240+ }
241+ if ((S == 0))
242+ then 0
243+ else {
244+ let Ann = (amp * nCoins)
245+ let AnnS = (toBigInt(Ann) * toBigInt(S))
246+ let Ann1 = toBigInt((Ann - 1))
247+ func Dproc (acc,i) = if ((acc._2 == true))
248+ then acc
249+ else {
250+ let Dprev = acc._1
251+ func D_PProc (D_P,i) = if ((nCoins > i))
252+ then ((D_P * Dprev) / (toBigInt(xp[i]) * toBigInt(nCoins)))
253+ else D_P
254+
255+ let D_P = {
256+ let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
257+ let $s = size($l)
258+ let $acc0 = Dprev
259+ func $f1_1 ($a,$i) = if (($i >= $s))
260+ then $a
261+ else D_PProc($a, $l[$i])
262+
263+ func $f1_2 ($a,$i) = if (($i >= $s))
264+ then $a
265+ else throw("List size exceeds 15")
266+
267+ $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)
268+ }
269+ let D = fraction((AnnS + (toBigInt(nCoins) * D_P)), Dprev, ((Ann1 * Dprev) + (toBigInt((nCoins + 1)) * D_P)))
270+ if ((D > Dprev))
271+ then if ((1 >= toInt((D - Dprev))))
272+ then $Tuple2(D, true)
273+ else $Tuple2(D, false)
274+ else if ((1 >= toInt((Dprev - D))))
275+ then $Tuple2(D, true)
276+ else $Tuple2(D, false)
277+ }
278+
279+ let $t064426554 = {
280+ let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
281+ let $s = size($l)
282+ let $acc0 = $Tuple2(toBigInt(S), false)
283+ func $f1_1 ($a,$i) = if (($i >= $s))
284+ then $a
285+ else Dproc($a, $l[$i])
286+
287+ func $f1_2 ($a,$i) = if (($i >= $s))
288+ then $a
289+ else throw("List size exceeds 15")
290+
291+ $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)
292+ }
293+ let D = $t064426554._1
294+ let finished = $t064426554._2
295+ if ((finished == false))
296+ then throw(("get_D() not finished with " + toString(D)))
297+ else toInt(D)
298+ }
299+ }
300+
301+
302+func getDMem (xp,amp) = get_D(_xp_mem(xp), amp)
303+
304+
305+func getY (in,out,x,xp_) = if (assert((in != out)))
306+ then throw("same coin")
307+ else if (assert(if ((out >= 0))
308+ then (in >= 0)
309+ else false))
310+ then throw("below zero")
311+ else if (assert(if ((nCoins > out))
312+ then (nCoins > in)
313+ else false))
314+ then throw("above N_COINS")
315+ else {
316+ let amp = _A()
317+ let D = get_D(xp_, amp)
318+ let Ann = (amp * nCoins)
319+ func S_c (acc,i) = {
320+ let $t071257142 = acc
321+ let S_ = $t071257142._1
322+ let c = $t071257142._2
323+ let x_ = if ((in == i))
324+ then x
325+ else xp_[i]
326+ if (if ((i != out))
327+ then (nCoins > i)
328+ else false)
329+ then $Tuple2((S_ + x_), fraction(c, toBigInt(D), toBigInt((x_ * nCoins))))
330+ else $Tuple2(S_, c)
331+ }
332+
333+ let $t073507451 = {
334+ let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
335+ let $s = size($l)
336+ let $acc0 = $Tuple2(0, toBigInt(D))
337+ func $f0_1 ($a,$i) = if (($i >= $s))
338+ then $a
339+ else S_c($a, $l[$i])
340+
341+ func $f0_2 ($a,$i) = if (($i >= $s))
342+ then $a
343+ else throw("List size exceeds 15")
344+
345+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15)
346+ }
347+ let S_ = $t073507451._1
348+ let c_ = $t073507451._2
349+ let c = fraction(c_, toBigInt(D), toBigInt((Ann * nCoins)))
350+ let bD = toBigInt(((S_ + (D / Ann)) - D))
351+ func y_proc (acc,_i) = if ((acc._2 == true))
352+ then acc
353+ else {
354+ let y_prev = acc._1
355+ let y = (((y_prev * y_prev) + c) / ((big2 * y_prev) + bD))
356+ if ((y > y_prev))
357+ then if ((1 >= toInt((y - y_prev))))
358+ then $Tuple2(y, true)
359+ else $Tuple2(y, false)
360+ else if ((1 >= toInt((y_prev - y))))
361+ then $Tuple2(y, true)
362+ else $Tuple2(y, false)
363+ }
364+
365+ let $t079338050 = {
366+ let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
367+ let $s = size($l)
368+ let $acc0 = $Tuple2(toBigInt(D), false)
369+ func $f1_1 ($a,$i) = if (($i >= $s))
370+ then $a
371+ else y_proc($a, $l[$i])
372+
373+ func $f1_2 ($a,$i) = if (($i >= $s))
374+ then $a
375+ else throw("List size exceeds 16")
376+
377+ $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)
378+ }
379+ let y = $t079338050._1
380+ let finished = $t079338050._2
381+ if ((finished == false))
382+ then throw(("getY() not finished with " + toString(y)))
383+ else toInt(y)
384+ }
385+
386+
387+func get_y_D (A_,in,xp,D) = if (assert((in >= 0)))
388+ then throw("i below zero")
389+ else if (assert((nCoins > in)))
390+ then throw("i above N_COINS")
391+ else {
392+ let Ann = (A_ * nCoins)
393+ func S_c (acc,i) = {
394+ let $t084298446 = acc
395+ let S_ = $t084298446._1
396+ let c = $t084298446._2
397+ let x_ = if (if ((in != i))
398+ then (nCoins > i)
399+ else false)
400+ then xp[i]
401+ else 0
402+ if (if ((nCoins > i))
403+ then (in != i)
404+ else false)
405+ then $Tuple2((S_ + x_), fraction(c, toBigInt(D), toBigInt((x_ * nCoins))))
406+ else $Tuple2(S_, c)
407+ }
408+
409+ let $t086668767 = {
410+ let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
411+ let $s = size($l)
412+ let $acc0 = $Tuple2(0, toBigInt(D))
413+ func $f0_1 ($a,$i) = if (($i >= $s))
414+ then $a
415+ else S_c($a, $l[$i])
416+
417+ func $f0_2 ($a,$i) = if (($i >= $s))
418+ then $a
419+ else throw("List size exceeds 15")
420+
421+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15)
422+ }
423+ let S_ = $t086668767._1
424+ let c_ = $t086668767._2
425+ let c = fraction(c_, toBigInt(D), toBigInt((Ann * nCoins)))
426+ let bD = toBigInt(((S_ + (D / Ann)) - D))
427+ func y_D_proc (acc,i) = if ((acc._2 == true))
428+ then acc
429+ else {
430+ let y_prev = acc._1
431+ let y = (((y_prev * y_prev) + c) / ((big2 * y_prev) + bD))
432+ if ((y > y_prev))
433+ then if ((1 >= toInt((y - y_prev))))
434+ then $Tuple2(y, true)
435+ else $Tuple2(y, false)
436+ else if ((1 >= toInt((y_prev - y))))
437+ then $Tuple2(y, true)
438+ else $Tuple2(y, false)
439+ }
440+
441+ let $t092509369 = {
442+ let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
443+ let $s = size($l)
444+ let $acc0 = $Tuple2(toBigInt(D), false)
445+ func $f1_1 ($a,$i) = if (($i >= $s))
446+ then $a
447+ else y_D_proc($a, $l[$i])
448+
449+ func $f1_2 ($a,$i) = if (($i >= $s))
450+ then $a
451+ else throw("List size exceeds 16")
452+
453+ $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)
454+ }
455+ let y = $t092509369._1
456+ let finished = $t092509369._2
457+ if ((finished == false))
458+ then throw(("get_y_D() not finished with " + toString(y)))
459+ else toInt(y)
460+ }
461+
462+
463+func _calcWithdrawOneCoin (xp,_token_amount,i,caller) = {
464+ let feeDiscount = calculateFeeDiscount(caller)
465+ let amp = _A()
466+ let _fee = ((fraction(fee, feeDiscount, feeScale6, CEILING) * nCoins) / (4 * (nCoins - 1)))
467+ let total_supply = shareSupply
468+ let D0 = get_D(xp, amp)
469+ let D1 = (D0 - fraction(_token_amount, D0, total_supply))
470+ let new_y = get_y_D(amp, i, xp, D1)
471+ let dy_0 = (xp[i] - new_y)
472+ func xp_reduced_proc (acc,xp_j) = {
473+ let $t01001010039 = acc
474+ let xp_reduced = $t01001010039._1
475+ let index = $t01001010039._2
476+ let dx_expected = if ((index == i))
477+ then (fraction(xp_j, D1, D0) - new_y)
478+ else (xp_j - fraction(xp_j, D1, D0))
479+ $Tuple2((xp_reduced :+ (xp_j - fraction(_fee, dx_expected, feeScale6))), (index + 1))
480+ }
481+
482+ let $t01030110365 = {
483+ let $l = xp
484+ let $s = size($l)
485+ let $acc0 = $Tuple2(nil, 0)
486+ func $f0_1 ($a,$i) = if (($i >= $s))
487+ then $a
488+ else xp_reduced_proc($a, $l[$i])
489+
490+ func $f0_2 ($a,$i) = if (($i >= $s))
491+ then $a
492+ else throw("List size exceeds 15")
493+
494+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15)
495+ }
496+ let xp_reduced = $t01030110365._1
497+ let index = $t01030110365._2
498+ let xp_reduced_i = xp_reduced[i]
499+ let dy = ((xp_reduced_i - get_y_D(amp, i, xp_reduced, D1)) - 1)
500+ $Tuple2(dy, (dy_0 - dy))
501+ }
502+
503+
504+func getStrAssetId (assetId) = match assetId {
505+ case id: ByteVector =>
506+ toBase58String(id)
507+ case waves: Unit =>
508+ "WAVES"
509+ case _ =>
510+ throw("Match error")
511+}
512+
513+
514+func calcStakingFuncAndAddres (stake,assetId) = if (stake)
515+ then $Tuple2("lockNeutrino", stakingUSDNAddress)
516+ else $Tuple2("unlockNeutrino", stakingUSDNAddress)
517+
518+
519+func calcStakingParams (stake,amount,assetId) = if (stake)
520+ then {
521+ let $t01092910995 = calcStakingFuncAndAddres(stake, assetId)
522+ let call = $t01092910995._1
523+ let stakingAddr = $t01092910995._2
524+ $Tuple4(call, stakingAddr, nil, [AttachedPayment(assetId, amount)])
525+ }
526+ else {
527+ let $t01108111147 = calcStakingFuncAndAddres(stake, assetId)
528+ let call = $t01108111147._1
529+ let stakingAddr = $t01108111147._2
530+ $Tuple4(call, stakingAddr, [amount, toBase58String(assetId)], nil)
531+ }
532+
533+
534+func stake (amount,assetIdString) = if (containsElement(stakingAssets, assetIdString))
535+ then {
536+ let $t01133411436 = calcStakingParams(true, amount, fromBase58String(assetIdString))
537+ let call = $t01133411436._1
538+ let addr = $t01133411436._2
539+ let params = $t01133411436._3
540+ let payments = $t01133411436._4
541+ invoke(addr, call, params, payments)
542+ }
543+ else 0
544+
545+
546+func unstake (amount,assetIdString) = if (containsElement(stakingAssets, assetIdString))
547+ then {
548+ let $t01162111724 = calcStakingParams(false, amount, fromBase58String(assetIdString))
549+ let call = $t01162111724._1
550+ let addr = $t01162111724._2
551+ let params = $t01162111724._3
552+ let payments = $t01162111724._4
553+ invoke(addr, call, params, payments)
554+ }
555+ else 0
556+
557+
558+func stakedAmount (assetId) = {
559+ let stakedAmountCalculated = match assetId {
560+ case aId: ByteVector =>
561+ if ((aId == USDN))
562+ then getInteger(stakingUSDNAddress, ((("rpd_balance_" + toBase58String(aId)) + "_") + toString(this)))
563+ else 0
564+ case _: Unit =>
565+ 0
566+ case _ =>
567+ throw("Match error")
568+ }
569+ match stakedAmountCalculated {
570+ case i: Int =>
571+ i
572+ case _ =>
573+ 0
574+ }
575+ }
576+
577+
578+func checkSuspicious () = {
579+ let contractBalances = _xp()
580+ func checkBalance (acc,assetId) = {
581+ let $t01233512360 = acc
582+ let suspicious = $t01233512360._1
583+ let i = $t01233512360._2
584+ if (suspicious)
585+ then $Tuple2(suspicious, i)
586+ else {
587+ let aBalance = (assetBalance(this, fromBase58String(assetId)) + stakedAmount(fromBase58String(assetId)))
588+ if ((contractBalances[i] > aBalance))
589+ then $Tuple2(true, i)
590+ else $Tuple2(false, (i + 1))
591+ }
592+ }
593+
594+ let $l = assetIds
595+ let $s = size($l)
596+ let $acc0 = $Tuple2(false, 0)
597+ func $f0_1 ($a,$i) = if (($i >= $s))
598+ then $a
599+ else checkBalance($a, $l[$i])
600+
601+ func $f0_2 ($a,$i) = if (($i >= $s))
602+ then $a
603+ else throw("List size exceeds 15")
604+
605+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15)
606+ }
607+
608+
609+func suspendSuspicious (i) = suspend(("Suspicious state with asset: " + assetIds[i]))
610+
611+
612+func returnPayments (caller,payments) = {
613+ func parsePayments (acc,payment) = (acc :+ ScriptTransfer(caller, payment.amount, payment.assetId))
614+
615+ let $l = payments
616+ let $s = size($l)
617+ let $acc0 = nil
618+ func $f0_1 ($a,$i) = if (($i >= $s))
619+ then $a
620+ else parsePayments($a, $l[$i])
621+
622+ func $f0_2 ($a,$i) = if (($i >= $s))
623+ then $a
624+ else throw("List size exceeds 15")
625+
626+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15)
627+ }
628+
629+
630+@Callable(msg)
631+func D (xp,amp) = {
632+ let D = get_D_internal(xp, amp)
633+ $Tuple2([IntegerEntry("D", D)], D)
634+ }
635+
636+
637+
638+@Callable(msg)
639+func init (coins,_A,firstHarvest) = if (!(isDataStorageUntouched(this)))
640+ then throw("Already initialized")
641+ else {
642+ let shareName = "s_Multi_USD"
643+ let shareDescription = ("ShareToken of SwopFi protocol for MultiStable USD pool at address " + toString(this))
644+ let issueToken = Issue(shareName, shareDescription, 0, 6, true)
645+ let tokenId = calculateAssetId(issueToken)
646+ let baseEntry = [StringEntry(kAssets, coins), IntegerEntry("initial_A", _A), IntegerEntry("future_A", _A), IntegerEntry(kFee, getIntegerValue(oracle, "base_fee_flat")), StringEntry(kShareAssetId, toBase58String(tokenId)), IntegerEntry(kShareAssetSupply, 0), BooleanEntry(kActive, true), issueToken]
647+ if (firstHarvest)
648+ then (baseEntry ++ [BooleanEntry(kFirstHarvest, firstHarvest), IntegerEntry(kFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))])
649+ else baseEntry
650+ }
651+
652+
653+
654+@Callable(msg)
655+func addLiquidity (minMintAmount,stakeFarming) = valueOrElse(isActive(), {
656+ let amp = _A()
657+ let xp = _xp()
658+ let D0 = if ((shareSupply == 0))
659+ then 0
660+ else getDMem(xp, amp)
661+ let payments = msg.payments
662+ let n = size(payments)
663+ func validPayments (n) = if ((n > nCoins))
664+ then throw(("payments size > " + toString(nCoins)))
665+ else if ((1 > n))
666+ then throw("payments size < 1")
667+ else if (if ((shareSupply == 0))
668+ then (nCoins != n)
669+ else false)
670+ then throw("initial deposit requires all coins")
671+ else {
672+ func paymantValid (acc,payment) = if (containsElement(assetIds, getStrAssetId(payment.assetId)))
673+ then true
674+ else throw("Invalid asset in payment")
675+
676+ let $l = payments
677+ let $s = size($l)
678+ let $acc0 = false
679+ func $f0_1 ($a,$i) = if (($i >= $s))
680+ then $a
681+ else paymantValid($a, $l[$i])
682+
683+ func $f0_2 ($a,$i) = if (($i >= $s))
684+ then $a
685+ else throw("List size exceeds 15")
686+
687+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15)
688+ }
689+
690+ if (!(validPayments(n)))
691+ then throw()
692+ else {
693+ let suspicious = checkSuspicious()
694+ if (suspicious._1)
695+ then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.caller, payments))
696+ else {
697+ let paymentsSize = size(payments)
698+ func parsePayments (acc,assetId) = {
699+ let $t01539715426 = acc
700+ let newBalances = $t01539715426._1
701+ let i = $t01539715426._2
702+ let j = $t01539715426._3
703+ if (if ((paymentsSize > j))
704+ then (getStrAssetId(payments[j].assetId) == assetId)
705+ else false)
706+ then {
707+ let s = stake(payments[j].amount, getStrAssetId(payments[j].assetId))
708+ if ((s == s))
709+ then $Tuple3((newBalances :+ (xp[i] + payments[j].amount)), (i + 1), (j + 1))
710+ else throw("Strict value is not equal to itself.")
711+ }
712+ else $Tuple3((newBalances :+ xp[i]), (i + 1), j)
713+ }
714+
715+ let $t01573215818 = {
716+ let $l = assetIds
717+ let $s = size($l)
718+ let $acc0 = $Tuple3(nil, 0, 0)
719+ func $f0_1 ($a,$i) = if (($i >= $s))
720+ then $a
721+ else parsePayments($a, $l[$i])
722+
723+ func $f0_2 ($a,$i) = if (($i >= $s))
724+ then $a
725+ else throw("List size exceeds 15")
726+
727+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15)
728+ }
729+ let newBalances = $t01573215818._1
730+ let k = $t01573215818._2
731+ let parsedPayments = $t01573215818._3
732+ if (((paymentsSize - 1) > parsedPayments))
733+ then throw("Incorect payments order")
734+ else {
735+ let D1 = getDMem(newBalances, amp)
736+ if (assert((D1 > D0)))
737+ then throw("D1 > D0")
738+ else {
739+ let feeDiscount = calculateFeeDiscount(msg.caller)
740+ func calcScriptActions (acc,newBalance) = {
741+ let $t01616516206 = acc
742+ let invBalances = $t01616516206._1
743+ let scriptActions = $t01616516206._2
744+ let i = $t01616516206._3
745+ if ((shareSupply > 0))
746+ then {
747+ let _fee = ((fraction(fee, feeDiscount, feeScale6, CEILING) * nCoins) / (4 * (nCoins - 1)))
748+ let fees = {
749+ let idealBalance = fraction(D1, xp[i], D0)
750+ let difference = if ((idealBalance > newBalance))
751+ then (idealBalance - newBalance)
752+ else (newBalance - idealBalance)
753+ fraction(_fee, difference, feeScale6)
754+ }
755+ let governanceFees = fraction(fees, feeGovernance, feeScale6)
756+ let finalBalance = (newBalance - governanceFees)
757+ let invariantBalance = (newBalance - fees)
758+ let us = unstake(fees, assetIds[i])
759+ if ((us == us))
760+ then $Tuple3((invBalances :+ invariantBalance), (scriptActions ++ [ScriptTransfer(capMoneyBoxAddress, (fees - governanceFees), fromBase58String(assetIds[i])), ScriptTransfer(moneyBoxAddress, governanceFees, fromBase58String(assetIds[i])), IntegerEntry((assetIds[i] + kAssetBalance), finalBalance)]), (i + 1))
761+ else throw("Strict value is not equal to itself.")
762+ }
763+ else $Tuple3((invBalances :+ newBalance), (scriptActions :+ IntegerEntry((assetIds[i] + kAssetBalance), newBalance)), (i + 1))
764+ }
765+
766+ let $t01754317631 = {
767+ let $l = newBalances
768+ let $s = size($l)
769+ let $acc0 = $Tuple3(nil, nil, 0)
770+ func $f1_1 ($a,$i) = if (($i >= $s))
771+ then $a
772+ else calcScriptActions($a, $l[$i])
773+
774+ func $f1_2 ($a,$i) = if (($i >= $s))
775+ then $a
776+ else throw("List size exceeds 15")
777+
778+ $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)
779+ }
780+ let invBalances = $t01754317631._1
781+ let scriptActions = $t01754317631._2
782+ let D2 = getDMem(invBalances, amp)
783+ let mint_amount = if ((shareSupply == 0))
784+ then D1
785+ else fraction(shareSupply, (D2 - D0), D0)
786+ if (assert((mint_amount >= minMintAmount)))
787+ then throw("Slippage screwed you")
788+ else if (stakeFarming)
789+ then {
790+ let re = Reissue(shareAssetId, mint_amount, true)
791+ if ((re == re))
792+ then {
793+ let s = invoke(farmingAddress, "lockShareTokens", [toString(msg.caller)], [AttachedPayment(shareAssetId, mint_amount)])
794+ if ((s == s))
795+ then scriptActions
796+ else throw("Strict value is not equal to itself.")
797+ }
798+ else throw("Strict value is not equal to itself.")
799+ }
800+ else (scriptActions ++ [Reissue(shareAssetId, mint_amount, true), ScriptTransfer(msg.caller, mint_amount, shareAssetId), IntegerEntry(kShareAssetSupply, (shareSupply + mint_amount))])
801+ }
802+ }
803+ }
804+ }
805+ })
806+
807+
808+
809+@Callable(msg)
810+func getDy (assetFrom,assetTo,dx,userAddress) = {
811+ let xp = _xp()
812+ let fromIndex = valueOrErrorMessage(indexOf(assetIds, assetFrom), "unknown token in")
813+ let toIndex = valueOrErrorMessage(indexOf(assetIds, assetTo), "unknown token out")
814+ let x = (xp[fromIndex] + dx)
815+ let y = getY(fromIndex, toIndex, x, xp)
816+ let dy = ((xp[toIndex] - y) - 1)
817+ let feeDiscount = calculateFeeDiscount(Address(fromBase58String(userAddress)))
818+ let _fee = fraction(fraction(fee, feeDiscount, feeScale6, CEILING), dy, feeScale6)
819+ $Tuple2(nil, (dy - _fee))
820+ }
821+
822+
823+
824+@Callable(msg)
825+func exchange (tokenOut,min_dy) = valueOrElse(isActive(), if ((size(msg.payments) != 1))
826+ then throw("size(payments) != 1")
827+ else {
828+ let suspicious = checkSuspicious()
829+ if (suspicious._1)
830+ then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.caller, msg.payments))
831+ else {
832+ let payment = msg.payments[0]
833+ let tokenIn = getStrAssetId(payment.assetId)
834+ let tokenOutB58 = fromBase58String(tokenOut)
835+ let dx = payment.amount
836+ let fromIndex = valueOrErrorMessage(indexOf(assetIds, tokenIn), "unknown token in")
837+ let toIndex = valueOrErrorMessage(indexOf(assetIds, tokenOut), "unknown token out")
838+ let xp = _xp()
839+ let x = (xp[fromIndex] + dx)
840+ let y = getY(fromIndex, toIndex, x, xp)
841+ let _dy = ((xp[toIndex] - y) - 1)
842+ let feeDiscount = calculateFeeDiscount(msg.caller)
843+ let _fee = fraction(_dy, fraction(fee, feeDiscount, feeScale6, CEILING), feeScale6)
844+ let dy = (_dy - _fee)
845+ if (assert((dy >= min_dy)))
846+ then throw("Exchange resulted in fewer coins than expected")
847+ else {
848+ let governanceFees = fraction(_fee, feeGovernance, feeScale6)
849+ let s = stake(payment.amount, getStrAssetId(payment.assetId))
850+ if ((s == s))
851+ then {
852+ let us = unstake((dy + _fee), tokenOut)
853+ if ((us == us))
854+ then $Tuple2([IntegerEntry((tokenIn + kAssetBalance), x), IntegerEntry((tokenOut + kAssetBalance), ((xp[toIndex] - dy) - governanceFees)), ScriptTransfer(msg.caller, dy, tokenOutB58), ScriptTransfer(moneyBoxAddress, governanceFees, tokenOutB58), ScriptTransfer(moneyBoxAddress, (_fee - governanceFees), tokenOutB58)], $Tuple2(dy, tokenOutB58))
855+ else throw("Strict value is not equal to itself.")
856+ }
857+ else throw("Strict value is not equal to itself.")
858+ }
859+ }
860+ })
861+
862+
863+
864+@Callable(msg)
865+func withdraw (minAmounts,unlockAmount) = valueOrElse(isActive(), if ((size(msg.payments) != 1))
866+ then throw("size(payments) != 1")
867+ else {
868+ let suspicious = checkSuspicious()
869+ if (suspicious._1)
870+ then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.caller, msg.payments))
871+ else {
872+ let payment = msg.payments[0]
873+ let tokenIn = payment.assetId
874+ if ((tokenIn != shareAssetId))
875+ then throw("unknown token")
876+ else {
877+ let _amount = payment.amount
878+ let total_supply = shareSupply
879+ let unlock = if ((unlockAmount > 0))
880+ then invoke(farmingAddress, "withdrawShareTokens", [toString(msg.caller), unlockAmount], nil)
881+ else 0
882+ if ((unlock == unlock))
883+ then {
884+ let withdrawAmount = (_amount + unlockAmount)
885+ func calcScriptActions (acc,balance) = {
886+ let $t02141521443 = acc
887+ let scriptActions = $t02141521443._1
888+ let i = $t02141521443._2
889+ let wAmount = fraction(balance, withdrawAmount, total_supply)
890+ if (assert((wAmount >= minAmounts[i])))
891+ then throw("Withdrawal resulted in fewer coins than expected")
892+ else {
893+ let us = unstake(wAmount, assetIds[i])
894+ if ((us == us))
895+ then $Tuple2((scriptActions ++ [IntegerEntry((assetIds[i] + kAssetBalance), (balance - wAmount)), ScriptTransfer(msg.caller, wAmount, fromBase58String(assetIds[i]))]), (i + 1))
896+ else throw("Strict value is not equal to itself.")
897+ }
898+ }
899+
900+ let $t02193322001 = {
901+ let $l = _xp()
902+ let $s = size($l)
903+ let $acc0 = $Tuple2(nil, 0)
904+ func $f0_1 ($a,$i) = if (($i >= $s))
905+ then $a
906+ else calcScriptActions($a, $l[$i])
907+
908+ func $f0_2 ($a,$i) = if (($i >= $s))
909+ then $a
910+ else throw("List size exceeds 15")
911+
912+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15)
913+ }
914+ let scriptActions = $t02193322001._1
915+ let i = $t02193322001._2
916+ (scriptActions ++ [Burn(shareAssetId, withdrawAmount), IntegerEntry(kShareAssetSupply, (shareSupply - withdrawAmount))])
917+ }
918+ else throw("Strict value is not equal to itself.")
919+ }
920+ }
921+ })
922+
923+
924+
925+@Callable(msg)
926+func calcWithdrawOneCoin (_tokenAmount,i) = $Tuple2(nil, _calcWithdrawOneCoin(_xp(), _tokenAmount, i, msg.caller)._1)
927+
928+
929+
930+@Callable(msg)
931+func withdrawOneCoin (tokenOut,minAmount,unlockAmount) = valueOrElse(isActive(), if ((size(msg.payments) != 1))
932+ then throw("size(payments) != 1")
933+ else {
934+ let suspicious = checkSuspicious()
935+ if (suspicious._1)
936+ then (suspendSuspicious(suspicious._2) ++ returnPayments(msg.caller, msg.payments))
937+ else {
938+ let payment = msg.payments[0]
939+ let tokenIn = payment.assetId
940+ if ((tokenIn != shareAssetId))
941+ then throw("unknown token")
942+ else {
943+ let i = valueOrErrorMessage(indexOf(assetIds, tokenOut), "unknown token out")
944+ let _tokenAmount = payment.amount
945+ let unlock = if ((unlockAmount > 0))
946+ then invoke(farmingAddress, "withdrawShareTokens", [toString(msg.caller), unlockAmount], nil)
947+ else 0
948+ if ((unlock == unlock))
949+ then {
950+ let withdrawAmount = (_tokenAmount + unlockAmount)
951+ let xp = _xp()
952+ let $t02310823182 = _calcWithdrawOneCoin(xp, withdrawAmount, i, msg.caller)
953+ let dy = $t02310823182._1
954+ let dy_fee = $t02310823182._2
955+ if (assert((dy >= minAmount)))
956+ then throw("Not enough coins removed")
957+ else {
958+ let governanceFees = fraction(dy_fee, feeGovernance, feeScale6)
959+ let dy_and_fee = (dy + dy_fee)
960+ let us = unstake(dy_and_fee, tokenOut)
961+ if ((us == us))
962+ then [ScriptTransfer(msg.caller, dy, fromBase58String(tokenOut)), IntegerEntry((assetIds[i] + kAssetBalance), (xp[i] - dy_and_fee)), Burn(shareAssetId, withdrawAmount), ScriptTransfer(moneyBoxAddress, governanceFees, fromBase58String(tokenOut)), ScriptTransfer(capMoneyBoxAddress, (dy_fee - governanceFees), fromBase58String(tokenOut)), IntegerEntry(kShareAssetSupply, (shareSupply - withdrawAmount))]
963+ else throw("Strict value is not equal to itself.")
964+ }
965+ }
966+ else throw("Strict value is not equal to itself.")
967+ }
968+ }
969+ })
970+
971+
972+
973+@Callable(msg)
974+func A () = $Tuple2(nil, _A())
975+
976+
977+
978+@Callable(msg)
979+func getVirtualPrice () = {
980+ let D = get_D(_xp(), _A())
981+ $Tuple2(nil, fraction(D, PRECISION, shareSupply))
982+ }
983+
984+
985+
986+@Callable(msg)
987+func calcTokenAmount (amounts,deposit) = {
988+ let amp = _A()
989+ let balances = _xp()
990+ let D0 = getDMem(balances, amp)
991+ func calcNewBalances (acc,balance) = {
992+ let $t02426124287 = acc
993+ let newBalances = $t02426124287._1
994+ let i = $t02426124287._2
995+ let newBalance = (balance + (if (deposit)
996+ then amounts[i]
997+ else -(amounts[i])))
998+ $Tuple2((newBalances :+ newBalance), (i + 1))
999+ }
1000+
1001+ let newBalances = ( let $l = balances
1002+ let $s = size($l)
1003+ let $acc0 = $Tuple2(nil, 0)
1004+ func $f0_1 ($a,$i) = if (($i >= $s))
1005+ then $a
1006+ else calcNewBalances($a, $l[$i])
1007+
1008+ func $f0_2 ($a,$i) = if (($i >= $s))
1009+ then $a
1010+ else throw("List size exceeds 15")
1011+
1012+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15))._1
1013+ let D1 = getDMem(newBalances, amp)
1014+ let diff = if (deposit)
1015+ then (D1 - D0)
1016+ else (D0 - D1)
1017+ $Tuple2(nil, fraction(diff, shareSupply, D0))
1018+ }
1019+
1020+
1021+
1022+@Callable(msg)
1023+func rampA (_futureA,_futureTime) = valueOrElse(isActive(), valueOrElse(isAdminCall(msg), if (assert((blockTimestamp >= (initial_A_time + MIN_RAMP_TIME))))
1024+ then throw("too often")
1025+ else if (assert((_futureTime >= (blockTimestamp + MIN_RAMP_TIME))))
1026+ then throw("insufficient time")
1027+ else {
1028+ let _initial_A = _A()
1029+ if (assert(if ((_futureA > 0))
1030+ then (MAX_A > _futureA)
1031+ else false))
1032+ then throw("out of base range")
1033+ else if (assert(if (if ((_futureA >= _initial_A))
1034+ then ((_initial_A * MAX_A_CHANGE) >= _futureA)
1035+ else false)
1036+ then true
1037+ else if ((_initial_A > _futureA))
1038+ then ((_futureA * MAX_A_CHANGE) >= _initial_A)
1039+ else false))
1040+ then throw("out of range")
1041+ else [IntegerEntry("initial_A", _initial_A), IntegerEntry("future_A", _futureA), IntegerEntry("initial_A_time", blockTimestamp), IntegerEntry("future_A_time", _futureTime)]
1042+ }))
1043+
1044+
1045+
1046+@Callable(msg)
1047+func stopRampA () = valueOrElse(isActive(), valueOrElse(isAdminCall(msg), {
1048+ let currentA = _A()
1049+[IntegerEntry("initial_A", currentA), IntegerEntry("future_A", currentA), IntegerEntry("initial_A_time", blockTimestamp), IntegerEntry("future_A_time", blockTimestamp)]
1050+ }))
1051+
1052+
1053+
1054+@Callable(msg)
1055+func shutdown () = valueOrElse(isAdminCall(msg), if (!(active))
1056+ then throw(("DApp is already suspended. Cause: " + valueOrElse(getString(this, kCause), "the cause wasn't specified")))
1057+ else suspend("Paused by admin"))
1058+
1059+
1060+
1061+@Callable(msg)
1062+func activate () = valueOrElse(isAdminCall(msg), if (active)
1063+ then throwIsActive()
1064+ else [BooleanEntry(kActive, true), DeleteEntry(kCause)])
1065+
1066+
1067+
1068+@Callable(msg)
1069+func keepLimitForFirstHarvest (shareLimit) = valueOrElse(isActive(), valueOrElse(isAdminCall(msg), [IntegerEntry(kShareLimit, shareLimit)]))
1070+
1071+
1072+@Verifier(tx)
1073+func verify () = {
1074+ let multiSignedByAdmins = {
1075+ let adminPubKey1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
1076+ then 1
1077+ else 0
1078+ let adminPubKey2Signed = if (sigVerify(tx.bodyBytes, tx.proofs[1], adminPubKey2))
1079+ then 1
1080+ else 0
1081+ let adminPubKey3Signed = if (sigVerify(tx.bodyBytes, tx.proofs[2], adminPubKey3))
1082+ then 1
1083+ else 0
1084+ (((adminPubKey1Signed + adminPubKey2Signed) + adminPubKey3Signed) >= 2)
1085+ }
1086+ match tx {
1087+ case inv: InvokeScriptTransaction =>
1088+ let callTakeIntoAccount = if ((inv.dApp == this))
1089+ then (inv.function == "takeIntoAccountExtraFunds")
1090+ else false
1091+ let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
1092+ then true
1093+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey2))
1094+ then true
1095+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey3))
1096+ then true
1097+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKeyInvoke)
1098+ if (if (callTakeIntoAccount)
1099+ then signedByAdmin
1100+ else false)
1101+ then true
1102+ else multiSignedByAdmins
1103+ case _ =>
1104+ multiSignedByAdmins
1105+ }
1106+ }
1107+

github/deemru/w8io/026f985 
70.91 ms