tx · 3jh6dkt1R7KUXxJZ2Dbg82p4DraHUKknmgByigfFUiUR

3N9LkJahTMx41wGhSxLS42prCZtRCp4dhTs:  -0.04000000 Waves

2022.10.19 14:22 [2279208] smart account 3N9LkJahTMx41wGhSxLS42prCZtRCp4dhTs > SELF 0.00000000 Waves

{ "type": 13, "id": "3jh6dkt1R7KUXxJZ2Dbg82p4DraHUKknmgByigfFUiUR", "fee": 4000000, "feeAssetId": null, "timestamp": 1666178557528, "version": 1, "sender": "3N9LkJahTMx41wGhSxLS42prCZtRCp4dhTs", "senderPublicKey": "8hm3x3tdBbKUu4XpjDGwNdaPA2qEdrdchHue4k49BsYJ", "proofs": [ "3nwHi97ZCYiTm2Wo2MEANW8FksMTzVrhrAss6c5u5BaW7TAqJqX1eyJpHAyz1N4EQMz7ghXULcGQCnGbuegW13Uk", "ZtZKoHfgnTTiDYf38w8E71b6HDJWanB4cV6a1AWvbxpW5AshB7UmQtZcvbu4bPzb6nNRQxx7eBoAYY3GNXiaDrB", "4qixREuxZvzFzvsm54va69HwKvQ3ZcHUJbp3P2dX2c2WZPo5x91UaXhSXYvyxcMXzbjjawctMhwn8uydUSRvpdTh" ], "script": "base64:BgI5CAISBQoDAQgIEgASABIDCgEBEgASABIAEgMKAQgSBAoCCAESABIECgIIARIAEgQKAgEIEgQKAgEIZQADU0VQAgJfXwAFTVVMVDYAwIQ9AAVNVUxUOACAwtcvAAZNVUxUWDYJALYCAQUFTVVMVDYABk1VTFRYOAkAtgIBBQVNVUxUOAAHTVVMVFgxOAkAtgIBAICAkLu61q3wDQAKV0FWRVNJRFNUUgIFV0FWRVMAB1dBVkVTSUQJANkEAQUKV0FWRVNJRFNUUgAJREFZTUlMTElTAIC4mSkAGUlkeENvbnRyb2xDZmdOZXV0cmlub0RhcHAAAQAYSWR4Q29udHJvbENmZ0F1Y3Rpb25EYXBwAAIAFElkeENvbnRyb2xDZmdScGREYXBwAAMAFUlkeENvbnRyb2xDZmdNYXRoRGFwcAAEABxJZHhDb250cm9sQ2ZnTGlxdWlkYXRpb25EYXBwAAUAFUlkeENvbnRyb2xDZmdSZXN0RGFwcAAGAB1JZHhDb250cm9sQ2ZnTm9kZVJlZ2lzdHJ5RGFwcAAHABxJZHhDb250cm9sQ2ZnTnNidFN0YWtpbmdEYXBwAAgAGUlkeENvbnRyb2xDZmdNZWRpYXRvckRhcHAACQAcSWR4Q29udHJvbENmZ1N1cmZTdGFraW5nRGFwcAAKACBJZHhDb250cm9sQ2ZnR25zYnRDb250cm9sbGVyRGFwcAALAQ9nZXRTdHJpbmdPckZhaWwCB2FkZHJlc3MDa2V5CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUHYWRkcmVzcwUDa2V5CQCsAgIJAKwCAgkArAICCQCsAgICCm1hbmRhdG9yeSAJAKUIAQUHYWRkcmVzcwIBLgUDa2V5Ag8gaXMgbm90IGRlZmluZWQBDGdldEludE9yRmFpbAEDa2V5CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUEdGhpcwUDa2V5CQCsAgIJAKwCAgIPTWFuZGF0b3J5IHRoaXMuBQNrZXkCDyBpcyBub3QgZGVmaW5lZAEMZ2V0U3RyT3JFbHNlAgNrZXkKZGVmYXVsdFZhbAkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQNrZXkFCmRlZmF1bHRWYWwBEGtleU1pbkxvY2tBbW91bnQAAhElc19fbWluTG9ja0Ftb3VudAEQa2V5U3Rha2VkQXNzZXRJZAACESVzX19zdGFrZWRBc3NldElkARFrZXlDb250cm9sQWRkcmVzcwACHCVzJXNfX2NvbmZpZ19fY29udHJvbEFkZHJlc3MBDWtleUNvbnRyb2xDZmcAAhElc19fY29udHJvbENvbmZpZwEYa2V5U3VwcG9ydGVkUmV3YXJkQXNzZXRzAAIVc3VwcG9ydGVkUmV3YXJkQXNzZXRzARRyZWFkQ29udHJvbENmZ09yRmFpbAEHY29udHJvbAkAvAkCCQEPZ2V0U3RyaW5nT3JGYWlsAgUHY29udHJvbAkBDWtleUNvbnRyb2xDZmcABQNTRVABGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIKY29udHJvbENmZwNpZHgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIFCmNvbnRyb2xDZmcFA2lkeAkArAICAi1Db250cm9sIGNmZyBkb2Vzbid0IGNvbnRhaW4gYWRkcmVzcyBhdCBpbmRleCAJAKQDAQUDaWR4AA9jb250cm9sQ29udHJhY3QJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwkBEWtleUNvbnRyb2xBZGRyZXNzAAIjM040TlM3ZDRKbzlhNkYxNExpRlVLS1lWZFVra2YyZVA0WngACmNvbnRyb2xDZmcJARRyZWFkQ29udHJvbENmZ09yRmFpbAEFD2NvbnRyb2xDb250cmFjdAAMbWF0aENvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUKY29udHJvbENmZwUVSWR4Q29udHJvbENmZ01hdGhEYXBwABBuZXV0cmlub0NvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUKY29udHJvbENmZwUZSWR4Q29udHJvbENmZ05ldXRyaW5vRGFwcAAPYXVjdGlvbkNvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUKY29udHJvbENmZwUYSWR4Q29udHJvbENmZ0F1Y3Rpb25EYXBwABBzdGFrZWRBc3NldElkU3RyCQEPZ2V0U3RyaW5nT3JGYWlsAgUEdGhpcwkBEGtleVN0YWtlZEFzc2V0SWQAAA1zdGFrZWRBc3NldElkCQDZBAEFEHN0YWtlZEFzc2V0SWRTdHIADW1pbkxvY2tBbW91bnQJAQxnZXRJbnRPckZhaWwBCQEQa2V5TWluTG9ja0Ftb3VudAAAEnN1cHBvcnRlZEFzc2V0c1N0cgkBDGdldFN0ck9yRWxzZQIJARhrZXlTdXBwb3J0ZWRSZXdhcmRBc3NldHMAAgAAE3N1cHBvcnRlZEFzc2V0c0xpc3QJALUJAgUSc3VwcG9ydGVkQXNzZXRzU3RyAgFfARZrZXlMb2NrUGFyYW1Vc2VyQW1vdW50AQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBiVzJXMlcwkAzAgCAgtwYXJhbUJ5VXNlcgkAzAgCBQt1c2VyQWRkcmVzcwkAzAgCAgZhbW91bnQFA25pbAUDU0VQARZrZXlMb2NrUGFyYW1TdGFydEJsb2NrAQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBiVzJXMlcwkAzAgCAgtwYXJhbUJ5VXNlcgkAzAgCBQt1c2VyQWRkcmVzcwkAzAgCAgVzdGFydAUDbmlsBQNTRVABEGtleUhpc3RvcnlSZWNvcmQDBHR5cGULdXNlckFkZHJlc3MEdHhJZAkAuQkCCQDMCAICCCVzJXMlcyVzCQDMCAICB2hpc3RvcnkJAMwIAgUEdHlwZQkAzAgCBQt1c2VyQWRkcmVzcwkAzAgCCQDYBAEFBHR4SWQFA25pbAUDU0VQARdrZXlMb2NrUGFyYW1Ub3RhbEFtb3VudAAJALkJAgkAzAgCAgQlcyVzCQDMCAICBXN0YXRzCQDMCAICEWFjdGl2ZVRvdGFsTG9ja2VkBQNuaWwFA1NFUAESa2V5U3RhdHNMb2Nrc0NvdW50AAkAuQkCCQDMCAICBCVzJXMJAMwIAgIFc3RhdHMJAMwIAgIKbG9ja3NDb3VudAUDbmlsBQNTRVABEmtleVN0YXRzVXNlcnNDb3VudAAJALkJAgkAzAgCAgQlcyVzCQDMCAICBXN0YXRzCQDMCAICEGFjdGl2ZVVzZXJzQ291bnQFA25pbAUDU0VQARdrZXlTdGF0c0RlcG9zaXRBbXRCeURheQEJdGltZXN0YW1wCQC5CQIJAMwIAgIGJXMlcyVkCQDMCAICBXN0YXRzCQDMCAICD2RlcG9zaXRBbXRCeURheQkAzAgCCQCkAwEFCXRpbWVzdGFtcAUDbmlsBQNTRVABGGtleVN0YXRzRGVwb3NpdEFtdFRvdGFscwAJALkJAgkAzAgCAgYlcyVzJWQJAMwIAgIFc3RhdHMJAMwIAgIQZGVwb3NpdEFtdFRvdGFscwUDbmlsBQNTRVABDWtleU5leHRQZXJpb2QAAg4lc19fbmV4dFBlcmlvZAERa2V5RGVwb3NpdE51bUxhc3QACQC5CQIJAMwIAgIGJXMlcyVzCQDMCAICA2RlcAkAzAgCAgdsYXN0TnVtBQNuaWwFA1NFUAEba2V5VXNlclJld2FyZEZyb21EZXBvc2l0TnVtAQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBiVzJXMlcwkAzAgCAhF1c2VyUndkRnJvbURlcE51bQkAzAgCBQt1c2VyQWRkcmVzcwUDbmlsBQNTRVABFWtleVJld2FyZFBlck5zYnRTdW1BdAIKZGVwb3NpdE51bQN0a24JALkJAgkAzAgCAgQlcyVkCQDMCAICFXJ3ZFBlck5zYnRTdW1CeURlcE51bQkAzAgCCQCkAwEFCmRlcG9zaXROdW0JAMwIAgUDdGtuBQNuaWwFA1NFUAEJa2V5UmV3YXJkAgt1c2VyQWRkcmVzcwN0a24JALkJAgkAzAgCAgYlcyVzJXMJAMwIAgIDcndkCQDMCAIFC3VzZXJBZGRyZXNzCQDMCAIFA3RrbgUDbmlsBQNTRVABCmtleUNsYWltZWQCC3VzZXJBZGRyZXNzA3RrbgkAuQkCCQDMCAICBiVzJXMlcwkAzAgCAgNjbG0JAMwIAgULdXNlckFkZHJlc3MJAMwIAgUDdGtuBQNuaWwFA1NFUAEXa2V5Tm90RGlzdHJpYnV0ZWRSZXdhcmQBA3RrbgkAuQkCCQDMCAICBCVzJXMJAMwIAgIObm90RGlzdHJpYnV0ZWQJAMwIAgUDdGtuBQNuaWwFA1NFUAEUa2V5TGVnYWN5VXNlckJhbGFuY2UCCHVzZXJBZGRyA3RrbgkAuQkCCQDMCAICC3JwZF9iYWxhbmNlCQDMCAIFA3RrbgkAzAgCBQh1c2VyQWRkcgUDbmlsBQNTRVABFWtleUxlZ2FjeVRvdGFsQmFsYW5jZQEDdGtuCQC5CQIJAMwIAgILcnBkX2JhbGFuY2UJAMwIAgUDdGtuBQNuaWwFA1NFUAEFdG9YMTgCB29yaWdWYWwIb3JpZ011bHQJALwCAwkAtgIBBQdvcmlnVmFsBQdNVUxUWDE4BQhvcmlnTXVsdAEMZ2V0SW50T3JaZXJvAQNrZXkJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUDa2V5AAABDGdldEludE9yRWxzZQIDa2V5CmRlZmF1bHRWYWwJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUDa2V5BQpkZWZhdWx0VmFsAQ90b0FkZHJlc3NPckZhaWwBCmFkZHJlc3NTdHIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBBQphZGRyZXNzU3RyCQCsAgICIWNvdWxkbid0IHBhcnNlIHBhc3NlZCBhZGRyZXNzU3RyPQUKYWRkcmVzc1N0cgELdG9Bc3NldFZlY3QBCGFzc2V0U3RyAwkAAAIFCGFzc2V0U3RyBQpXQVZFU0lEU1RSBQR1bml0CQDZBAEFCGFzc2V0U3RyAQVhc0ludAEDdmFsBAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIDSW50BAZ2YWxJbnQFByRtYXRjaDAFBnZhbEludAkAAgECFWZhaWwgdG8gY2FzdCBpbnRvIEludAESYXNTd2FwUGFyYW1zU1RSVUNUAQF2BAckbWF0Y2gwBQF2AwkAAQIFByRtYXRjaDACIyhJbnQsIEludCwgSW50LCBJbnQsIEludCwgSW50LCBJbnQpBAZzdHJ1Y3QFByRtYXRjaDAFBnN0cnVjdAkAAgECFWZhaWwgdG8gY2FzdCBpbnRvIEludAETZm9ybWF0SGlzdG9yeVJlY29yZAMLdXNlckFkZHJlc3MJb2xkQW1vdW50CW5ld0Ftb3VudAkAuQkCCQDMCAICCiVzJWQlZCVkJWQJAMwIAgULdXNlckFkZHJlc3MJAMwIAgkApAMBCAUJbGFzdEJsb2NrBmhlaWdodAkAzAgCCQCkAwEIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAKQDAQUJb2xkQW1vdW50CQDMCAIJAKQDAQUJbmV3QW1vdW50BQNuaWwFA1NFUAEYZm9ybWF0Q2xhaW1IaXN0b3J5UmVjb3JkAgt1c2VyQWRkcmVzcw5jbGFpbWVkUmV3YXJkcwkAuQkCCQDMCAICCCVzJWQlZCVzCQDMCAIFC3VzZXJBZGRyZXNzCQDMCAIJAKQDAQgFCWxhc3RCbG9jawZoZWlnaHQJAMwIAgkApAMBCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCBQ5jbGFpbWVkUmV3YXJkcwUDbmlsBQNTRVABEkhpc3RvcnlSZWNvcmRFbnRyeQUEdHlwZQt1c2VyQWRkcmVzcwR0eElkCW9sZEFtb3VudAluZXdBbW91bnQJAQtTdHJpbmdFbnRyeQIJARBrZXlIaXN0b3J5UmVjb3JkAwUEdHlwZQULdXNlckFkZHJlc3MFBHR4SWQJARNmb3JtYXRIaXN0b3J5UmVjb3JkAwULdXNlckFkZHJlc3MFCW9sZEFtb3VudAUJbmV3QW1vdW50ARFDbGFpbUhpc3RvcnlFbnRyeQMLdXNlckFkZHJlc3MEdHhJZA5jbGFpbWVkUmV3YXJkcwkBC1N0cmluZ0VudHJ5AgkBEGtleUhpc3RvcnlSZWNvcmQDAgVjbGFpbQULdXNlckFkZHJlc3MFBHR4SWQJARhmb3JtYXRDbGFpbUhpc3RvcnlSZWNvcmQCBQt1c2VyQWRkcmVzcwUOY2xhaW1lZFJld2FyZHMBC1N0YXRzUmVzdWx0Aw50b3RhbExvY2tlZEluYwxsb2NrQ291bnRJbmMNdXNlcnNDb3VudEluYwQKbG9ja3NDb3VudAkBDGdldEludE9yWmVybwEJARJrZXlTdGF0c0xvY2tzQ291bnQABAp1c2Vyc0NvdW50CQEMZ2V0SW50T3JaZXJvAQkBEmtleVN0YXRzVXNlcnNDb3VudAAEC3RvdGFsQW1vdW50CQEMZ2V0SW50T3JaZXJvAQkBF2tleUxvY2tQYXJhbVRvdGFsQW1vdW50AAQOdG90YWxBbW91bnROZXcJAGQCBQt0b3RhbEFtb3VudAUOdG90YWxMb2NrZWRJbmMJAJUKAwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBEmtleVN0YXRzTG9ja3NDb3VudAAJAGQCBQpsb2Nrc0NvdW50BQxsb2NrQ291bnRJbmMJAMwIAgkBDEludGVnZXJFbnRyeQIJARJrZXlTdGF0c1VzZXJzQ291bnQACQBkAgUKdXNlcnNDb3VudAUNdXNlcnNDb3VudEluYwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBF2tleUxvY2tQYXJhbVRvdGFsQW1vdW50AAUOdG90YWxBbW91bnROZXcJAMwIAgkBDEludGVnZXJFbnRyeQIJARVrZXlMZWdhY3lUb3RhbEJhbGFuY2UBBRBzdGFrZWRBc3NldElkU3RyBQ50b3RhbEFtb3VudE5ldwUDbmlsBQt0b3RhbEFtb3VudAUOdG90YWxBbW91bnROZXcBD0xvY2tQYXJhbXNFbnRyeQMLdXNlckFkZHJlc3MGYW1vdW50EnN0YWtpbmdTdGFydEhlaWdodAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBFGtleUxlZ2FjeVVzZXJCYWxhbmNlAgULdXNlckFkZHJlc3MFEHN0YWtlZEFzc2V0SWRTdHIFBmFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBFmtleUxvY2tQYXJhbVVzZXJBbW91bnQBBQt1c2VyQWRkcmVzcwUGYW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEWa2V5TG9ja1BhcmFtU3RhcnRCbG9jawEFC3VzZXJBZGRyZXNzBRJzdGFraW5nU3RhcnRIZWlnaHQFA25pbAEPZ2V0UGFyYW1zT3JGYWlsAAkAlAoCCQDZBAEJAQ9nZXRTdHJpbmdPckZhaWwCBQR0aGlzCQEQa2V5U3Rha2VkQXNzZXRJZAAJAQxnZXRJbnRPckZhaWwBCQEQa2V5TWluTG9ja0Ftb3VudAABDGlzQWN0aXZlVXNlcgELdXNlckFkZHJlc3MJAGYCCQEMZ2V0SW50T3JFbHNlAgkBFmtleUxvY2tQYXJhbVVzZXJBbW91bnQBBQt1c2VyQWRkcmVzcwAAAAABE2dldFVzZXJQYXJhbXNPclVuaXQBC3VzZXJBZGRyZXNzAwkBDGlzQWN0aXZlVXNlcgEFC3VzZXJBZGRyZXNzCQCVCgMHCQEMZ2V0SW50T3JGYWlsAQkBFmtleUxvY2tQYXJhbVVzZXJBbW91bnQBBQt1c2VyQWRkcmVzcwkBDGdldEludE9yRmFpbAEJARZrZXlMb2NrUGFyYW1TdGFydEJsb2NrAQULdXNlckFkZHJlc3MFBHVuaXQBE2dldFVzZXJQYXJhbXNPckZhaWwBC3VzZXJBZGRyZXNzCQETdmFsdWVPckVycm9yTWVzc2FnZQIJARNnZXRVc2VyUGFyYW1zT3JVbml0AQULdXNlckFkZHJlc3MJAKwCAgkArAICAgVVc2VyIAULdXNlckFkZHJlc3MCDyBpcyBub3QgZGVmaW5lZAEKY2FsY1Jld2FyZAULdXNlckFkZHJlc3MHYXNzZXRJZA1zdGFrZWRBbW91bnRYDmRlcG9zaXROdW1Vc2VyDmRlcG9zaXROdW1MYXN0BBdyZXdhcmRQZXJOc2J0U3VtTGFzdEtFWQkBFWtleVJld2FyZFBlck5zYnRTdW1BdAIFDmRlcG9zaXROdW1MYXN0BQdhc3NldElkBApzdW1MYXN0WDE4CQCnAwEJAQxnZXRTdHJPckVsc2UCCQEVa2V5UmV3YXJkUGVyTnNidFN1bUF0AgUOZGVwb3NpdE51bUxhc3QFB2Fzc2V0SWQCATAECnN1bVVzZXJYMTgJAKcDAQkBDGdldFN0ck9yRWxzZQIJARVrZXlSZXdhcmRQZXJOc2J0U3VtQXQCBQ5kZXBvc2l0TnVtVXNlcgUHYXNzZXRJZAIBMAQRcmV3YXJkRHluYW1pY1BhcnQJAKADAQkAvAIDCQC4AgIFCnN1bUxhc3RYMTgFCnN1bVVzZXJYMTgFDXN0YWtlZEFtb3VudFgFB01VTFRYMTgEE3Jld2FyZENhY2hlZFBhcnRLRVkJAQlrZXlSZXdhcmQCBQt1c2VyQWRkcmVzcwUHYXNzZXRJZAQQcmV3YXJkQ2FjaGVkUGFydAkBDGdldEludE9yRWxzZQIFE3Jld2FyZENhY2hlZFBhcnRLRVkAAAkAlgoECQBkAgUQcmV3YXJkQ2FjaGVkUGFydAURcmV3YXJkRHluYW1pY1BhcnQFEHJld2FyZENhY2hlZFBhcnQFEXJld2FyZER5bmFtaWNQYXJ0BRNyZXdhcmRDYWNoZWRQYXJ0S0VZAQx0b1N0YXJ0T2ZEYXkBCXRpbWVzdGFtcAkAaAIJAGkCBQl0aW1lc3RhbXAFCURBWU1JTExJUwUJREFZTUlMTElTARNmaW5kRWxlbWVudFBvc2l0aW9uAwNzcmMHZWxlbWVudANzZXAEDGVsZW1lbnRTdGFydAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCzCQIFA3NyYwUHZWxlbWVudAkArAICCQCsAgIJAKwCAgIWdGhlcmUgaXMgbm8gc3Vic3RyaW5nIAUHZWxlbWVudAIEIGluIAUDc3JjAwkAAAIFDGVsZW1lbnRTdGFydAAAAAAEBGxlZnQJAK8CAgUDc3JjBQxlbGVtZW50U3RhcnQJAGUCCQCQAwEJALUJAgUEbGVmdAUDc2VwAAEAE0RlcG9zaXRUb3RhbHNQUkVGSVgCBCVkJWQBE3VwZGF0ZURlcG9zaXRUb3RhbHMDB2N1cnJWYWwLaWR4VG9VcGRhdGUIZGVsdGFBbXQEB2N1cnJBcnIJALUJAgUHY3VyclZhbAUDU0VQCgEOdXBkRGVwVG90QnlJZHgBA2lkeAMJAQIhPQIFA2lkeAULaWR4VG9VcGRhdGUJAJEDAgUHY3VyckFycgUDaWR4CQCkAwEJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHY3VyckFycgUDaWR4BQhkZWx0YUFtdAkAuQkCCQDMCAIFE0RlcG9zaXRUb3RhbHNQUkVGSVgJAMwIAgkBDnVwZERlcFRvdEJ5SWR4AQABCQDMCAIJAQ51cGREZXBUb3RCeUlkeAEAAgUDbmlsBQNTRVABFURlcG9zaXRzVG90YWxzRW50cmllcwINZGVwb3NpdEFtb3VudAphc3NldElkU3RyBApzdGFydE9mRGF5CQEMdG9TdGFydE9mRGF5AQgFCWxhc3RCbG9jawl0aW1lc3RhbXAECGJ5RGF5S0VZCQEXa2V5U3RhdHNEZXBvc2l0QW10QnlEYXkBBQpzdGFydE9mRGF5BAl0b3RhbHNLRVkJARhrZXlTdGF0c0RlcG9zaXRBbXRUb3RhbHMABAhwb3NpdGlvbgkBE2ZpbmRFbGVtZW50UG9zaXRpb24DBRJzdXBwb3J0ZWRBc3NldHNTdHIFCmFzc2V0SWRTdHICAV8EC2RlZmF1bHREQVRBCQCsAgIFE0RlcG9zaXRUb3RhbHNQUkVGSVgCBl9fMF9fMAQOY3VyclRvdGFsc0RBVEEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwUJdG90YWxzS0VZBQtkZWZhdWx0REFUQQQNbmV3VG90YWxzREFUQQkBE3VwZGF0ZURlcG9zaXRUb3RhbHMDBQ5jdXJyVG90YWxzREFUQQkAZAIFCHBvc2l0aW9uAAEFDWRlcG9zaXRBbW91bnQJAMwIAgkBC1N0cmluZ0VudHJ5AgUJdG90YWxzS0VZBQ1uZXdUb3RhbHNEQVRBCQDMCAIJAQtTdHJpbmdFbnRyeQIFCGJ5RGF5S0VZBQ1uZXdUb3RhbHNEQVRBBQNuaWwBDVJld2FyZEVudHJpZXMDCWlzTmV3VXNlcgt1c2VyQWRkcmVzcwxzdGFrZWRBbW91bnQEDXN0YWtlZEFtb3VudFgJALYCAQUMc3Rha2VkQW1vdW50BBt1c2VyUmV3YXJkRnJvbURlcG9zaXROdW1LRVkJARtrZXlVc2VyUmV3YXJkRnJvbURlcG9zaXROdW0BBQt1c2VyQWRkcmVzcwQOZGVwb3NpdE51bVVzZXIJAQxnZXRJbnRPckVsc2UCBRt1c2VyUmV3YXJkRnJvbURlcG9zaXROdW1LRVkA////////////AQQOZGVwb3NpdE51bUxhc3QJAQxnZXRJbnRPckVsc2UCCQERa2V5RGVwb3NpdE51bUxhc3QAAP///////////wEKARtmb3JFYWNoQXNzZXRDYWNoZVVzZXJSZXdhcmQCBWFjY3VtBWFzc2V0BA0kdDAxMDYxNzEwNzUyCQEKY2FsY1Jld2FyZAUFC3VzZXJBZGRyZXNzBQVhc3NldAUNc3Rha2VkQW1vdW50WAUOZGVwb3NpdE51bVVzZXIFDmRlcG9zaXROdW1MYXN0BAtyZXdhcmRUb3RhbAgFDSR0MDEwNjE3MTA3NTICXzEEBmNhY2hlZAgFDSR0MDEwNjE3MTA3NTICXzIEB2R5bmFtaWMIBQ0kdDAxMDYxNzEwNzUyAl8zBBNyZXdhcmRDYWNoZWRQYXJ0S0VZCAUNJHQwMTA2MTcxMDc1MgJfNAkAzQgCBQVhY2N1bQkBDEludGVnZXJFbnRyeQIFE3Jld2FyZENhY2hlZFBhcnRLRVkFC3Jld2FyZFRvdGFsAwMJAAACBQ5kZXBvc2l0TnVtTGFzdAD///////////8BCQAAAgUOZGVwb3NpdE51bVVzZXIA////////////AQcFA25pbAMDCQAAAgUOZGVwb3NpdE51bUxhc3QA////////////AQkAZgIFDmRlcG9zaXROdW1Vc2VyAP///////////wEHCQACAQIvaW52YWxpZCBkZXBvc2l0TnVtTGFzdCBhbmQgZGVwb3NpdE51bVVzZXIgc3RhdGUDAwkAZgIFDmRlcG9zaXROdW1MYXN0AP///////////wEJAGcCBQ5kZXBvc2l0TnVtVXNlcgD///////////8BBwMFCWlzTmV3VXNlcgkAzAgCCQEMSW50ZWdlckVudHJ5AgUbdXNlclJld2FyZEZyb21EZXBvc2l0TnVtS0VZBQ5kZXBvc2l0TnVtTGFzdAUDbmlsCQDNCAIKAAIkbAUTc3VwcG9ydGVkQXNzZXRzTGlzdAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEbZm9yRWFjaEFzc2V0Q2FjaGVVc2VyUmV3YXJkAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyAyCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgkBDEludGVnZXJFbnRyeQIFG3VzZXJSZXdhcmRGcm9tRGVwb3NpdE51bUtFWQUOZGVwb3NpdE51bUxhc3QJAAIBCQCsAgIJAKwCAgkArAICAiR1bmNvdmVyZWQgY29uZGl0aW9uOiBkZXBvc2l0TnVtTGFzdD0JAKQDAQUOZGVwb3NpdE51bUxhc3QCECBkZXBvc2l0TnVtVXNlcj0JAKQDAQUOZGVwb3NpdE51bVVzZXIBIkluY3JlbWVudE5vdERpc3RyaWJ1dGVkUmV3YXJkRW50cnkCA3RrbglhbW91bnRJbmMEF25vdERpc3RyaWJ1dGVkUmV3YXJkS0VZCQEXa2V5Tm90RGlzdHJpYnV0ZWRSZXdhcmQBBQN0a24EFG5vdERpc3RyaWJ1dGVkUmV3YXJkCQEMZ2V0SW50T3JFbHNlAgUXbm90RGlzdHJpYnV0ZWRSZXdhcmRLRVkAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgUXbm90RGlzdHJpYnV0ZWRSZXdhcmRLRVkJAGQCBRRub3REaXN0cmlidXRlZFJld2FyZAUJYW1vdW50SW5jBQNuaWwBCm1lcmdlU3Rha2UCC3VzZXJBZGRyZXNzC2Ftb3VudFRvQWRkBA0kdDAxMzU3NjEzNjkyCQELdmFsdWVPckVsc2UCCQETZ2V0VXNlclBhcmFtc09yVW5pdAEFC3VzZXJBZGRyZXNzCQCVCgMGAAAFBmhlaWdodAQJaXNOZXdVc2VyCAUNJHQwMTM1NzYxMzY5MgJfMQQMc3Rha2VkQW1vdW50CAUNJHQwMTM1NzYxMzY5MgJfMgQSc3Rha2luZ1N0YXJ0SGVpZ2h0CAUNJHQwMTM1NzYxMzY5MgJfMwQPc3Rha2VkQW1vdW50TkVXAwUJaXNOZXdVc2VyBQthbW91bnRUb0FkZAkAZAIFC2Ftb3VudFRvQWRkBQxzdGFrZWRBbW91bnQJAJYKBAUJaXNOZXdVc2VyBQxzdGFrZWRBbW91bnQFEnN0YWtpbmdTdGFydEhlaWdodAUPc3Rha2VkQW1vdW50TkVXAQtjb21tb25TdGFrZQILdXNlckFkZHJlc3MBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECFUludmFsaWQgcGF5bWVudHMgc2l6ZQQHcGF5bWVudAkAkQMCCAUBaQhwYXltZW50cwAABAZhbW91bnQIBQdwYXltZW50BmFtb3VudAQTaW52YWxpZEFzc2V0TWVzc2FnZQkArAICCQCsAgICD0ludmFsaWQgYXNzZXQuIAkA2AQBBQ1zdGFrZWRBc3NldElkAgwgaXMgZXhwZWN0ZWQEB2Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAggFB3BheW1lbnQHYXNzZXRJZAUTaW52YWxpZEFzc2V0TWVzc2FnZQMJAQIhPQIFB2Fzc2V0SWQFDXN0YWtlZEFzc2V0SWQJAAIBBRNpbnZhbGlkQXNzZXRNZXNzYWdlBA51c2VyQWRkcmVzc1N0cgkApQgBBQt1c2VyQWRkcmVzcwQKbWVyZ2VkRGF0YQkBCm1lcmdlU3Rha2UCBQ51c2VyQWRkcmVzc1N0cgUGYW1vdW50BAlpc05ld1VzZXIIBQptZXJnZWREYXRhAl8xBAxzdGFrZWRBbW91bnQIBQptZXJnZWREYXRhAl8yBBJzdGFraW5nU3RhcnRIZWlnaHQIBQptZXJnZWREYXRhAl8zBA9zdGFrZWRBbW91bnRORVcIBQptZXJnZWREYXRhAl80AwkAZgIFDW1pbkxvY2tBbW91bnQFD3N0YWtlZEFtb3VudE5FVwkAAgEJAKwCAgITTWluIGxvY2sgYW1vdW50IGlzIAkApAMBBQ1taW5Mb2NrQW1vdW50BA0kdDAxNDY2NTE0NzY3CQELU3RhdHNSZXN1bHQDBQZhbW91bnQAAQMFCWlzTmV3VXNlcgABAAAEDHN0YXRzRW50cmllcwgFDSR0MDE0NjY1MTQ3NjcCXzEEC3RvdGFsU3Rha2VkCAUNJHQwMTQ2NjUxNDc2NwJfMgQOdG90YWxTdGFrZWROZXcIBQ0kdDAxNDY2NTE0NzY3Al8zCQDOCAIJAM4IAgkAzggCCQDMCAIJARJIaXN0b3J5UmVjb3JkRW50cnkFAgVzdGFrZQUOdXNlckFkZHJlc3NTdHIIBQFpDXRyYW5zYWN0aW9uSWQFDHN0YWtlZEFtb3VudAUPc3Rha2VkQW1vdW50TkVXBQNuaWwJAQ1SZXdhcmRFbnRyaWVzAwUJaXNOZXdVc2VyBQ51c2VyQWRkcmVzc1N0cgUMc3Rha2VkQW1vdW50CQEPTG9ja1BhcmFtc0VudHJ5AwUOdXNlckFkZHJlc3NTdHIFD3N0YWtlZEFtb3VudE5FVwUSc3Rha2luZ1N0YXJ0SGVpZ2h0BQxzdGF0c0VudHJpZXMBDWNvbW1vblVuc3Rha2UCBmFtb3VudAFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIjdW5zdGFrZSBkb2Vzbid0IHJlcXVpcmUgYW55IHBheW1lbnQEC3VzZXJBZGRyZXNzCAUBaQZjYWxsZXIEDnVzZXJBZGRyZXNzU3RyCQClCAEFC3VzZXJBZGRyZXNzBA0kdDAxNTI0MjE1MzMwCQETZ2V0VXNlclBhcmFtc09yRmFpbAEFDnVzZXJBZGRyZXNzU3RyBAlpc05ld1VzZXIIBQ0kdDAxNTI0MjE1MzMwAl8xBAxzdGFrZWRBbW91bnQIBQ0kdDAxNTI0MjE1MzMwAl8yBBJzdGFraW5nU3RhcnRIZWlnaHQIBQ0kdDAxNTI0MjE1MzMwAl8zBBBzd2FwUGFyYW1zU1RSVUNUCQESYXNTd2FwUGFyYW1zU1RSVUNUAQkA/QcEBRBuZXV0cmlub0NvbnRyYWN0Ahtzd2FwUGFyYW1zQnlVc2VyU1lTUkVBRE9OTFkJAMwIAgUOdXNlckFkZHJlc3NTdHIJAMwIAgAABQNuaWwFA25pbAQUc3dhcExpbWl0U3BlbnRJblVzZG4IBRBzd2FwUGFyYW1zU1RSVUNUAl8yBA5ibGNrczJMbXRSZXNldAgFEHN3YXBQYXJhbXNTVFJVQ1QCXzMDCQBmAgUUc3dhcExpbWl0U3BlbnRJblVzZG4AAAkAAgEJAKwCAgkArAICAi1Zb3UgaGF2ZSBhbHJlYWR5IG1hZGUgYSBzd2FwIG9wZXJhdGlvbi4gV2FpdCAJAKQDAQkAZAIFBmhlaWdodAUOYmxja3MyTG10UmVzZXQCEiBoZWlnaHQgdG8gdW5zdGFrZQMJAGcCAAAFDHN0YWtlZEFtb3VudAkAAgECEk5vdGhpbmcgdG8gdW5zdGFrZQMJAGYCBQZhbW91bnQFDHN0YWtlZEFtb3VudAkAAgEJAKwCAgkArAICCQCsAgICClJlcXVlc3RlZCAJAKQDAQUGYW1vdW50AhIsIGJ1dCBzdGFrZWQgb25seSAJAKQDAQUMc3Rha2VkQW1vdW50BA9zdGFrZWRBbW91bnRORVcJAGUCBQxzdGFrZWRBbW91bnQFBmFtb3VudAQNJHQwMTU5NjgxNjEyNgkBC1N0YXRzUmVzdWx0AwkBAS0BBQZhbW91bnQDCQAAAgUGYW1vdW50BQxzdGFrZWRBbW91bnQA////////////AQAAAwkAAAIFBmFtb3VudAUMc3Rha2VkQW1vdW50AP///////////wEAAAQMc3RhdHNFbnRyaWVzCAUNJHQwMTU5NjgxNjEyNgJfMQQLdG90YWxTdGFrZWQIBQ0kdDAxNTk2ODE2MTI2Al8yBA50b3RhbFN0YWtlZE5ldwgFDSR0MDE1OTY4MTYxMjYCXzMJAM4IAgkAzggCCQDOCAIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwULdXNlckFkZHJlc3MFBmFtb3VudAUNc3Rha2VkQXNzZXRJZAkAzAgCCQESSGlzdG9yeVJlY29yZEVudHJ5BQIHdW5zdGFrZQUOdXNlckFkZHJlc3NTdHIIBQFpDXRyYW5zYWN0aW9uSWQFDHN0YWtlZEFtb3VudAUPc3Rha2VkQW1vdW50TkVXBQNuaWwJAQ1SZXdhcmRFbnRyaWVzAwcFDnVzZXJBZGRyZXNzU3RyBQxzdGFrZWRBbW91bnQJAQ9Mb2NrUGFyYW1zRW50cnkDBQ51c2VyQWRkcmVzc1N0cgUPc3Rha2VkQW1vdW50TkVXBRJzdGFraW5nU3RhcnRIZWlnaHQFDHN0YXRzRW50cmllcwELY29tbW9uQ2xhaW0CC3VzZXJBZGRyZXNzAWkEDnVzZXJBZGRyZXNzU3RyCQClCAEFC3VzZXJBZGRyZXNzAwkAZgIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECGXBheW1lbnRzIGFyZSBub3QgYWNjZXB0ZWQEDSR0MDE2NjIyMTY3MzAJAQt2YWx1ZU9yRWxzZQIJARNnZXRVc2VyUGFyYW1zT3JVbml0AQUOdXNlckFkZHJlc3NTdHIJAJUKAwYAAAAABAlpc05ld1VzZXIIBQ0kdDAxNjYyMjE2NzMwAl8xBAxzdGFrZWRBbW91bnQIBQ0kdDAxNjYyMjE2NzMwAl8yBAxzdGFraW5nU3RhcnQIBQ0kdDAxNjYyMjE2NzMwAl8zBA1zdGFrZWRBbW91bnRYCQC2AgEFDHN0YWtlZEFtb3VudAQbdXNlclJld2FyZEZyb21EZXBvc2l0TnVtS0VZCQEba2V5VXNlclJld2FyZEZyb21EZXBvc2l0TnVtAQUOdXNlckFkZHJlc3NTdHIEDmRlcG9zaXROdW1Vc2VyCQEMZ2V0SW50T3JFbHNlAgUbdXNlclJld2FyZEZyb21EZXBvc2l0TnVtS0VZAP///////////wEEDmRlcG9zaXROdW1MYXN0CQEMZ2V0SW50T3JFbHNlAgkBEWtleURlcG9zaXROdW1MYXN0AAD///////////8BCgEfZm9yRWFjaEFzc2V0Q2FsY1VuY2xhaW1lZFJld2FyZAIFYWNjdW0FYXNzZXQEDSR0MDE3MTAxMTcyMzkJAQpjYWxjUmV3YXJkBQUOdXNlckFkZHJlc3NTdHIFBWFzc2V0BQ1zdGFrZWRBbW91bnRYBQ5kZXBvc2l0TnVtVXNlcgUOZGVwb3NpdE51bUxhc3QEC3Jld2FyZFRvdGFsCAUNJHQwMTcxMDExNzIzOQJfMQQGY2FjaGVkCAUNJHQwMTcxMDExNzIzOQJfMgQHZHluYW1pYwgFDSR0MDE3MTAxMTcyMzkCXzMEE3Jld2FyZENhY2hlZFBhcnRLRVkIBQ0kdDAxNzEwMTE3MjM5Al80BApjbGFpbWVkS0VZCQEKa2V5Q2xhaW1lZAIFDnVzZXJBZGRyZXNzU3RyBQVhc3NldAQNJHQwMTcyOTkxNzMzNgUFYWNjdW0EBGRhdGEIBQ0kdDAxNzI5OTE3MzM2Al8xBBFjbGFpbWVkQW10QnlBc3NldAgFDSR0MDE3Mjk5MTczMzYCXzIEB25ld1BhcnQJALkJAgkAzAgCBQVhc3NldAkAzAgCCQCkAwEFC3Jld2FyZFRvdGFsBQNuaWwCAToEFGNsYWltZWRBbXRCeUFzc2V0TmV3CQC5CQIJAMwIAgURY2xhaW1lZEFtdEJ5QXNzZXQJAMwIAgUHbmV3UGFydAUDbmlsAgFfAwkAZwIAAAULcmV3YXJkVG90YWwJAJQKAgUEZGF0YQUUY2xhaW1lZEFtdEJ5QXNzZXROZXcJAJQKAgkAzQgCCQDNCAIJAM0IAgUEZGF0YQkBDlNjcmlwdFRyYW5zZmVyAwULdXNlckFkZHJlc3MFC3Jld2FyZFRvdGFsCQELdG9Bc3NldFZlY3QBBQVhc3NldAkBDEludGVnZXJFbnRyeQIFCmNsYWltZWRLRVkJAGQCCQELdmFsdWVPckVsc2UCCQCfCAEFCmNsYWltZWRLRVkAAAULcmV3YXJkVG90YWwJAQxJbnRlZ2VyRW50cnkCBRNyZXdhcmRDYWNoZWRQYXJ0S0VZAAAFFGNsYWltZWRBbXRCeUFzc2V0TmV3BA0kdDAxNzc5NjE3OTA5CgACJGwFE3N1cHBvcnRlZEFzc2V0c0xpc3QKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgIFA25pbAIACgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAR9mb3JFYWNoQXNzZXRDYWxjVW5jbGFpbWVkUmV3YXJkAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyAyCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgQJdHJhbnNmZXJzCAUNJHQwMTc3OTYxNzkwOQJfMQQXY2xhaW1lZEFtdEJ5QXNzZXRSZXN1bHQIBQ0kdDAxNzc5NjE3OTA5Al8yAwkAZwIAAAkAkAMBBQl0cmFuc2ZlcnMJAJQKAgUDbmlsAAAJAJQKAgkAzQgCCQDNCAIFCXRyYW5zZmVycwkBDEludGVnZXJFbnRyeQIFG3VzZXJSZXdhcmRGcm9tRGVwb3NpdE51bUtFWQUOZGVwb3NpdE51bUxhc3QJARFDbGFpbUhpc3RvcnlFbnRyeQMFDnVzZXJBZGRyZXNzU3RyCAUBaQ10cmFuc2FjdGlvbklkCQCwAgIFF2NsYWltZWRBbXRCeUFzc2V0UmVzdWx0AAEJAJADAQUJdHJhbnNmZXJzAAhVU0ROVFlQRQIEVVNETgAITlNCVFRZUEUCBE5TQlQAEk5ldXRyaW5vQXNzZXRJZEtleQIRbmV1dHJpbm9fYXNzZXRfaWQAE05ldXRyaW5vQ29udHJhY3RLZXkCEW5ldXRyaW5vX2NvbnRyYWN0AA5Oc2J0QXNzZXRJZEtleQINYm9uZF9hc3NldF9pZAAKQmFsYW5jZUtleQILcnBkX2JhbGFuY2UAD25ldXRyaW5vQXNzZXRJZAkA2QQBCQEPZ2V0U3RyaW5nT3JGYWlsAgUQbmV1dHJpbm9Db250cmFjdAUSTmV1dHJpbm9Bc3NldElkS2V5AA5uc2J0QXNzZXRJZFN0cgkBD2dldFN0cmluZ09yRmFpbAIFEG5ldXRyaW5vQ29udHJhY3QFDk5zYnRBc3NldElkS2V5AAtuc2J0QXNzZXRJZAkA2QQBBQ5uc2J0QXNzZXRJZFN0cgERZ2V0VXNlckJhbGFuY2VLZXkCBW93bmVyB2Fzc2V0SWQJALkJAgkAzAgCBQpCYWxhbmNlS2V5CQDMCAIFB2Fzc2V0SWQJAMwIAgUFb3duZXIFA25pbAIBXwEVZ2V0Q29udHJhY3RCYWxhbmNlS2V5AQdhc3NldElkCQCsAgIJAKwCAgUKQmFsYW5jZUtleQIBXwUHYXNzZXRJZAESZ2V0Q29udHJhY3RCYWxhbmNlAQdhc3NldElkCQEMZ2V0SW50T3JFbHNlAgkBFWdldENvbnRyYWN0QmFsYW5jZUtleQEFB2Fzc2V0SWQAAAEOZ2V0VXNlckJhbGFuY2UCBW93bmVyB2Fzc2V0SWQJAQxnZXRJbnRPckVsc2UCCQERZ2V0VXNlckJhbGFuY2VLZXkCBQVvd25lcgUHYXNzZXRJZAAAARpnZXRWYWxpZFN0YWtpbmdBc3NldE9yRmFpbAILc3Rha2luZ1R5cGUHYXNzZXRJZAMDCQAAAgULc3Rha2luZ1R5cGUFCFVTRE5UWVBFCQECIT0CBQdhc3NldElkBQ9uZXV0cmlub0Fzc2V0SWQHCQACAQIRY2FuIHVzZSBVU0ROIG9ubHkDAwkAAAIFC3N0YWtpbmdUeXBlBQhOU0JUVFlQRQkBAiE9AgUHYXNzZXRJZAULbnNidEFzc2V0SWQHCQACAQIRY2FuIHVzZSBOU0JUIG9ubHkDAwkBAiE9AgULc3Rha2luZ1R5cGUFCFVTRE5UWVBFCQECIT0CBQtzdGFraW5nVHlwZQUITlNCVFRZUEUHCQACAQkArAICAhl1bnN1cHBvcnRlZCBzdGFraW5nIHR5cGUgBQtzdGFraW5nVHlwZQUHYXNzZXRJZAEOaW50ZXJuYWxVbmxvY2sEC3N0YWtpbmdUeXBlAWkMdW5sb2NrQW1vdW50DGFzc2V0SWRQYXJhbQQHYWNjb3VudAkApQgBCAUBaQZjYWxsZXIEB2Fzc2V0SWQJARpnZXRWYWxpZFN0YWtpbmdBc3NldE9yRmFpbAIFC3N0YWtpbmdUeXBlCQDZBAEFDGFzc2V0SWRQYXJhbQQNYXNzZXRJZFN0cmluZwkA2AQBBQdhc3NldElkBAdiYWxhbmNlCQBlAgkBDmdldFVzZXJCYWxhbmNlAgUHYWNjb3VudAUNYXNzZXRJZFN0cmluZwUMdW5sb2NrQW1vdW50AwkAZgIAAAUHYmFsYW5jZQkAAgECDmludmFsaWQgYW1vdW50CQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIJARVnZXRDb250cmFjdEJhbGFuY2VLZXkBBQ1hc3NldElkU3RyaW5nCQBlAgkBEmdldENvbnRyYWN0QmFsYW5jZQEFDWFzc2V0SWRTdHJpbmcFDHVubG9ja0Ftb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBEWdldFVzZXJCYWxhbmNlS2V5AgUHYWNjb3VudAUNYXNzZXRJZFN0cmluZwUHYmFsYW5jZQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCQERQGV4dHJOYXRpdmUoMTA2MikBBQdhY2NvdW50BQx1bmxvY2tBbW91bnQFB2Fzc2V0SWQFA25pbAUEdW5pdA4BaQELY29uc3RydWN0b3IDDW1pbkxvY2tBbW91bnQVc3VwcG9ydGVkUmV3YXJkQXNzZXRzDnBTdGFrZWRBc3NldElkAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIRUGVybWlzc2lvbiBkZW5pZWQJAMwIAgkBDEludGVnZXJFbnRyeQIJARBrZXlNaW5Mb2NrQW1vdW50AAUNbWluTG9ja0Ftb3VudAkAzAgCCQELU3RyaW5nRW50cnkCCQEYa2V5U3VwcG9ydGVkUmV3YXJkQXNzZXRzAAUVc3VwcG9ydGVkUmV3YXJkQXNzZXRzCQDMCAIJAQtTdHJpbmdFbnRyeQIJARBrZXlTdGFrZWRBc3NldElkAAUOcFN0YWtlZEFzc2V0SWQFA25pbAFpAQVzdGFrZQAJAQtjb21tb25TdGFrZQIIBQFpBmNhbGxlcgUBaQFpARNzdGFrZUJ5T3JpZ2luQ2FsbGVyAAkBC2NvbW1vblN0YWtlAggFAWkMb3JpZ2luQ2FsbGVyBQFpAWkBB3Vuc3Rha2UBBmFtb3VudAkBDWNvbW1vblVuc3Rha2UCBQZhbW91bnQFAWkBaQEHZGVwb3NpdAADCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAh9leGFjdCAxIHBheW1lbnQgaXMgYWxsb3dlZCBvbmx5BANwbXQJAJEDAggFAWkIcGF5bWVudHMAAAQGYW1vdW50CAUDcG10BmFtb3VudAQKcG10QXNzZXRJZAkBC3ZhbHVlT3JFbHNlAggFA3BtdAdhc3NldElkBQdXQVZFU0lEBA1wbXRBc3NldElkU3RyCQDYBAEFCnBtdEFzc2V0SWQECHBtdE11bHRYAwkAAAIFCnBtdEFzc2V0SWQFB1dBVkVTSUQFBk1VTFRYOAUGTVVMVFg2BAdhbW91bnRYCQC2AgEFBmFtb3VudAQLdG90YWxTdGFrZWQJAQxnZXRJbnRPckVsc2UCCQEXa2V5TG9ja1BhcmFtVG90YWxBbW91bnQAAAAEDHRvdGFsU3Rha2VkWAkAtgIBBQt0b3RhbFN0YWtlZAMJAGYCAAAFC3RvdGFsU3Rha2VkCQACAQIbVE9ETzogY2FzZSBpcyBub3Qgc3VwcG9ydGVkAwkAAAIFC3RvdGFsU3Rha2VkAAAJASJJbmNyZW1lbnROb3REaXN0cmlidXRlZFJld2FyZEVudHJ5AgUNcG10QXNzZXRJZFN0cgUGYW1vdW50BBByZXdhcmRQZXJOc2J0WDE4CQC8AgMFB2Ftb3VudFgFB01VTFRYMTgFDHRvdGFsU3Rha2VkWAQRZGVwb3NpdE51bUxhc3RLRVkJARFrZXlEZXBvc2l0TnVtTGFzdAAEDmRlcG9zaXROdW1MYXN0CQEMZ2V0SW50T3JFbHNlAgURZGVwb3NpdE51bUxhc3RLRVkA////////////AQQNZGVwb3NpdE51bU5ldwkAZAIFDmRlcG9zaXROdW1MYXN0AAEDCQEBIQEJAQhjb250YWlucwIFEnN1cHBvcnRlZEFzc2V0c1N0cgUNcG10QXNzZXRJZFN0cgkAAgEJAKwCAgkArAICBRJzdXBwb3J0ZWRBc3NldHNTdHICESBkb2Vzbid0IGNvbnRhaW4gBQ1wbXRBc3NldElkU3RyCgEXcmVmcmVzaFJld2FyZFBlck5zYnRTVU0CBWFjY3VtCW5leHRBc3NldAQWcmV3YXJkUGVyTnNidFN1bU5ld0tFWQkBFWtleVJld2FyZFBlck5zYnRTdW1BdAIFDWRlcG9zaXROdW1OZXcFCW5leHRBc3NldAQKc3VtTGFzdFN0cgkBDGdldFN0ck9yRWxzZQIJARVrZXlSZXdhcmRQZXJOc2J0U3VtQXQCBQ5kZXBvc2l0TnVtTGFzdAUJbmV4dEFzc2V0AgEwCQDNCAIFBWFjY3VtAwkAAAIFCW5leHRBc3NldAUNcG10QXNzZXRJZFN0cgkBC1N0cmluZ0VudHJ5AgUWcmV3YXJkUGVyTnNidFN1bU5ld0tFWQkApgMBCQC3AgIJAKcDAQUKc3VtTGFzdFN0cgUQcmV3YXJkUGVyTnNidFgxOAkBC1N0cmluZ0VudHJ5AgUWcmV3YXJkUGVyTnNidFN1bU5ld0tFWQUKc3VtTGFzdFN0cgkAzggCCQDNCAIKAAIkbAUTc3VwcG9ydGVkQXNzZXRzTGlzdAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEXcmVmcmVzaFJld2FyZFBlck5zYnRTVU0CBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDIJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACCQEMSW50ZWdlckVudHJ5AgURZGVwb3NpdE51bUxhc3RLRVkFDWRlcG9zaXROdW1OZXcJARVEZXBvc2l0c1RvdGFsc0VudHJpZXMCBQZhbW91bnQFDXBtdEFzc2V0SWRTdHIBaQEMY2xhaW1SZXdhcmRzAAkBC2NvbW1vbkNsYWltAggFAWkGY2FsbGVyBQFpAWkBGmNsYWltUmV3YXJkc0J5T3JpZ2luQ2FsbGVyAAkBC2NvbW1vbkNsYWltAggFAWkMb3JpZ2luQ2FsbGVyBQFpAWkBGHVuY2xhaW1lZFJld2FyZHNSRUFET05MWQEOdXNlckFkZHJlc3NTdHIKARZmb3JFYWNoQXNzZXRaZXJvUmV3YXJkAgVhY2N1bQVhc3NldAkArAICCQCsAgIFBWFjY3VtCQC5CQIJAMwIAgUFYXNzZXQJAMwIAgIBMAkAzAgCAgEwBQNuaWwCAToCAV8EEnVuY2xhaW1lZFJld2FyZFN0cgMJAAACBQ51c2VyQWRkcmVzc1N0cgIACgACJGwFE3N1cHBvcnRlZEFzc2V0c0xpc3QKAAIkcwkAkAMBBQIkbAoABSRhY2MwAgAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBFmZvckVhY2hBc3NldFplcm9SZXdhcmQCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDIJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACBAt1c2VyQWRkcmVzcwkBEUBleHRyTmF0aXZlKDEwNjIpAQUOdXNlckFkZHJlc3NTdHIEDSR0MDIyOTY0MjMwNzgJAQt2YWx1ZU9yRWxzZQIJARNnZXRVc2VyUGFyYW1zT3JVbml0AQUOdXNlckFkZHJlc3NTdHIJAJUKAwYAAAAABAlpc05ld1VzZXIIBQ0kdDAyMjk2NDIzMDc4Al8xBAxzdGFrZWRBbW91bnQIBQ0kdDAyMjk2NDIzMDc4Al8yBBJzdGFraW5nU3RhcnRIZWlnaHQIBQ0kdDAyMjk2NDIzMDc4Al8zBA1zdGFrZWRBbW91bnRYCQC2AgEFDHN0YWtlZEFtb3VudAQbdXNlclJld2FyZEZyb21EZXBvc2l0TnVtS0VZCQEba2V5VXNlclJld2FyZEZyb21EZXBvc2l0TnVtAQUOdXNlckFkZHJlc3NTdHIEDmRlcG9zaXROdW1Vc2VyCQEMZ2V0SW50T3JFbHNlAgUbdXNlclJld2FyZEZyb21EZXBvc2l0TnVtS0VZAP///////////wEEDmRlcG9zaXROdW1MYXN0CQEMZ2V0SW50T3JFbHNlAgkBEWtleURlcG9zaXROdW1MYXN0AAD///////////8BCgEfZm9yRWFjaEFzc2V0Q2FsY1VuY2xhaW1lZFJld2FyZAIFYWNjdW0FYXNzZXQEDSR0MDIzNDI0MjM1NjIJAQpjYWxjUmV3YXJkBQUOdXNlckFkZHJlc3NTdHIFBWFzc2V0BQ1zdGFrZWRBbW91bnRYBQ5kZXBvc2l0TnVtVXNlcgUOZGVwb3NpdE51bUxhc3QEC3Jld2FyZFRvdGFsCAUNJHQwMjM0MjQyMzU2MgJfMQQGY2FjaGVkCAUNJHQwMjM0MjQyMzU2MgJfMgQHZHluYW1pYwgFDSR0MDIzNDI0MjM1NjICXzMEE3Jld2FyZENhY2hlZFBhcnRLRVkIBQ0kdDAyMzQyNDIzNTYyAl80BAdjbGFpbWVkCQELdmFsdWVPckVsc2UCCQCfCAEJAQprZXlDbGFpbWVkAgUOdXNlckFkZHJlc3NTdHIFBWFzc2V0AAAJAKwCAgkArAICBQVhY2N1bQkAuQkCCQDMCAIFBWFzc2V0CQDMCAIJAKQDAQULcmV3YXJkVG90YWwJAMwIAgkApAMBBQdjbGFpbWVkBQNuaWwCAToCAV8KAAIkbAUTc3VwcG9ydGVkQXNzZXRzTGlzdAoAAiRzCQCQAwEFAiRsCgAFJGFjYzACAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEfZm9yRWFjaEFzc2V0Q2FsY1VuY2xhaW1lZFJld2FyZAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgMgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIJAJQKAgUDbmlsCQCzAgIFEnVuY2xhaW1lZFJld2FyZFN0cgABAWkBFnVzZG5TdGFraW5nU1lTUkVBRE9OTFkCFXVzZXJBZGRyZXNzU3RyT3JFbXB0eQh1c2RuRGlmZgQSdXNkblRvdGFsQW10U3Rha2VkCQEMZ2V0SW50T3JFbHNlAgkBF2tleUxvY2tQYXJhbVRvdGFsQW1vdW50AAAAAwkAAAIFFXVzZXJBZGRyZXNzU3RyT3JFbXB0eQIACQCUCgIFA25pbAkAzAgCAAAJAMwIAgUSdXNkblRvdGFsQW10U3Rha2VkCQDMCAIAAAUDbmlsBAt1c2VyQWRkcmVzcwkBD3RvQWRkcmVzc09yRmFpbAEFFXVzZXJBZGRyZXNzU3RyT3JFbXB0eQQKbWVyZ2VkRGF0YQkBCm1lcmdlU3Rha2UCBRV1c2VyQWRkcmVzc1N0ck9yRW1wdHkFCHVzZG5EaWZmBAlpc05ld1VzZXIIBQptZXJnZWREYXRhAl8xBBB1c2RuU3Rha2VkQnlVc2VyCAUKbWVyZ2VkRGF0YQJfMgQSc3Rha2luZ1N0YXJ0SGVpZ2h0CAUKbWVyZ2VkRGF0YQJfMwQPc3Rha2VkQW1vdW50TkVXCAUKbWVyZ2VkRGF0YQJfNAkAlAoCBQNuaWwJAMwIAgUQdXNkblN0YWtlZEJ5VXNlcgkAzAgCBRJ1c2RuVG90YWxBbXRTdGFrZWQFA25pbAFpARFjb25maWdTWVNSRUFET05MWQAECm1pbkxvY2tBbXQJARFAZXh0ck5hdGl2ZSgxMDU1KQEJARBrZXlNaW5Mb2NrQW1vdW50AAkAlAoCBQNuaWwJAMwIAgUKbWluTG9ja0FtdAUDbmlsAWkBDmxvY2tOZXV0cmlub1NQAghyZWNlaXZlcgVzaGFyZQkBC2NvbW1vblN0YWtlAggFAWkGY2FsbGVyBQFpAWkBDGxvY2tOZXV0cmlubwAJAQtjb21tb25TdGFrZQIIBQFpBmNhbGxlcgUBaQFpAQ51bmxvY2tOZXV0cmlubwIMdW5sb2NrQW1vdW50DWFzc2V0SWRTdHJpbmcJAQ1jb21tb25VbnN0YWtlAgUMdW5sb2NrQW1vdW50BQFpAWkBCnVubG9ja05zYnQCDHVubG9ja0Ftb3VudA1hc3NldElkU3RyaW5nCQEOaW50ZXJuYWxVbmxvY2sEBQhOU0JUVFlQRQUBaQUMdW5sb2NrQW1vdW50BQ1hc3NldElkU3RyaW5nAQJ0eAEGdmVyaWZ5AAQTcHViS2V5QWRtaW5zTGlzdFN0cgkAuQkCCQDMCAICLEV4dEVFSzE5bm1LajltQ3BuV3l2RUVKRllBVExNY1ZFTXZvaGhVSGt5SE5tCQDMCAICLEV2NXB5NUZmQlFYOWNacFlLbmZRclRCNDlCeWY4UW1wWldlRFZSaW00eVY3CQDMCAICLERVdXVMalh1OThuQndaYzdmcXdDVGp0QTNublJ3Z1Ria01TcjVTVTJObURSCQDMCAICLERVdXVMalh1OThuQndaYzdmcXdDVGp0QTNublJ3Z1Ria01TcjVTVTJObURSBQNuaWwFA1NFUAQQcHViS2V5QWRtaW5zTGlzdAkAtQkCCQELdmFsdWVPckVsc2UCCQCdCAIFD2NvbnRyb2xDb250cmFjdAIMJXNfX211bHRpc2lnBRNwdWJLZXlBZG1pbnNMaXN0U3RyBQNTRVAEBWNvdW50CQBkAgkAZAIJAGQCAwkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAkA2QQBCQCRAwIFEHB1YktleUFkbWluc0xpc3QAAAABAAADCQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwABCQDZBAEJAJEDAgUQcHViS2V5QWRtaW5zTGlzdAABAAEAAAMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAIJANkEAQkAkQMCBRBwdWJLZXlBZG1pbnNMaXN0AAIAAQAAAwkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAwkA2QQBCQCRAwIFEHB1YktleUFkbWluc0xpc3QAAwACAAAJAGcCBQVjb3VudAADMc5tbQ==", "chainId": 84, "height": 2279208, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: BAk3WBRB9ftqvAH6Qc357RPUTfCsoc2U7DRSgtvLWXb9 Next: 3i4Kd15QJzxL6YABmmnBDfiTnp1dsrickaUysfZBDjAg Diff:
OldNewDifferences
9191
9292 let supportedAssetsList = split(supportedAssetsStr, "_")
9393
94-func keyLockParamUserAmount (userAddress) = makeString(["%s%s%s", "paramByUser", toString(userAddress), "amount"], SEP)
94+func keyLockParamUserAmount (userAddress) = makeString(["%s%s%s", "paramByUser", userAddress, "amount"], SEP)
9595
9696
97-func keyLockParamStartBlock (userAddress) = makeString(["%s%s%s", "paramByUser", toString(userAddress), "start"], SEP)
97+func keyLockParamStartBlock (userAddress) = makeString(["%s%s%s", "paramByUser", userAddress, "start"], SEP)
9898
9999
100100 func keyHistoryRecord (type,userAddress,txId) = makeString(["%s%s%s%s", "history", type, userAddress, toBase58String(txId)], SEP)
196196 }
197197
198198
199-func LockParamsEntry (userAddress,amount,stakingStartHeight) = [IntegerEntry(keyLockParamUserAmount(userAddress), amount), IntegerEntry(keyLockParamStartBlock(userAddress), stakingStartHeight)]
199+func LockParamsEntry (userAddress,amount,stakingStartHeight) = [IntegerEntry(keyLegacyUserBalance(userAddress, stakedAssetIdStr), amount), IntegerEntry(keyLockParamUserAmount(userAddress), amount), IntegerEntry(keyLockParamStartBlock(userAddress), stakingStartHeight)]
200200
201201
202202 func getParamsOrFail () = $Tuple2(fromBase58String(getStringOrFail(this, keyStakedAssetId())), getIntOrFail(keyMinLockAmount()))
210210 else unit
211211
212212
213-func getUserParamsOrFail (userAddress) = valueOrErrorMessage(getUserParamsOrUnit(userAddress), (("User " + toString(userAddress)) + " is not defined"))
213+func getUserParamsOrFail (userAddress) = valueOrErrorMessage(getUserParamsOrUnit(userAddress), (("User " + userAddress) + " is not defined"))
214214
215215
216216 func calcReward (userAddress,assetId,stakedAmountX,depositNumUser,depositNumLast) = {
268268 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
269269 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
270270 func forEachAssetCacheUserReward (accum,asset) = {
271- let $t01057810713 = calcReward(userAddress, asset, stakedAmountX, depositNumUser, depositNumLast)
272- let rewardTotal = $t01057810713._1
273- let cached = $t01057810713._2
274- let dynamic = $t01057810713._3
275- let rewardCachedPartKEY = $t01057810713._4
271+ let $t01061710752 = calcReward(userAddress, asset, stakedAmountX, depositNumUser, depositNumLast)
272+ let rewardTotal = $t01061710752._1
273+ let cached = $t01061710752._2
274+ let dynamic = $t01061710752._3
275+ let rewardCachedPartKEY = $t01061710752._4
276276 (accum :+ IntegerEntry(rewardCachedPartKEY, rewardTotal))
277277 }
278278
315315
316316
317317 func mergeStake (userAddress,amountToAdd) = {
318- let $t01353813654 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, height))
319- let isNewUser = $t01353813654._1
320- let stakedAmount = $t01353813654._2
321- let stakingStartHeight = $t01353813654._3
318+ let $t01357613692 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, height))
319+ let isNewUser = $t01357613692._1
320+ let stakedAmount = $t01357613692._2
321+ let stakingStartHeight = $t01357613692._3
322322 let stakedAmountNEW = if (isNewUser)
323323 then amountToAdd
324324 else (amountToAdd + stakedAmount)
337337 then throw(invalidAssetMessage)
338338 else {
339339 let userAddressStr = toString(userAddress)
340- let mergedData = mergeStake(userAddress, amount)
340+ let mergedData = mergeStake(userAddressStr, amount)
341341 let isNewUser = mergedData._1
342342 let stakedAmount = mergedData._2
343343 let stakingStartHeight = mergedData._3
345345 if ((minLockAmount > stakedAmountNEW))
346346 then throw(("Min lock amount is " + toString(minLockAmount)))
347347 else {
348- let $t01462414726 = StatsResult(amount, 1, if (isNewUser)
348+ let $t01466514767 = StatsResult(amount, 1, if (isNewUser)
349349 then 1
350350 else 0)
351- let statsEntries = $t01462414726._1
352- let totalStaked = $t01462414726._2
353- let totalStakedNew = $t01462414726._3
354- ((([HistoryRecordEntry("stake", userAddressStr, i.transactionId, stakedAmount, stakedAmountNEW)] ++ RewardEntries(isNewUser, userAddressStr, stakedAmount)) ++ LockParamsEntry(userAddress, stakedAmountNEW, stakingStartHeight)) ++ statsEntries)
351+ let statsEntries = $t01466514767._1
352+ let totalStaked = $t01466514767._2
353+ let totalStakedNew = $t01466514767._3
354+ ((([HistoryRecordEntry("stake", userAddressStr, i.transactionId, stakedAmount, stakedAmountNEW)] ++ RewardEntries(isNewUser, userAddressStr, stakedAmount)) ++ LockParamsEntry(userAddressStr, stakedAmountNEW, stakingStartHeight)) ++ statsEntries)
355355 }
356356 }
357357 }
362362 else {
363363 let userAddress = i.caller
364364 let userAddressStr = toString(userAddress)
365- let $t01519815283 = getUserParamsOrFail(userAddress)
366- let isNewUser = $t01519815283._1
367- let stakedAmount = $t01519815283._2
368- let stakingStartHeight = $t01519815283._3
365+ let $t01524215330 = getUserParamsOrFail(userAddressStr)
366+ let isNewUser = $t01524215330._1
367+ let stakedAmount = $t01524215330._2
368+ let stakingStartHeight = $t01524215330._3
369369 let swapParamsSTRUCT = asSwapParamsSTRUCT(reentrantInvoke(neutrinoContract, "swapParamsByUserSYSREADONLY", [userAddressStr, 0], nil))
370370 let swapLimitSpentInUsdn = swapParamsSTRUCT._2
371371 let blcks2LmtReset = swapParamsSTRUCT._3
377377 then throw(((("Requested " + toString(amount)) + ", but staked only ") + toString(stakedAmount)))
378378 else {
379379 let stakedAmountNEW = (stakedAmount - amount)
380- let $t01592116079 = StatsResult(-(amount), if ((amount == stakedAmount))
380+ let $t01596816126 = StatsResult(-(amount), if ((amount == stakedAmount))
381381 then -1
382382 else 0, if ((amount == stakedAmount))
383383 then -1
384384 else 0)
385- let statsEntries = $t01592116079._1
386- let totalStaked = $t01592116079._2
387- let totalStakedNew = $t01592116079._3
388- ((([ScriptTransfer(userAddress, amount, stakedAssetId), HistoryRecordEntry("unstake", userAddressStr, i.transactionId, stakedAmount, stakedAmountNEW)] ++ RewardEntries(false, userAddressStr, stakedAmount)) ++ LockParamsEntry(userAddress, stakedAmountNEW, stakingStartHeight)) ++ statsEntries)
385+ let statsEntries = $t01596816126._1
386+ let totalStaked = $t01596816126._2
387+ let totalStakedNew = $t01596816126._3
388+ ((([ScriptTransfer(userAddress, amount, stakedAssetId), HistoryRecordEntry("unstake", userAddressStr, i.transactionId, stakedAmount, stakedAmountNEW)] ++ RewardEntries(false, userAddressStr, stakedAmount)) ++ LockParamsEntry(userAddressStr, stakedAmountNEW, stakingStartHeight)) ++ statsEntries)
389389 }
390390 }
391391
395395 if ((size(i.payments) > 0))
396396 then throw("payments are not accepted")
397397 else {
398- let $t01657216677 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
399- let isNewUser = $t01657216677._1
400- let stakedAmount = $t01657216677._2
401- let stakingStart = $t01657216677._3
398+ let $t01662216730 = valueOrElse(getUserParamsOrUnit(userAddressStr), $Tuple3(true, 0, 0))
399+ let isNewUser = $t01662216730._1
400+ let stakedAmount = $t01662216730._2
401+ let stakingStart = $t01662216730._3
402402 let stakedAmountX = toBigInt(stakedAmount)
403403 let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddressStr)
404404 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
405405 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
406406 func forEachAssetCalcUnclaimedReward (accum,asset) = {
407- let $t01704817186 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
408- let rewardTotal = $t01704817186._1
409- let cached = $t01704817186._2
410- let dynamic = $t01704817186._3
411- let rewardCachedPartKEY = $t01704817186._4
407+ let $t01710117239 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
408+ let rewardTotal = $t01710117239._1
409+ let cached = $t01710117239._2
410+ let dynamic = $t01710117239._3
411+ let rewardCachedPartKEY = $t01710117239._4
412412 let claimedKEY = keyClaimed(userAddressStr, asset)
413- let $t01724617283 = accum
414- let data = $t01724617283._1
415- let claimedAmtByAsset = $t01724617283._2
413+ let $t01729917336 = accum
414+ let data = $t01729917336._1
415+ let claimedAmtByAsset = $t01729917336._2
416416 let newPart = makeString([asset, toString(rewardTotal)], ":")
417417 let claimedAmtByAssetNew = makeString([claimedAmtByAsset, newPart], "_")
418418 if ((0 >= rewardTotal))
420420 else $Tuple2((((data :+ ScriptTransfer(userAddress, rewardTotal, toAssetVect(asset))) :+ IntegerEntry(claimedKEY, (valueOrElse(getInteger(claimedKEY), 0) + rewardTotal))) :+ IntegerEntry(rewardCachedPartKEY, 0)), claimedAmtByAssetNew)
421421 }
422422
423- let $t01774317856 = {
423+ let $t01779617909 = {
424424 let $l = supportedAssetsList
425425 let $s = size($l)
426426 let $acc0 = $Tuple2(nil, "")
434434
435435 $f0_2($f0_1($f0_1($acc0, 0), 1), 2)
436436 }
437- let transfers = $t01774317856._1
438- let claimedAmtByAssetResult = $t01774317856._2
437+ let transfers = $t01779617909._1
438+ let claimedAmtByAssetResult = $t01779617909._2
439439 if ((0 >= size(transfers)))
440440 then $Tuple2(nil, 0)
441441 else $Tuple2(((transfers :+ IntegerEntry(userRewardFromDepositNumKEY, depositNumLast)) :+ ClaimHistoryEntry(userAddressStr, i.transactionId, drop(claimedAmtByAssetResult, 1))), size(transfers))
606606 }
607607 else {
608608 let userAddress = addressFromStringValue(userAddressStr)
609- let $t02291123022 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
610- let isNewUser = $t02291123022._1
611- let stakedAmount = $t02291123022._2
612- let stakingStartHeight = $t02291123022._3
609+ let $t02296423078 = valueOrElse(getUserParamsOrUnit(userAddressStr), $Tuple3(true, 0, 0))
610+ let isNewUser = $t02296423078._1
611+ let stakedAmount = $t02296423078._2
612+ let stakingStartHeight = $t02296423078._3
613613 let stakedAmountX = toBigInt(stakedAmount)
614614 let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddressStr)
615615 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
616616 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
617617 func forEachAssetCalcUnclaimedReward (accum,asset) = {
618- let $t02336823506 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
619- let rewardTotal = $t02336823506._1
620- let cached = $t02336823506._2
621- let dynamic = $t02336823506._3
622- let rewardCachedPartKEY = $t02336823506._4
618+ let $t02342423562 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
619+ let rewardTotal = $t02342423562._1
620+ let cached = $t02342423562._2
621+ let dynamic = $t02342423562._3
622+ let rewardCachedPartKEY = $t02342423562._4
623623 let claimed = valueOrElse(getInteger(keyClaimed(userAddressStr, asset)), 0)
624624 ((accum + makeString([asset, toString(rewardTotal), toString(claimed)], ":")) + "_")
625625 }
649649 then $Tuple2(nil, [0, usdnTotalAmtStaked, 0])
650650 else {
651651 let userAddress = toAddressOrFail(userAddressStrOrEmpty)
652- let mergedData = mergeStake(userAddress, usdnDiff)
652+ let mergedData = mergeStake(userAddressStrOrEmpty, usdnDiff)
653653 let isNewUser = mergedData._1
654654 let usdnStakedByUser = mergedData._2
655655 let stakingStartHeight = mergedData._3
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let SEP = "__"
55
66 let MULT6 = 1000000
77
88 let MULT8 = 100000000
99
1010 let MULTX6 = toBigInt(MULT6)
1111
1212 let MULTX8 = toBigInt(MULT8)
1313
1414 let MULTX18 = toBigInt(1000000000000000000)
1515
1616 let WAVESIDSTR = "WAVES"
1717
1818 let WAVESID = fromBase58String(WAVESIDSTR)
1919
2020 let DAYMILLIS = 86400000
2121
2222 let IdxControlCfgNeutrinoDapp = 1
2323
2424 let IdxControlCfgAuctionDapp = 2
2525
2626 let IdxControlCfgRpdDapp = 3
2727
2828 let IdxControlCfgMathDapp = 4
2929
3030 let IdxControlCfgLiquidationDapp = 5
3131
3232 let IdxControlCfgRestDapp = 6
3333
3434 let IdxControlCfgNodeRegistryDapp = 7
3535
3636 let IdxControlCfgNsbtStakingDapp = 8
3737
3838 let IdxControlCfgMediatorDapp = 9
3939
4040 let IdxControlCfgSurfStakingDapp = 10
4141
4242 let IdxControlCfgGnsbtControllerDapp = 11
4343
4444 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), (((("mandatory " + toString(address)) + ".") + key) + " is not defined"))
4545
4646
4747 func getIntOrFail (key) = valueOrErrorMessage(getInteger(this, key), (("Mandatory this." + key) + " is not defined"))
4848
4949
5050 func getStrOrElse (key,defaultVal) = valueOrElse(getString(this, key), defaultVal)
5151
5252
5353 func keyMinLockAmount () = "%s__minLockAmount"
5454
5555
5656 func keyStakedAssetId () = "%s__stakedAssetId"
5757
5858
5959 func keyControlAddress () = "%s%s__config__controlAddress"
6060
6161
6262 func keyControlCfg () = "%s__controlConfig"
6363
6464
6565 func keySupportedRewardAssets () = "supportedRewardAssets"
6666
6767
6868 func readControlCfgOrFail (control) = split_4C(getStringOrFail(control, keyControlCfg()), SEP)
6969
7070
7171 func getContractAddressOrFail (controlCfg,idx) = valueOrErrorMessage(addressFromString(controlCfg[idx]), ("Control cfg doesn't contain address at index " + toString(idx)))
7272
7373
7474 let controlContract = addressFromStringValue(valueOrElse(getString(this, keyControlAddress()), "3N4NS7d4Jo9a6F14LiFUKKYVdUkkf2eP4Zx"))
7575
7676 let controlCfg = readControlCfgOrFail(controlContract)
7777
7878 let mathContract = getContractAddressOrFail(controlCfg, IdxControlCfgMathDapp)
7979
8080 let neutrinoContract = getContractAddressOrFail(controlCfg, IdxControlCfgNeutrinoDapp)
8181
8282 let auctionContract = getContractAddressOrFail(controlCfg, IdxControlCfgAuctionDapp)
8383
8484 let stakedAssetIdStr = getStringOrFail(this, keyStakedAssetId())
8585
8686 let stakedAssetId = fromBase58String(stakedAssetIdStr)
8787
8888 let minLockAmount = getIntOrFail(keyMinLockAmount())
8989
9090 let supportedAssetsStr = getStrOrElse(keySupportedRewardAssets(), "")
9191
9292 let supportedAssetsList = split(supportedAssetsStr, "_")
9393
94-func keyLockParamUserAmount (userAddress) = makeString(["%s%s%s", "paramByUser", toString(userAddress), "amount"], SEP)
94+func keyLockParamUserAmount (userAddress) = makeString(["%s%s%s", "paramByUser", userAddress, "amount"], SEP)
9595
9696
97-func keyLockParamStartBlock (userAddress) = makeString(["%s%s%s", "paramByUser", toString(userAddress), "start"], SEP)
97+func keyLockParamStartBlock (userAddress) = makeString(["%s%s%s", "paramByUser", userAddress, "start"], SEP)
9898
9999
100100 func keyHistoryRecord (type,userAddress,txId) = makeString(["%s%s%s%s", "history", type, userAddress, toBase58String(txId)], SEP)
101101
102102
103103 func keyLockParamTotalAmount () = makeString(["%s%s", "stats", "activeTotalLocked"], SEP)
104104
105105
106106 func keyStatsLocksCount () = makeString(["%s%s", "stats", "locksCount"], SEP)
107107
108108
109109 func keyStatsUsersCount () = makeString(["%s%s", "stats", "activeUsersCount"], SEP)
110110
111111
112112 func keyStatsDepositAmtByDay (timestamp) = makeString(["%s%s%d", "stats", "depositAmtByDay", toString(timestamp)], SEP)
113113
114114
115115 func keyStatsDepositAmtTotals () = makeString(["%s%s%d", "stats", "depositAmtTotals"], SEP)
116116
117117
118118 func keyNextPeriod () = "%s__nextPeriod"
119119
120120
121121 func keyDepositNumLast () = makeString(["%s%s%s", "dep", "lastNum"], SEP)
122122
123123
124124 func keyUserRewardFromDepositNum (userAddress) = makeString(["%s%s%s", "userRwdFromDepNum", userAddress], SEP)
125125
126126
127127 func keyRewardPerNsbtSumAt (depositNum,tkn) = makeString(["%s%d", "rwdPerNsbtSumByDepNum", toString(depositNum), tkn], SEP)
128128
129129
130130 func keyReward (userAddress,tkn) = makeString(["%s%s%s", "rwd", userAddress, tkn], SEP)
131131
132132
133133 func keyClaimed (userAddress,tkn) = makeString(["%s%s%s", "clm", userAddress, tkn], SEP)
134134
135135
136136 func keyNotDistributedReward (tkn) = makeString(["%s%s", "notDistributed", tkn], SEP)
137137
138138
139139 func keyLegacyUserBalance (userAddr,tkn) = makeString(["rpd_balance", tkn, userAddr], SEP)
140140
141141
142142 func keyLegacyTotalBalance (tkn) = makeString(["rpd_balance", tkn], SEP)
143143
144144
145145 func toX18 (origVal,origMult) = fraction(toBigInt(origVal), MULTX18, origMult)
146146
147147
148148 func getIntOrZero (key) = valueOrElse(getInteger(this, key), 0)
149149
150150
151151 func getIntOrElse (key,defaultVal) = valueOrElse(getInteger(this, key), defaultVal)
152152
153153
154154 func toAddressOrFail (addressStr) = valueOrErrorMessage(addressFromString(addressStr), ("couldn't parse passed addressStr=" + addressStr))
155155
156156
157157 func toAssetVect (assetStr) = if ((assetStr == WAVESIDSTR))
158158 then unit
159159 else fromBase58String(assetStr)
160160
161161
162162 func asInt (val) = match val {
163163 case valInt: Int =>
164164 valInt
165165 case _ =>
166166 throw("fail to cast into Int")
167167 }
168168
169169
170170 func asSwapParamsSTRUCT (v) = match v {
171171 case struct: (Int, Int, Int, Int, Int, Int, Int) =>
172172 struct
173173 case _ =>
174174 throw("fail to cast into Int")
175175 }
176176
177177
178178 func formatHistoryRecord (userAddress,oldAmount,newAmount) = makeString(["%s%d%d%d%d", userAddress, toString(lastBlock.height), toString(lastBlock.timestamp), toString(oldAmount), toString(newAmount)], SEP)
179179
180180
181181 func formatClaimHistoryRecord (userAddress,claimedRewards) = makeString(["%s%d%d%s", userAddress, toString(lastBlock.height), toString(lastBlock.timestamp), claimedRewards], SEP)
182182
183183
184184 func HistoryRecordEntry (type,userAddress,txId,oldAmount,newAmount) = StringEntry(keyHistoryRecord(type, userAddress, txId), formatHistoryRecord(userAddress, oldAmount, newAmount))
185185
186186
187187 func ClaimHistoryEntry (userAddress,txId,claimedRewards) = StringEntry(keyHistoryRecord("claim", userAddress, txId), formatClaimHistoryRecord(userAddress, claimedRewards))
188188
189189
190190 func StatsResult (totalLockedInc,lockCountInc,usersCountInc) = {
191191 let locksCount = getIntOrZero(keyStatsLocksCount())
192192 let usersCount = getIntOrZero(keyStatsUsersCount())
193193 let totalAmount = getIntOrZero(keyLockParamTotalAmount())
194194 let totalAmountNew = (totalAmount + totalLockedInc)
195195 $Tuple3([IntegerEntry(keyStatsLocksCount(), (locksCount + lockCountInc)), IntegerEntry(keyStatsUsersCount(), (usersCount + usersCountInc)), IntegerEntry(keyLockParamTotalAmount(), totalAmountNew), IntegerEntry(keyLegacyTotalBalance(stakedAssetIdStr), totalAmountNew)], totalAmount, totalAmountNew)
196196 }
197197
198198
199-func LockParamsEntry (userAddress,amount,stakingStartHeight) = [IntegerEntry(keyLockParamUserAmount(userAddress), amount), IntegerEntry(keyLockParamStartBlock(userAddress), stakingStartHeight)]
199+func LockParamsEntry (userAddress,amount,stakingStartHeight) = [IntegerEntry(keyLegacyUserBalance(userAddress, stakedAssetIdStr), amount), IntegerEntry(keyLockParamUserAmount(userAddress), amount), IntegerEntry(keyLockParamStartBlock(userAddress), stakingStartHeight)]
200200
201201
202202 func getParamsOrFail () = $Tuple2(fromBase58String(getStringOrFail(this, keyStakedAssetId())), getIntOrFail(keyMinLockAmount()))
203203
204204
205205 func isActiveUser (userAddress) = (getIntOrElse(keyLockParamUserAmount(userAddress), 0) > 0)
206206
207207
208208 func getUserParamsOrUnit (userAddress) = if (isActiveUser(userAddress))
209209 then $Tuple3(false, getIntOrFail(keyLockParamUserAmount(userAddress)), getIntOrFail(keyLockParamStartBlock(userAddress)))
210210 else unit
211211
212212
213-func getUserParamsOrFail (userAddress) = valueOrErrorMessage(getUserParamsOrUnit(userAddress), (("User " + toString(userAddress)) + " is not defined"))
213+func getUserParamsOrFail (userAddress) = valueOrErrorMessage(getUserParamsOrUnit(userAddress), (("User " + userAddress) + " is not defined"))
214214
215215
216216 func calcReward (userAddress,assetId,stakedAmountX,depositNumUser,depositNumLast) = {
217217 let rewardPerNsbtSumLastKEY = keyRewardPerNsbtSumAt(depositNumLast, assetId)
218218 let sumLastX18 = parseBigIntValue(getStrOrElse(keyRewardPerNsbtSumAt(depositNumLast, assetId), "0"))
219219 let sumUserX18 = parseBigIntValue(getStrOrElse(keyRewardPerNsbtSumAt(depositNumUser, assetId), "0"))
220220 let rewardDynamicPart = toInt(fraction((sumLastX18 - sumUserX18), stakedAmountX, MULTX18))
221221 let rewardCachedPartKEY = keyReward(userAddress, assetId)
222222 let rewardCachedPart = getIntOrElse(rewardCachedPartKEY, 0)
223223 $Tuple4((rewardCachedPart + rewardDynamicPart), rewardCachedPart, rewardDynamicPart, rewardCachedPartKEY)
224224 }
225225
226226
227227 func toStartOfDay (timestamp) = ((timestamp / DAYMILLIS) * DAYMILLIS)
228228
229229
230230 func findElementPosition (src,element,sep) = {
231231 let elementStart = valueOrErrorMessage(indexOf(src, element), ((("there is no substring " + element) + " in ") + src))
232232 if ((elementStart == 0))
233233 then 0
234234 else {
235235 let left = take(src, elementStart)
236236 (size(split(left, sep)) - 1)
237237 }
238238 }
239239
240240
241241 let DepositTotalsPREFIX = "%d%d"
242242
243243 func updateDepositTotals (currVal,idxToUpdate,deltaAmt) = {
244244 let currArr = split(currVal, SEP)
245245 func updDepTotByIdx (idx) = if ((idx != idxToUpdate))
246246 then currArr[idx]
247247 else toString((parseIntValue(currArr[idx]) + deltaAmt))
248248
249249 makeString([DepositTotalsPREFIX, updDepTotByIdx(1), updDepTotByIdx(2)], SEP)
250250 }
251251
252252
253253 func DepositsTotalsEntries (depositAmount,assetIdStr) = {
254254 let startOfDay = toStartOfDay(lastBlock.timestamp)
255255 let byDayKEY = keyStatsDepositAmtByDay(startOfDay)
256256 let totalsKEY = keyStatsDepositAmtTotals()
257257 let position = findElementPosition(supportedAssetsStr, assetIdStr, "_")
258258 let defaultDATA = (DepositTotalsPREFIX + "__0__0")
259259 let currTotalsDATA = valueOrElse(getString(this, totalsKEY), defaultDATA)
260260 let newTotalsDATA = updateDepositTotals(currTotalsDATA, (position + 1), depositAmount)
261261 [StringEntry(totalsKEY, newTotalsDATA), StringEntry(byDayKEY, newTotalsDATA)]
262262 }
263263
264264
265265 func RewardEntries (isNewUser,userAddress,stakedAmount) = {
266266 let stakedAmountX = toBigInt(stakedAmount)
267267 let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddress)
268268 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
269269 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
270270 func forEachAssetCacheUserReward (accum,asset) = {
271- let $t01057810713 = calcReward(userAddress, asset, stakedAmountX, depositNumUser, depositNumLast)
272- let rewardTotal = $t01057810713._1
273- let cached = $t01057810713._2
274- let dynamic = $t01057810713._3
275- let rewardCachedPartKEY = $t01057810713._4
271+ let $t01061710752 = calcReward(userAddress, asset, stakedAmountX, depositNumUser, depositNumLast)
272+ let rewardTotal = $t01061710752._1
273+ let cached = $t01061710752._2
274+ let dynamic = $t01061710752._3
275+ let rewardCachedPartKEY = $t01061710752._4
276276 (accum :+ IntegerEntry(rewardCachedPartKEY, rewardTotal))
277277 }
278278
279279 if (if ((depositNumLast == -1))
280280 then (depositNumUser == -1)
281281 else false)
282282 then nil
283283 else if (if ((depositNumLast == -1))
284284 then (depositNumUser > -1)
285285 else false)
286286 then throw("invalid depositNumLast and depositNumUser state")
287287 else if (if ((depositNumLast > -1))
288288 then (depositNumUser >= -1)
289289 else false)
290290 then if (isNewUser)
291291 then [IntegerEntry(userRewardFromDepositNumKEY, depositNumLast)]
292292 else ({
293293 let $l = supportedAssetsList
294294 let $s = size($l)
295295 let $acc0 = nil
296296 func $f0_1 ($a,$i) = if (($i >= $s))
297297 then $a
298298 else forEachAssetCacheUserReward($a, $l[$i])
299299
300300 func $f0_2 ($a,$i) = if (($i >= $s))
301301 then $a
302302 else throw("List size exceeds 2")
303303
304304 $f0_2($f0_1($f0_1($acc0, 0), 1), 2)
305305 } :+ IntegerEntry(userRewardFromDepositNumKEY, depositNumLast))
306306 else throw(((("uncovered condition: depositNumLast=" + toString(depositNumLast)) + " depositNumUser=") + toString(depositNumUser)))
307307 }
308308
309309
310310 func IncrementNotDistributedRewardEntry (tkn,amountInc) = {
311311 let notDistributedRewardKEY = keyNotDistributedReward(tkn)
312312 let notDistributedReward = getIntOrElse(notDistributedRewardKEY, 0)
313313 [IntegerEntry(notDistributedRewardKEY, (notDistributedReward + amountInc))]
314314 }
315315
316316
317317 func mergeStake (userAddress,amountToAdd) = {
318- let $t01353813654 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, height))
319- let isNewUser = $t01353813654._1
320- let stakedAmount = $t01353813654._2
321- let stakingStartHeight = $t01353813654._3
318+ let $t01357613692 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, height))
319+ let isNewUser = $t01357613692._1
320+ let stakedAmount = $t01357613692._2
321+ let stakingStartHeight = $t01357613692._3
322322 let stakedAmountNEW = if (isNewUser)
323323 then amountToAdd
324324 else (amountToAdd + stakedAmount)
325325 $Tuple4(isNewUser, stakedAmount, stakingStartHeight, stakedAmountNEW)
326326 }
327327
328328
329329 func commonStake (userAddress,i) = if ((size(i.payments) != 1))
330330 then throw("Invalid payments size")
331331 else {
332332 let payment = i.payments[0]
333333 let amount = payment.amount
334334 let invalidAssetMessage = (("Invalid asset. " + toBase58String(stakedAssetId)) + " is expected")
335335 let assetId = valueOrErrorMessage(payment.assetId, invalidAssetMessage)
336336 if ((assetId != stakedAssetId))
337337 then throw(invalidAssetMessage)
338338 else {
339339 let userAddressStr = toString(userAddress)
340- let mergedData = mergeStake(userAddress, amount)
340+ let mergedData = mergeStake(userAddressStr, amount)
341341 let isNewUser = mergedData._1
342342 let stakedAmount = mergedData._2
343343 let stakingStartHeight = mergedData._3
344344 let stakedAmountNEW = mergedData._4
345345 if ((minLockAmount > stakedAmountNEW))
346346 then throw(("Min lock amount is " + toString(minLockAmount)))
347347 else {
348- let $t01462414726 = StatsResult(amount, 1, if (isNewUser)
348+ let $t01466514767 = StatsResult(amount, 1, if (isNewUser)
349349 then 1
350350 else 0)
351- let statsEntries = $t01462414726._1
352- let totalStaked = $t01462414726._2
353- let totalStakedNew = $t01462414726._3
354- ((([HistoryRecordEntry("stake", userAddressStr, i.transactionId, stakedAmount, stakedAmountNEW)] ++ RewardEntries(isNewUser, userAddressStr, stakedAmount)) ++ LockParamsEntry(userAddress, stakedAmountNEW, stakingStartHeight)) ++ statsEntries)
351+ let statsEntries = $t01466514767._1
352+ let totalStaked = $t01466514767._2
353+ let totalStakedNew = $t01466514767._3
354+ ((([HistoryRecordEntry("stake", userAddressStr, i.transactionId, stakedAmount, stakedAmountNEW)] ++ RewardEntries(isNewUser, userAddressStr, stakedAmount)) ++ LockParamsEntry(userAddressStr, stakedAmountNEW, stakingStartHeight)) ++ statsEntries)
355355 }
356356 }
357357 }
358358
359359
360360 func commonUnstake (amount,i) = if ((size(i.payments) != 0))
361361 then throw("unstake doesn't require any payment")
362362 else {
363363 let userAddress = i.caller
364364 let userAddressStr = toString(userAddress)
365- let $t01519815283 = getUserParamsOrFail(userAddress)
366- let isNewUser = $t01519815283._1
367- let stakedAmount = $t01519815283._2
368- let stakingStartHeight = $t01519815283._3
365+ let $t01524215330 = getUserParamsOrFail(userAddressStr)
366+ let isNewUser = $t01524215330._1
367+ let stakedAmount = $t01524215330._2
368+ let stakingStartHeight = $t01524215330._3
369369 let swapParamsSTRUCT = asSwapParamsSTRUCT(reentrantInvoke(neutrinoContract, "swapParamsByUserSYSREADONLY", [userAddressStr, 0], nil))
370370 let swapLimitSpentInUsdn = swapParamsSTRUCT._2
371371 let blcks2LmtReset = swapParamsSTRUCT._3
372372 if ((swapLimitSpentInUsdn > 0))
373373 then throw((("You have already made a swap operation. Wait " + toString((height + blcks2LmtReset))) + " height to unstake"))
374374 else if ((0 >= stakedAmount))
375375 then throw("Nothing to unstake")
376376 else if ((amount > stakedAmount))
377377 then throw(((("Requested " + toString(amount)) + ", but staked only ") + toString(stakedAmount)))
378378 else {
379379 let stakedAmountNEW = (stakedAmount - amount)
380- let $t01592116079 = StatsResult(-(amount), if ((amount == stakedAmount))
380+ let $t01596816126 = StatsResult(-(amount), if ((amount == stakedAmount))
381381 then -1
382382 else 0, if ((amount == stakedAmount))
383383 then -1
384384 else 0)
385- let statsEntries = $t01592116079._1
386- let totalStaked = $t01592116079._2
387- let totalStakedNew = $t01592116079._3
388- ((([ScriptTransfer(userAddress, amount, stakedAssetId), HistoryRecordEntry("unstake", userAddressStr, i.transactionId, stakedAmount, stakedAmountNEW)] ++ RewardEntries(false, userAddressStr, stakedAmount)) ++ LockParamsEntry(userAddress, stakedAmountNEW, stakingStartHeight)) ++ statsEntries)
385+ let statsEntries = $t01596816126._1
386+ let totalStaked = $t01596816126._2
387+ let totalStakedNew = $t01596816126._3
388+ ((([ScriptTransfer(userAddress, amount, stakedAssetId), HistoryRecordEntry("unstake", userAddressStr, i.transactionId, stakedAmount, stakedAmountNEW)] ++ RewardEntries(false, userAddressStr, stakedAmount)) ++ LockParamsEntry(userAddressStr, stakedAmountNEW, stakingStartHeight)) ++ statsEntries)
389389 }
390390 }
391391
392392
393393 func commonClaim (userAddress,i) = {
394394 let userAddressStr = toString(userAddress)
395395 if ((size(i.payments) > 0))
396396 then throw("payments are not accepted")
397397 else {
398- let $t01657216677 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
399- let isNewUser = $t01657216677._1
400- let stakedAmount = $t01657216677._2
401- let stakingStart = $t01657216677._3
398+ let $t01662216730 = valueOrElse(getUserParamsOrUnit(userAddressStr), $Tuple3(true, 0, 0))
399+ let isNewUser = $t01662216730._1
400+ let stakedAmount = $t01662216730._2
401+ let stakingStart = $t01662216730._3
402402 let stakedAmountX = toBigInt(stakedAmount)
403403 let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddressStr)
404404 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
405405 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
406406 func forEachAssetCalcUnclaimedReward (accum,asset) = {
407- let $t01704817186 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
408- let rewardTotal = $t01704817186._1
409- let cached = $t01704817186._2
410- let dynamic = $t01704817186._3
411- let rewardCachedPartKEY = $t01704817186._4
407+ let $t01710117239 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
408+ let rewardTotal = $t01710117239._1
409+ let cached = $t01710117239._2
410+ let dynamic = $t01710117239._3
411+ let rewardCachedPartKEY = $t01710117239._4
412412 let claimedKEY = keyClaimed(userAddressStr, asset)
413- let $t01724617283 = accum
414- let data = $t01724617283._1
415- let claimedAmtByAsset = $t01724617283._2
413+ let $t01729917336 = accum
414+ let data = $t01729917336._1
415+ let claimedAmtByAsset = $t01729917336._2
416416 let newPart = makeString([asset, toString(rewardTotal)], ":")
417417 let claimedAmtByAssetNew = makeString([claimedAmtByAsset, newPart], "_")
418418 if ((0 >= rewardTotal))
419419 then $Tuple2(data, claimedAmtByAssetNew)
420420 else $Tuple2((((data :+ ScriptTransfer(userAddress, rewardTotal, toAssetVect(asset))) :+ IntegerEntry(claimedKEY, (valueOrElse(getInteger(claimedKEY), 0) + rewardTotal))) :+ IntegerEntry(rewardCachedPartKEY, 0)), claimedAmtByAssetNew)
421421 }
422422
423- let $t01774317856 = {
423+ let $t01779617909 = {
424424 let $l = supportedAssetsList
425425 let $s = size($l)
426426 let $acc0 = $Tuple2(nil, "")
427427 func $f0_1 ($a,$i) = if (($i >= $s))
428428 then $a
429429 else forEachAssetCalcUnclaimedReward($a, $l[$i])
430430
431431 func $f0_2 ($a,$i) = if (($i >= $s))
432432 then $a
433433 else throw("List size exceeds 2")
434434
435435 $f0_2($f0_1($f0_1($acc0, 0), 1), 2)
436436 }
437- let transfers = $t01774317856._1
438- let claimedAmtByAssetResult = $t01774317856._2
437+ let transfers = $t01779617909._1
438+ let claimedAmtByAssetResult = $t01779617909._2
439439 if ((0 >= size(transfers)))
440440 then $Tuple2(nil, 0)
441441 else $Tuple2(((transfers :+ IntegerEntry(userRewardFromDepositNumKEY, depositNumLast)) :+ ClaimHistoryEntry(userAddressStr, i.transactionId, drop(claimedAmtByAssetResult, 1))), size(transfers))
442442 }
443443 }
444444
445445
446446 let USDNTYPE = "USDN"
447447
448448 let NSBTTYPE = "NSBT"
449449
450450 let NeutrinoAssetIdKey = "neutrino_asset_id"
451451
452452 let NeutrinoContractKey = "neutrino_contract"
453453
454454 let NsbtAssetIdKey = "bond_asset_id"
455455
456456 let BalanceKey = "rpd_balance"
457457
458458 let neutrinoAssetId = fromBase58String(getStringOrFail(neutrinoContract, NeutrinoAssetIdKey))
459459
460460 let nsbtAssetIdStr = getStringOrFail(neutrinoContract, NsbtAssetIdKey)
461461
462462 let nsbtAssetId = fromBase58String(nsbtAssetIdStr)
463463
464464 func getUserBalanceKey (owner,assetId) = makeString([BalanceKey, assetId, owner], "_")
465465
466466
467467 func getContractBalanceKey (assetId) = ((BalanceKey + "_") + assetId)
468468
469469
470470 func getContractBalance (assetId) = getIntOrElse(getContractBalanceKey(assetId), 0)
471471
472472
473473 func getUserBalance (owner,assetId) = getIntOrElse(getUserBalanceKey(owner, assetId), 0)
474474
475475
476476 func getValidStakingAssetOrFail (stakingType,assetId) = if (if ((stakingType == USDNTYPE))
477477 then (assetId != neutrinoAssetId)
478478 else false)
479479 then throw("can use USDN only")
480480 else if (if ((stakingType == NSBTTYPE))
481481 then (assetId != nsbtAssetId)
482482 else false)
483483 then throw("can use NSBT only")
484484 else if (if ((stakingType != USDNTYPE))
485485 then (stakingType != NSBTTYPE)
486486 else false)
487487 then throw(("unsupported staking type " + stakingType))
488488 else assetId
489489
490490
491491 func internalUnlock (stakingType,i,unlockAmount,assetIdParam) = {
492492 let account = toString(i.caller)
493493 let assetId = getValidStakingAssetOrFail(stakingType, fromBase58String(assetIdParam))
494494 let assetIdString = toBase58String(assetId)
495495 let balance = (getUserBalance(account, assetIdString) - unlockAmount)
496496 if ((0 > balance))
497497 then throw("invalid amount")
498498 else $Tuple2([IntegerEntry(getContractBalanceKey(assetIdString), (getContractBalance(assetIdString) - unlockAmount)), IntegerEntry(getUserBalanceKey(account, assetIdString), balance), ScriptTransfer(addressFromStringValue(account), unlockAmount, assetId)], unit)
499499 }
500500
501501
502502 @Callable(i)
503503 func constructor (minLockAmount,supportedRewardAssets,pStakedAssetId) = if ((i.caller != this))
504504 then throw("Permission denied")
505505 else [IntegerEntry(keyMinLockAmount(), minLockAmount), StringEntry(keySupportedRewardAssets(), supportedRewardAssets), StringEntry(keyStakedAssetId(), pStakedAssetId)]
506506
507507
508508
509509 @Callable(i)
510510 func stake () = commonStake(i.caller, i)
511511
512512
513513
514514 @Callable(i)
515515 func stakeByOriginCaller () = commonStake(i.originCaller, i)
516516
517517
518518
519519 @Callable(i)
520520 func unstake (amount) = commonUnstake(amount, i)
521521
522522
523523
524524 @Callable(i)
525525 func deposit () = if ((size(i.payments) != 1))
526526 then throw("exact 1 payment is allowed only")
527527 else {
528528 let pmt = i.payments[0]
529529 let amount = pmt.amount
530530 let pmtAssetId = valueOrElse(pmt.assetId, WAVESID)
531531 let pmtAssetIdStr = toBase58String(pmtAssetId)
532532 let pmtMultX = if ((pmtAssetId == WAVESID))
533533 then MULTX8
534534 else MULTX6
535535 let amountX = toBigInt(amount)
536536 let totalStaked = getIntOrElse(keyLockParamTotalAmount(), 0)
537537 let totalStakedX = toBigInt(totalStaked)
538538 if ((0 > totalStaked))
539539 then throw("TODO: case is not supported")
540540 else if ((totalStaked == 0))
541541 then IncrementNotDistributedRewardEntry(pmtAssetIdStr, amount)
542542 else {
543543 let rewardPerNsbtX18 = fraction(amountX, MULTX18, totalStakedX)
544544 let depositNumLastKEY = keyDepositNumLast()
545545 let depositNumLast = getIntOrElse(depositNumLastKEY, -1)
546546 let depositNumNew = (depositNumLast + 1)
547547 if (!(contains(supportedAssetsStr, pmtAssetIdStr)))
548548 then throw(((supportedAssetsStr + " doesn't contain ") + pmtAssetIdStr))
549549 else {
550550 func refreshRewardPerNsbtSUM (accum,nextAsset) = {
551551 let rewardPerNsbtSumNewKEY = keyRewardPerNsbtSumAt(depositNumNew, nextAsset)
552552 let sumLastStr = getStrOrElse(keyRewardPerNsbtSumAt(depositNumLast, nextAsset), "0")
553553 (accum :+ (if ((nextAsset == pmtAssetIdStr))
554554 then StringEntry(rewardPerNsbtSumNewKEY, toString((parseBigIntValue(sumLastStr) + rewardPerNsbtX18)))
555555 else StringEntry(rewardPerNsbtSumNewKEY, sumLastStr)))
556556 }
557557
558558 (({
559559 let $l = supportedAssetsList
560560 let $s = size($l)
561561 let $acc0 = nil
562562 func $f0_1 ($a,$i) = if (($i >= $s))
563563 then $a
564564 else refreshRewardPerNsbtSUM($a, $l[$i])
565565
566566 func $f0_2 ($a,$i) = if (($i >= $s))
567567 then $a
568568 else throw("List size exceeds 2")
569569
570570 $f0_2($f0_1($f0_1($acc0, 0), 1), 2)
571571 } :+ IntegerEntry(depositNumLastKEY, depositNumNew)) ++ DepositsTotalsEntries(amount, pmtAssetIdStr))
572572 }
573573 }
574574 }
575575
576576
577577
578578 @Callable(i)
579579 func claimRewards () = commonClaim(i.caller, i)
580580
581581
582582
583583 @Callable(i)
584584 func claimRewardsByOriginCaller () = commonClaim(i.originCaller, i)
585585
586586
587587
588588 @Callable(i)
589589 func unclaimedRewardsREADONLY (userAddressStr) = {
590590 func forEachAssetZeroReward (accum,asset) = ((accum + makeString([asset, "0", "0"], ":")) + "_")
591591
592592 let unclaimedRewardStr = if ((userAddressStr == ""))
593593 then {
594594 let $l = supportedAssetsList
595595 let $s = size($l)
596596 let $acc0 = ""
597597 func $f0_1 ($a,$i) = if (($i >= $s))
598598 then $a
599599 else forEachAssetZeroReward($a, $l[$i])
600600
601601 func $f0_2 ($a,$i) = if (($i >= $s))
602602 then $a
603603 else throw("List size exceeds 2")
604604
605605 $f0_2($f0_1($f0_1($acc0, 0), 1), 2)
606606 }
607607 else {
608608 let userAddress = addressFromStringValue(userAddressStr)
609- let $t02291123022 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
610- let isNewUser = $t02291123022._1
611- let stakedAmount = $t02291123022._2
612- let stakingStartHeight = $t02291123022._3
609+ let $t02296423078 = valueOrElse(getUserParamsOrUnit(userAddressStr), $Tuple3(true, 0, 0))
610+ let isNewUser = $t02296423078._1
611+ let stakedAmount = $t02296423078._2
612+ let stakingStartHeight = $t02296423078._3
613613 let stakedAmountX = toBigInt(stakedAmount)
614614 let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddressStr)
615615 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
616616 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
617617 func forEachAssetCalcUnclaimedReward (accum,asset) = {
618- let $t02336823506 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
619- let rewardTotal = $t02336823506._1
620- let cached = $t02336823506._2
621- let dynamic = $t02336823506._3
622- let rewardCachedPartKEY = $t02336823506._4
618+ let $t02342423562 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
619+ let rewardTotal = $t02342423562._1
620+ let cached = $t02342423562._2
621+ let dynamic = $t02342423562._3
622+ let rewardCachedPartKEY = $t02342423562._4
623623 let claimed = valueOrElse(getInteger(keyClaimed(userAddressStr, asset)), 0)
624624 ((accum + makeString([asset, toString(rewardTotal), toString(claimed)], ":")) + "_")
625625 }
626626
627627 let $l = supportedAssetsList
628628 let $s = size($l)
629629 let $acc0 = ""
630630 func $f0_1 ($a,$i) = if (($i >= $s))
631631 then $a
632632 else forEachAssetCalcUnclaimedReward($a, $l[$i])
633633
634634 func $f0_2 ($a,$i) = if (($i >= $s))
635635 then $a
636636 else throw("List size exceeds 2")
637637
638638 $f0_2($f0_1($f0_1($acc0, 0), 1), 2)
639639 }
640640 $Tuple2(nil, dropRight(unclaimedRewardStr, 1))
641641 }
642642
643643
644644
645645 @Callable(i)
646646 func usdnStakingSYSREADONLY (userAddressStrOrEmpty,usdnDiff) = {
647647 let usdnTotalAmtStaked = getIntOrElse(keyLockParamTotalAmount(), 0)
648648 if ((userAddressStrOrEmpty == ""))
649649 then $Tuple2(nil, [0, usdnTotalAmtStaked, 0])
650650 else {
651651 let userAddress = toAddressOrFail(userAddressStrOrEmpty)
652- let mergedData = mergeStake(userAddress, usdnDiff)
652+ let mergedData = mergeStake(userAddressStrOrEmpty, usdnDiff)
653653 let isNewUser = mergedData._1
654654 let usdnStakedByUser = mergedData._2
655655 let stakingStartHeight = mergedData._3
656656 let stakedAmountNEW = mergedData._4
657657 $Tuple2(nil, [usdnStakedByUser, usdnTotalAmtStaked])
658658 }
659659 }
660660
661661
662662
663663 @Callable(i)
664664 func configSYSREADONLY () = {
665665 let minLockAmt = getIntegerValue(keyMinLockAmount())
666666 $Tuple2(nil, [minLockAmt])
667667 }
668668
669669
670670
671671 @Callable(i)
672672 func lockNeutrinoSP (receiver,share) = commonStake(i.caller, i)
673673
674674
675675
676676 @Callable(i)
677677 func lockNeutrino () = commonStake(i.caller, i)
678678
679679
680680
681681 @Callable(i)
682682 func unlockNeutrino (unlockAmount,assetIdString) = commonUnstake(unlockAmount, i)
683683
684684
685685
686686 @Callable(i)
687687 func unlockNsbt (unlockAmount,assetIdString) = internalUnlock(NSBTTYPE, i, unlockAmount, assetIdString)
688688
689689
690690 @Verifier(tx)
691691 func verify () = {
692692 let pubKeyAdminsListStr = makeString(["ExtEEK19nmKj9mCpnWyvEEJFYATLMcVEMvohhUHkyHNm", "Ev5py5FfBQX9cZpYKnfQrTB49Byf8QmpZWeDVRim4yV7", "DUuuLjXu98nBwZc7fqwCTjtA3nnRwgTbkMSr5SU2NmDR", "DUuuLjXu98nBwZc7fqwCTjtA3nnRwgTbkMSr5SU2NmDR"], SEP)
693693 let pubKeyAdminsList = split(valueOrElse(getString(controlContract, "%s__multisig"), pubKeyAdminsListStr), SEP)
694694 let count = ((((if (sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(pubKeyAdminsList[0])))
695695 then 1
696696 else 0) + (if (sigVerify(tx.bodyBytes, tx.proofs[1], fromBase58String(pubKeyAdminsList[1])))
697697 then 1
698698 else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[2], fromBase58String(pubKeyAdminsList[2])))
699699 then 1
700700 else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[3], fromBase58String(pubKeyAdminsList[3])))
701701 then 2
702702 else 0))
703703 (count >= 3)
704704 }
705705

github/deemru/w8io/873ac7e 
104.33 ms