tx · FQCe87NV6PPjKfFyBWiGQeHMgtrfce1jK6UmqengBY8j

3NCJATKcGvC9HbmBJTbeyfcPMfPTYgtyRrk:  -0.03100000 Waves

2022.08.31 16:46 [2208719] smart account 3NCJATKcGvC9HbmBJTbeyfcPMfPTYgtyRrk > SELF 0.00000000 Waves

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

github/deemru/w8io/026f985 
68.57 ms