tx · 71EJdf6XKkdoexZSfhjqDjJMf5ZU2x6dtnc1keKdfeiY

3MsYwsDYqRPeSzKDytib2snwr8eMQYLqP7F:  -0.01000000 Waves

2023.09.27 16:16 [2773866] smart account 3MsYwsDYqRPeSzKDytib2snwr8eMQYLqP7F > SELF 0.00000000 Waves

{ "type": 13, "id": "71EJdf6XKkdoexZSfhjqDjJMf5ZU2x6dtnc1keKdfeiY", "fee": 1000000, "feeAssetId": null, "timestamp": 1695820657433, "version": 2, "chainId": 84, "sender": "3MsYwsDYqRPeSzKDytib2snwr8eMQYLqP7F", "senderPublicKey": "9WNcTCGFvr3s3tbM7g3vcsCdR8eXiu7d4kLJrMYusqx1", "proofs": [ "4uv3rLtqHvfRxYFHZH5E6gEb2uTm2y8RB49xV8CmHLFbEhB5q87PsEv74yauy5nEjpA38zFk8e3YokhcvFA3sx8f" ], "script": "base64:BgIYCAISBwoFCAgBCAgSABIDCgEBEgASABIADgAGTVVMVDEwAIDIr6AlAANTRVACAl9fABBpc0NvbnN0cnVjdGVkS2V5Ag5pc19jb25zdHJ1Y3RlZAAXd2l0aGRyYXdhbExvY2tQZXJpb2RLZXkCFndpdGhkcmF3YWxfbG9ja19wZXJpb2QAEHJld2FyZEFzc2V0SWRLZXkCD3Jld2FyZF9hc3NldF9pZAATcG9vbFN0YWtlQXNzZXRJZEtleQITcG9vbF9zdGFrZV9hc3NldF9pZAAWcm9vdENvbnRyYWN0QWRkcmVzc0tleQIVcm9vdF9jb250cmFjdF9hZGRyZXNzAA9hZG1pbkFkZHJlc3NLZXkCEWFkbWluX2FkZHJlc3Nfa2V5ABJ0b3RhbFBvb2xTdGFrZWRLZXkCEnRvdGFsX3Bvb2xfX3N0YWtlZAASdG90YWxQb29sRWFybmVkS2V5AhF0b3RhbF9wb29sX2Vhcm5lZAAVcG9vbEN1cnJlbnRDbGFpbUlkS2V5AhVwb29sX2N1cnJlbnRfY2xhaW1faWQAKHBvb2xDdXJyZW50VW5jbGFpbWVkQWRkaXRpb25hbFJld2FyZHNLZXkCKXBvb2xfY3VycmVudF91bmNsYWltZWRfYWRkaXRpb25hbF9yZXdhcmRzAQlhc1BheW1lbnQBAXYEByRtYXRjaDAFAXYDCQABAgUHJG1hdGNoMAIPQXR0YWNoZWRQYXltZW50BAFwBQckbWF0Y2gwBQFwCQACAQIhZmFpbCB0byBjYXN0IGludG8gQXR0YWNoZWRQYXltZW50ARppc1VzZXJIYXZlVW5jbGFpbWVkUmV3YXJkcwEHYWRkcmVzcwMJAQEhAQkBCWlzRGVmaW5lZAEJAKIIAQUHYWRkcmVzcwcEEmN1cnJlbnRQb29sQ2xhaW1JZAkBEUBleHRyTmF0aXZlKDEwNTUpAQUVcG9vbEN1cnJlbnRDbGFpbUlkS2V5BAh1c2VyRGF0YQkAtQkCCQERQGV4dHJOYXRpdmUoMTA1OCkBBQdhZGRyZXNzBQNTRVAEI3VzZXJMYXN0Q2xhaW1lZFJld2FyZHNBdFBvb2xDbGFpbUlkCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIdXNlckRhdGEAAgkAZgIFEmN1cnJlbnRQb29sQ2xhaW1JZAUjdXNlckxhc3RDbGFpbWVkUmV3YXJkc0F0UG9vbENsYWltSWQGAWkBC2NvbnN0cnVjdG9yBQ1yZXdhcmRBc3NldElkEHBvb2xTdGFrZUFzc2V0SWQUd2l0aGRyYXdhbExvY2tQZXJpb2QMcm9vdENvbnRyYWN0DWFkbWluQ29udHJhY3QDCQEJaXNEZWZpbmVkAQkAoAgBBRBpc0NvbnN0cnVjdGVkS2V5CQACAQIiQ29uc3RydWN0b3IgY2FuIGJlIGNhbGxlZCBvbmUgdGltZQkAzAgCCQEMQm9vbGVhbkVudHJ5AgUQaXNDb25zdHJ1Y3RlZEtleQYJAMwIAgkBDEludGVnZXJFbnRyeQIFKHBvb2xDdXJyZW50VW5jbGFpbWVkQWRkaXRpb25hbFJld2FyZHNLZXkAAAkAzAgCCQELU3RyaW5nRW50cnkCBRByZXdhcmRBc3NldElkS2V5BQ1yZXdhcmRBc3NldElkCQDMCAIJAQtTdHJpbmdFbnRyeQIFE3Bvb2xTdGFrZUFzc2V0SWRLZXkFEHBvb2xTdGFrZUFzc2V0SWQJAMwIAgkBC1N0cmluZ0VudHJ5AgUWcm9vdENvbnRyYWN0QWRkcmVzc0tleQUMcm9vdENvbnRyYWN0CQDMCAIJAQtTdHJpbmdFbnRyeQIFD2FkbWluQWRkcmVzc0tleQUNYWRtaW5Db250cmFjdAkAzAgCCQEMSW50ZWdlckVudHJ5AgUSdG90YWxQb29sRWFybmVkS2V5AAAJAMwIAgkBDEludGVnZXJFbnRyeQIFFXBvb2xDdXJyZW50Q2xhaW1JZEtleQAACQDMCAIJAQxJbnRlZ2VyRW50cnkCBRJ0b3RhbFBvb2xTdGFrZWRLZXkAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgUXd2l0aGRyYXdhbExvY2tQZXJpb2RLZXkFFHdpdGhkcmF3YWxMb2NrUGVyaW9kBQNuaWwBaQEFc3Rha2UAAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIUT25lIFBheW1lbnQgZXhwZWN0ZWQEDWNhbGxlckFkZHJlc3MJANgEAQgIBQFpBmNhbGxlcgVieXRlcwQHcGF5bWVudAkBCWFzUGF5bWVudAEJAJEDAggFAWkIcGF5bWVudHMAAAQQcG9vbFN0YWtlQXNzZXRJZAkA2QQBCQERQGV4dHJOYXRpdmUoMTA1OCkBBRNwb29sU3Rha2VBc3NldElkS2V5AwMJAQIhPQIIBQdwYXltZW50B2Fzc2V0SWQFEHBvb2xTdGFrZUFzc2V0SWQGCQBnAgAACAUHcGF5bWVudAZhbW91bnQJAAIBAiFXcm9uZyBhc3NldCBpZCBvciBuZWdhdGl2ZSBhbW91bnQDCQEaaXNVc2VySGF2ZVVuY2xhaW1lZFJld2FyZHMBBQ1jYWxsZXJBZGRyZXNzCQACAQI4WW91IGhhdmUgdW5jbGFpbWVkIHJld2FyZHMgb24gY29udHJhY3QsIGNsYWltIHRoZW0gZmlyc3QEEmN1cnJlbnRQb29sQ2xhaW1JZAkBEUBleHRyTmF0aXZlKDEwNTUpAQUVcG9vbEN1cnJlbnRDbGFpbUlkS2V5BBZjdXJyZW50VG90YWxQb29sU3Rha2VkCQERQGV4dHJOYXRpdmUoMTA1NSkBBRJ0b3RhbFBvb2xTdGFrZWRLZXkELWN1cnJlbnRUb3RhbFBvb2xSZXdhcmRzRWFybmVkRm9yT25lU3Rha2VUb2tlbgkBEUBleHRyTmF0aXZlKDEwNTUpAQUSdG90YWxQb29sRWFybmVkS2V5BBNyb290Q29udHJhY3RBZGRyZXNzCQERQGV4dHJOYXRpdmUoMTA1OCkBBRZyb290Q29udHJhY3RBZGRyZXNzS2V5BAZyZXN1bHQDCQBmAgkAsQIBBRNyb290Q29udHJhY3RBZGRyZXNzAAAJAPwHBAkBB0FkZHJlc3MBCQDZBAEFE3Jvb3RDb250cmFjdEFkZHJlc3MCDHN0YWtlUG9vbExwcwUDbmlsCQDMCAIFB3BheW1lbnQFA25pbAUEdW5pdAMJAAACBQZyZXN1bHQFBnJlc3VsdAQLdXNlckRhdGFTdHIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUNY2FsbGVyQWRkcmVzcwIABAh1c2VyRGF0YQMJAGYCCQCxAgEFC3VzZXJEYXRhU3RyAAAECHVzZXJEYXRhCQC1CQIFC3VzZXJEYXRhU3RyBQNTRVAEFXVzZXJUb3RhbFN0YWtlZEFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCHVzZXJEYXRhAAAJALkJAgkAzAgCCQCkAwEJAGQCBRV1c2VyVG90YWxTdGFrZWRBbW91bnQIBQdwYXltZW50BmFtb3VudAkAzAgCCQCRAwIFCHVzZXJEYXRhAAEJAMwIAgkAkQMCBQh1c2VyRGF0YQACCQDMCAIJAJEDAgUIdXNlckRhdGEAAwkAzAgCCQCkAwEFBmhlaWdodAUDbmlsBQNTRVAJALkJAgkAzAgCCQCkAwEIBQdwYXltZW50BmFtb3VudAkAzAgCAgEwCQDMCAIJAKQDAQUSY3VycmVudFBvb2xDbGFpbUlkCQDMCAIJAKQDAQUtY3VycmVudFRvdGFsUG9vbFJld2FyZHNFYXJuZWRGb3JPbmVTdGFrZVRva2VuCQDMCAIJAKQDAQUGaGVpZ2h0BQNuaWwFA1NFUAkAzAgCCQELU3RyaW5nRW50cnkCBQ1jYWxsZXJBZGRyZXNzBQh1c2VyRGF0YQkAzAgCCQEMSW50ZWdlckVudHJ5AgUSdG90YWxQb29sU3Rha2VkS2V5CQBkAgUWY3VycmVudFRvdGFsUG9vbFN0YWtlZAgFB3BheW1lbnQGYW1vdW50BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEId2l0aGRyYXcBBmFtb3VudAMJAGcCAAAFBmFtb3VudAkAAgECF0Ftb3VudCBtdXN0IGJlIHBvc2l0aXZlBA1jYWxsZXJBZGRyZXNzCQDYBAEICAUBaQZjYWxsZXIFYnl0ZXMDCQEaaXNVc2VySGF2ZVVuY2xhaW1lZFJld2FyZHMBBQ1jYWxsZXJBZGRyZXNzCQACAQI4WW91IGhhdmUgdW5jbGFpbWVkIHJld2FyZHMgb24gY29udHJhY3QsIGNsYWltIHRoZW0gZmlyc3QECHVzZXJEYXRhCQC1CQIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBBQ1jYWxsZXJBZGRyZXNzAg5Vc2VyIG5vdCBmb3VuZAUDU0VQBBV1c2VyVG90YWxTdGFrZWRBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQh1c2VyRGF0YQAAAwkAZgIFBmFtb3VudAUVdXNlclRvdGFsU3Rha2VkQW1vdW50CQACAQISSW5zdWZmaWNpZW50IGZ1bmRzBBR3aXRoZHJhd2FsTG9ja1BlcmlvZAkBEUBleHRyTmF0aXZlKDEwNTUpAQUXd2l0aGRyYXdhbExvY2tQZXJpb2RLZXkEEnVzZXJMYXN0U3Rha2VCbG9jawkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCHVzZXJEYXRhAAQDAwkAZgIFFHdpdGhkcmF3YWxMb2NrUGVyaW9kAAAJAGYCBRR3aXRoZHJhd2FsTG9ja1BlcmlvZAkAZQIFBmhlaWdodAUSdXNlckxhc3RTdGFrZUJsb2NrBwkAAgEJAKwCAgkArAICAi1UaGlzIHBvb2wgaGF2ZSBsb2NrIHBlcmlvZC4gWW91IG5lZWQgdG8gd2FpdCAJAKQDAQkAZQIFFHdpdGhkcmF3YWxMb2NrUGVyaW9kCQBlAgUGaGVpZ2h0BRJ1c2VyTGFzdFN0YWtlQmxvY2sCByBibG9ja3MEE3Jvb3RDb250cmFjdEFkZHJlc3MJARFAZXh0ck5hdGl2ZSgxMDU4KQEFFnJvb3RDb250cmFjdEFkZHJlc3NLZXkEFmN1cnJlbnRUb3RhbFBvb2xTdGFrZWQJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUSdG90YWxQb29sU3Rha2VkS2V5AAAEEHBvb2xTdGFrZUFzc2V0SWQJARFAZXh0ck5hdGl2ZSgxMDU4KQEFE3Bvb2xTdGFrZUFzc2V0SWRLZXkEBnJlc3VsdAMJAGYCCQCxAgEFE3Jvb3RDb250cmFjdEFkZHJlc3MAAAkA/AcECQEHQWRkcmVzcwEJANkEAQUTcm9vdENvbnRyYWN0QWRkcmVzcwIPd2l0aGRyYXdQb29sTHBzCQDMCAIFBmFtb3VudAUDbmlsBQNuaWwFBHVuaXQDCQAAAgUGcmVzdWx0BQZyZXN1bHQEC25ld1VzZXJEYXRhCQDMCAIJAKQDAQkAZQIFFXVzZXJUb3RhbFN0YWtlZEFtb3VudAUGYW1vdW50CQDRCAIFCHVzZXJEYXRhAAAJAM0IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUSdG90YWxQb29sU3Rha2VkS2V5CQBlAgUWY3VycmVudFRvdGFsUG9vbFN0YWtlZAUGYW1vdW50CQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMJAQdBZGRyZXNzAQgIBQFpBmNhbGxlcgVieXRlcwUGYW1vdW50CQDZBAEFEHBvb2xTdGFrZUFzc2V0SWQFA25pbAMJAAACCQBlAgUVdXNlclRvdGFsU3Rha2VkQW1vdW50BQZhbW91bnQAAAkBC0RlbGV0ZUVudHJ5AQUNY2FsbGVyQWRkcmVzcwkBC1N0cmluZ0VudHJ5AgUNY2FsbGVyQWRkcmVzcwkAuQkCBQtuZXdVc2VyRGF0YQUDU0VQCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDGNsYWltUmV3YXJkcwAEDWNhbGxlckFkZHJlc3MJANgEAQgIBQFpBmNhbGxlcgVieXRlcwMJAQEhAQkBGmlzVXNlckhhdmVVbmNsYWltZWRSZXdhcmRzAQUNY2FsbGVyQWRkcmVzcwkAAgECI05vdGhpbmcgdG8gY2xhaW0sIG9yIHVzZXIgbm90IGZvdW5kBBJwb29sQ3VycmVudENsYWltSWQJARFAZXh0ck5hdGl2ZSgxMDU1KQEFFXBvb2xDdXJyZW50Q2xhaW1JZEtleQQmdG90YWxQb29sRWFybmVkUmV3YXJkc0Zvck9uZVN0YWtlVG9rZW4JARFAZXh0ck5hdGl2ZSgxMDU1KQEFEnRvdGFsUG9vbEVhcm5lZEtleQQIdXNlckRhdGEJALUJAgkBEUBleHRyTmF0aXZlKDEwNTgpAQUNY2FsbGVyQWRkcmVzcwUDU0VQBA91c2VyVG90YWxTdGFrZWQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQh1c2VyRGF0YQAABBd1c2VyVG90YWxSZXdhcmRzQ2xhaW1lZAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCHVzZXJEYXRhAAEEGHVzZXJMYXN0Q2xhaW1Qb29sQ2xhaW1JZAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCHVzZXJEYXRhAAIEKXVzZXJBbHJlYWR5Q2xhaW1lZFJld2FyZHNGb3JPbmVTdGFrZVRva2VuCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIdXNlckRhdGEAAwQpdXNlclVuY2xhaW1lZFBvb2xFYXJuaW5nc0Zvck9uZVN0YWtlVG9rZW4JAGUCBSZ0b3RhbFBvb2xFYXJuZWRSZXdhcmRzRm9yT25lU3Rha2VUb2tlbgUpdXNlckFscmVhZHlDbGFpbWVkUmV3YXJkc0Zvck9uZVN0YWtlVG9rZW4ECXVzZXJDbGFpbQkAawMFKXVzZXJVbmNsYWltZWRQb29sRWFybmluZ3NGb3JPbmVTdGFrZVRva2VuBQ91c2VyVG90YWxTdGFrZWQFBk1VTFQxMAQLbmV3VXNlckRhdGEJALkJAgkAzAgCCQCRAwIFCHVzZXJEYXRhAAAJAMwIAgkApAMBCQBkAgUXdXNlclRvdGFsUmV3YXJkc0NsYWltZWQFCXVzZXJDbGFpbQkAzAgCCQCkAwEFEnBvb2xDdXJyZW50Q2xhaW1JZAkAzAgCCQCkAwEJAGQCBSl1c2VyQWxyZWFkeUNsYWltZWRSZXdhcmRzRm9yT25lU3Rha2VUb2tlbgUpdXNlclVuY2xhaW1lZFBvb2xFYXJuaW5nc0Zvck9uZVN0YWtlVG9rZW4JAMwIAgkAkQMCBQh1c2VyRGF0YQAEBQNuaWwFA1NFUAQNcmV3YXJkQXNzZXRJZAkA2QQBCQERQGV4dHJOYXRpdmUoMTA1OCkBBRByZXdhcmRBc3NldElkS2V5CQDMCAIJAQtTdHJpbmdFbnRyeQIFDWNhbGxlckFkZHJlc3MFC25ld1VzZXJEYXRhCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgUJdXNlckNsYWltBQ1yZXdhcmRBc3NldElkBQNuaWwBaQEQY2xhaW1Qb29sUmV3YXJkcwADCQECIT0CCAgFAWkGY2FsbGVyBWJ5dGVzCQDZBAEJARFAZXh0ck5hdGl2ZSgxMDU4KQEFD2FkbWluQWRkcmVzc0tleQkAAgECCkFkbWluIG9ubHkED3RvdGFsUG9vbFN0YWtlZAkBEUBleHRyTmF0aXZlKDEwNTUpAQUSdG90YWxQb29sU3Rha2VkS2V5BA90b3RhbFBvb2xFYXJuZWQJARFAZXh0ck5hdGl2ZSgxMDU1KQEFEnRvdGFsUG9vbEVhcm5lZEtleQQScG9vbEN1cnJlbnRDbGFpbUlkCQERQGV4dHJOYXRpdmUoMTA1NSkBBRVwb29sQ3VycmVudENsYWltSWRLZXkEDXJld2FyZEFzc2V0SWQJANkEAQkBEUBleHRyTmF0aXZlKDEwNTgpAQUQcmV3YXJkQXNzZXRJZEtleQQTcm9vdENvbnRyYWN0QWRkcmVzcwkBEUBleHRyTmF0aXZlKDEwNTgpAQUWcm9vdENvbnRyYWN0QWRkcmVzc0tleQQXY3VycmVudFJld2FyZE9uQ29udHJhY3QJAPAHAgUEdGhpcwUNcmV3YXJkQXNzZXRJZAMJAAACBRdjdXJyZW50UmV3YXJkT25Db250cmFjdAUXY3VycmVudFJld2FyZE9uQ29udHJhY3QEEXJvb3RDb250cmFjdENsYWltAwkAZgIJALECAQUTcm9vdENvbnRyYWN0QWRkcmVzcwAACQD8BwQJAQdBZGRyZXNzAQkA2QQBBRNyb290Q29udHJhY3RBZGRyZXNzAhBjbGFpbVBvb2xSZXdhcmRzBQNuaWwFA25pbAUEdW5pdAMJAAACBRFyb290Q29udHJhY3RDbGFpbQURcm9vdENvbnRyYWN0Q2xhaW0EE25ld1Jld2FyZE9uQ29udHJhY3QJAPAHAgUEdGhpcwUNcmV3YXJkQXNzZXRJZAQhY3VycmVudEFkZGl0aW9uYWxVbmNsYWltZWRSZXdhcmRzCQERQGV4dHJOYXRpdmUoMTA1NSkBBShwb29sQ3VycmVudFVuY2xhaW1lZEFkZGl0aW9uYWxSZXdhcmRzS2V5BBNjbGFpbWVkUmV3YXJkQW1vdW50CQBkAgkAZQIFE25ld1Jld2FyZE9uQ29udHJhY3QFF2N1cnJlbnRSZXdhcmRPbkNvbnRyYWN0BSFjdXJyZW50QWRkaXRpb25hbFVuY2xhaW1lZFJld2FyZHMDCQAAAgUTY2xhaW1lZFJld2FyZEFtb3VudAAABQNuaWwEJmN1cnJlbnRDbGFpbUlkRWFybmluZ3NGb3JPbmVTdGFrZVRva2VuCQBrAwUTY2xhaW1lZFJld2FyZEFtb3VudAUGTVVMVDEwBQ90b3RhbFBvb2xTdGFrZWQJAMwIAgkBDEludGVnZXJFbnRyeQIFFXBvb2xDdXJyZW50Q2xhaW1JZEtleQkAZAIFEnBvb2xDdXJyZW50Q2xhaW1JZAABCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRJ0b3RhbFBvb2xFYXJuZWRLZXkJAGQCBQ90b3RhbFBvb2xFYXJuZWQFJmN1cnJlbnRDbGFpbUlkRWFybmluZ3NGb3JPbmVTdGFrZVRva2VuCQDMCAIJAQxJbnRlZ2VyRW50cnkCBShwb29sQ3VycmVudFVuY2xhaW1lZEFkZGl0aW9uYWxSZXdhcmRzS2V5AAAFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARdyZWNlaXZlQWRkaXRpb25hbFJld2FyZAADCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAhRPbmUgUGF5bWVudCBleHBlY3RlZAQHcGF5bWVudAkBCWFzUGF5bWVudAEJAJEDAggFAWkIcGF5bWVudHMAAAQNcmV3YXJkQXNzZXRJZAkA2QQBCQERQGV4dHJOYXRpdmUoMTA1OCkBBRByZXdhcmRBc3NldElkS2V5AwMJAQIhPQIIBQdwYXltZW50B2Fzc2V0SWQFDXJld2FyZEFzc2V0SWQGCQBnAgAACAUHcGF5bWVudAZhbW91bnQJAAIBAihXcm9uZyByZXdhcmQgYXNzZXQgaWQgb3IgbmVnYXRpdmUgYW1vdW50BCFjdXJyZW50VW5jbGFpbWVkQWRkaXRpb25hbFJld2FyZHMJARFAZXh0ck5hdGl2ZSgxMDU1KQEFKHBvb2xDdXJyZW50VW5jbGFpbWVkQWRkaXRpb25hbFJld2FyZHNLZXkJAMwIAgkBDEludGVnZXJFbnRyeQIFKHBvb2xDdXJyZW50VW5jbGFpbWVkQWRkaXRpb25hbFJld2FyZHNLZXkJAGQCBSFjdXJyZW50VW5jbGFpbWVkQWRkaXRpb25hbFJld2FyZHMIBQdwYXltZW50BmFtb3VudAUDbmlsAQJ0eAEGdmVyaWZ5AAkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAgFAnR4D3NlbmRlclB1YmxpY0tleVL+lcc=", "height": 2773866, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: none Next: none Full:
OldNewDifferences
1-# no script
1+{-# STDLIB_VERSION 6 #-}
2+{-# SCRIPT_TYPE ACCOUNT #-}
3+{-# CONTENT_TYPE DAPP #-}
4+let MULT10 = 10000000000
5+
6+let SEP = "__"
7+
8+let isConstructedKey = "is_constructed"
9+
10+let withdrawalLockPeriodKey = "withdrawal_lock_period"
11+
12+let rewardAssetIdKey = "reward_asset_id"
13+
14+let poolStakeAssetIdKey = "pool_stake_asset_id"
15+
16+let rootContractAddressKey = "root_contract_address"
17+
18+let adminAddressKey = "admin_address_key"
19+
20+let totalPoolStakedKey = "total_pool__staked"
21+
22+let totalPoolEarnedKey = "total_pool_earned"
23+
24+let poolCurrentClaimIdKey = "pool_current_claim_id"
25+
26+let poolCurrentUnclaimedAdditionalRewardsKey = "pool_current_unclaimed_additional_rewards"
27+
28+func asPayment (v) = match v {
29+ case p: AttachedPayment =>
30+ p
31+ case _ =>
32+ throw("fail to cast into AttachedPayment")
33+}
34+
35+
36+func isUserHaveUnclaimedRewards (address) = if (!(isDefined(getString(address))))
37+ then false
38+ else {
39+ let currentPoolClaimId = getIntegerValue(poolCurrentClaimIdKey)
40+ let userData = split(getStringValue(address), SEP)
41+ let userLastClaimedRewardsAtPoolClaimId = parseIntValue(userData[2])
42+ (currentPoolClaimId > userLastClaimedRewardsAtPoolClaimId)
43+ }
44+
45+
46+@Callable(i)
47+func constructor (rewardAssetId,poolStakeAssetId,withdrawalLockPeriod,rootContract,adminContract) = if (isDefined(getBoolean(isConstructedKey)))
48+ then throw("Constructor can be called one time")
49+ else [BooleanEntry(isConstructedKey, true), IntegerEntry(poolCurrentUnclaimedAdditionalRewardsKey, 0), StringEntry(rewardAssetIdKey, rewardAssetId), StringEntry(poolStakeAssetIdKey, poolStakeAssetId), StringEntry(rootContractAddressKey, rootContract), StringEntry(adminAddressKey, adminContract), IntegerEntry(totalPoolEarnedKey, 0), IntegerEntry(poolCurrentClaimIdKey, 0), IntegerEntry(totalPoolStakedKey, 0), IntegerEntry(withdrawalLockPeriodKey, withdrawalLockPeriod)]
50+
51+
52+
53+@Callable(i)
54+func stake () = if ((size(i.payments) != 1))
55+ then throw("One Payment expected")
56+ else {
57+ let callerAddress = toBase58String(i.caller.bytes)
58+ let payment = asPayment(i.payments[0])
59+ let poolStakeAssetId = fromBase58String(getStringValue(poolStakeAssetIdKey))
60+ if (if ((payment.assetId != poolStakeAssetId))
61+ then true
62+ else (0 >= payment.amount))
63+ then throw("Wrong asset id or negative amount")
64+ else if (isUserHaveUnclaimedRewards(callerAddress))
65+ then throw("You have unclaimed rewards on contract, claim them first")
66+ else {
67+ let currentPoolClaimId = getIntegerValue(poolCurrentClaimIdKey)
68+ let currentTotalPoolStaked = getIntegerValue(totalPoolStakedKey)
69+ let currentTotalPoolRewardsEarnedForOneStakeToken = getIntegerValue(totalPoolEarnedKey)
70+ let rootContractAddress = getStringValue(rootContractAddressKey)
71+ let result = if ((size(rootContractAddress) > 0))
72+ then invoke(Address(fromBase58String(rootContractAddress)), "stakePoolLps", nil, [payment])
73+ else unit
74+ if ((result == result))
75+ then {
76+ let userDataStr = valueOrElse(getString(callerAddress), "")
77+ let userData = if ((size(userDataStr) > 0))
78+ then {
79+ let userData = split(userDataStr, SEP)
80+ let userTotalStakedAmount = parseIntValue(userData[0])
81+ makeString([toString((userTotalStakedAmount + payment.amount)), userData[1], userData[2], userData[3], toString(height)], SEP)
82+ }
83+ else makeString([toString(payment.amount), "0", toString(currentPoolClaimId), toString(currentTotalPoolRewardsEarnedForOneStakeToken), toString(height)], SEP)
84+[StringEntry(callerAddress, userData), IntegerEntry(totalPoolStakedKey, (currentTotalPoolStaked + payment.amount))]
85+ }
86+ else throw("Strict value is not equal to itself.")
87+ }
88+ }
89+
90+
91+
92+@Callable(i)
93+func withdraw (amount) = if ((0 >= amount))
94+ then throw("Amount must be positive")
95+ else {
96+ let callerAddress = toBase58String(i.caller.bytes)
97+ if (isUserHaveUnclaimedRewards(callerAddress))
98+ then throw("You have unclaimed rewards on contract, claim them first")
99+ else {
100+ let userData = split(valueOrErrorMessage(getString(callerAddress), "User not found"), SEP)
101+ let userTotalStakedAmount = parseIntValue(userData[0])
102+ if ((amount > userTotalStakedAmount))
103+ then throw("Insufficient funds")
104+ else {
105+ let withdrawalLockPeriod = getIntegerValue(withdrawalLockPeriodKey)
106+ let userLastStakeBlock = parseIntValue(userData[4])
107+ if (if ((withdrawalLockPeriod > 0))
108+ then (withdrawalLockPeriod > (height - userLastStakeBlock))
109+ else false)
110+ then throw((("This pool have lock period. You need to wait " + toString((withdrawalLockPeriod - (height - userLastStakeBlock)))) + " blocks"))
111+ else {
112+ let rootContractAddress = getStringValue(rootContractAddressKey)
113+ let currentTotalPoolStaked = valueOrElse(getInteger(totalPoolStakedKey), 0)
114+ let poolStakeAssetId = getStringValue(poolStakeAssetIdKey)
115+ let result = if ((size(rootContractAddress) > 0))
116+ then invoke(Address(fromBase58String(rootContractAddress)), "withdrawPoolLps", [amount], nil)
117+ else unit
118+ if ((result == result))
119+ then {
120+ let newUserData = [toString((userTotalStakedAmount - amount)), removeByIndex(userData, 0)]
121+ ([IntegerEntry(totalPoolStakedKey, (currentTotalPoolStaked - amount)), ScriptTransfer(Address(i.caller.bytes), amount, fromBase58String(poolStakeAssetId))] :+ (if (((userTotalStakedAmount - amount) == 0))
122+ then DeleteEntry(callerAddress)
123+ else StringEntry(callerAddress, makeString(newUserData, SEP))))
124+ }
125+ else throw("Strict value is not equal to itself.")
126+ }
127+ }
128+ }
129+ }
130+
131+
132+
133+@Callable(i)
134+func claimRewards () = {
135+ let callerAddress = toBase58String(i.caller.bytes)
136+ if (!(isUserHaveUnclaimedRewards(callerAddress)))
137+ then throw("Nothing to claim, or user not found")
138+ else {
139+ let poolCurrentClaimId = getIntegerValue(poolCurrentClaimIdKey)
140+ let totalPoolEarnedRewardsForOneStakeToken = getIntegerValue(totalPoolEarnedKey)
141+ let userData = split(getStringValue(callerAddress), SEP)
142+ let userTotalStaked = parseIntValue(userData[0])
143+ let userTotalRewardsClaimed = parseIntValue(userData[1])
144+ let userLastClaimPoolClaimId = parseIntValue(userData[2])
145+ let userAlreadyClaimedRewardsForOneStakeToken = parseIntValue(userData[3])
146+ let userUnclaimedPoolEarningsForOneStakeToken = (totalPoolEarnedRewardsForOneStakeToken - userAlreadyClaimedRewardsForOneStakeToken)
147+ let userClaim = fraction(userUnclaimedPoolEarningsForOneStakeToken, userTotalStaked, MULT10)
148+ let newUserData = makeString([userData[0], toString((userTotalRewardsClaimed + userClaim)), toString(poolCurrentClaimId), toString((userAlreadyClaimedRewardsForOneStakeToken + userUnclaimedPoolEarningsForOneStakeToken)), userData[4]], SEP)
149+ let rewardAssetId = fromBase58String(getStringValue(rewardAssetIdKey))
150+[StringEntry(callerAddress, newUserData), ScriptTransfer(i.caller, userClaim, rewardAssetId)]
151+ }
152+ }
153+
154+
155+
156+@Callable(i)
157+func claimPoolRewards () = if ((i.caller.bytes != fromBase58String(getStringValue(adminAddressKey))))
158+ then throw("Admin only")
159+ else {
160+ let totalPoolStaked = getIntegerValue(totalPoolStakedKey)
161+ let totalPoolEarned = getIntegerValue(totalPoolEarnedKey)
162+ let poolCurrentClaimId = getIntegerValue(poolCurrentClaimIdKey)
163+ let rewardAssetId = fromBase58String(getStringValue(rewardAssetIdKey))
164+ let rootContractAddress = getStringValue(rootContractAddressKey)
165+ let currentRewardOnContract = assetBalance(this, rewardAssetId)
166+ if ((currentRewardOnContract == currentRewardOnContract))
167+ then {
168+ let rootContractClaim = if ((size(rootContractAddress) > 0))
169+ then invoke(Address(fromBase58String(rootContractAddress)), "claimPoolRewards", nil, nil)
170+ else unit
171+ if ((rootContractClaim == rootContractClaim))
172+ then {
173+ let newRewardOnContract = assetBalance(this, rewardAssetId)
174+ let currentAdditionalUnclaimedRewards = getIntegerValue(poolCurrentUnclaimedAdditionalRewardsKey)
175+ let claimedRewardAmount = ((newRewardOnContract - currentRewardOnContract) + currentAdditionalUnclaimedRewards)
176+ if ((claimedRewardAmount == 0))
177+ then nil
178+ else {
179+ let currentClaimIdEarningsForOneStakeToken = fraction(claimedRewardAmount, MULT10, totalPoolStaked)
180+[IntegerEntry(poolCurrentClaimIdKey, (poolCurrentClaimId + 1)), IntegerEntry(totalPoolEarnedKey, (totalPoolEarned + currentClaimIdEarningsForOneStakeToken)), IntegerEntry(poolCurrentUnclaimedAdditionalRewardsKey, 0)]
181+ }
182+ }
183+ else throw("Strict value is not equal to itself.")
184+ }
185+ else throw("Strict value is not equal to itself.")
186+ }
187+
188+
189+
190+@Callable(i)
191+func receiveAdditionalReward () = if ((size(i.payments) != 1))
192+ then throw("One Payment expected")
193+ else {
194+ let payment = asPayment(i.payments[0])
195+ let rewardAssetId = fromBase58String(getStringValue(rewardAssetIdKey))
196+ if (if ((payment.assetId != rewardAssetId))
197+ then true
198+ else (0 >= payment.amount))
199+ then throw("Wrong reward asset id or negative amount")
200+ else {
201+ let currentUnclaimedAdditionalRewards = getIntegerValue(poolCurrentUnclaimedAdditionalRewardsKey)
202+[IntegerEntry(poolCurrentUnclaimedAdditionalRewardsKey, (currentUnclaimedAdditionalRewards + payment.amount))]
203+ }
204+ }
205+
206+
207+@Verifier(tx)
208+func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
209+

github/deemru/w8io/026f985 
17.75 ms