tx · DcQS7LBtgKnKTHEksqQAPPvHFt3qcLfDEnZ7cHUytwu7

3N3nfqFcxXfd3T18V9icDdh58MJ9wQ2k2xx:  -0.01700000 Waves

2023.10.14 19:48 [2798551] smart account 3N3nfqFcxXfd3T18V9icDdh58MJ9wQ2k2xx > SELF 0.00000000 Waves

{ "type": 13, "id": "DcQS7LBtgKnKTHEksqQAPPvHFt3qcLfDEnZ7cHUytwu7", "fee": 1700000, "feeAssetId": null, "timestamp": 1697302105616, "version": 2, "chainId": 84, "sender": "3N3nfqFcxXfd3T18V9icDdh58MJ9wQ2k2xx", "senderPublicKey": "UGqkWsCpv7xRVXkQRXyLd6pWPDtYGXmPip7FxSd1pAu", "proofs": [ "2QCTiFvWWoT3MLRfMitzv6KA5JdQhKe5Jvp7RvK42NEuoRHG9cDunWEBYZNcvMwqCHJCW6T12efBuHtB6y1ZoyVe" ], "script": "base64:BgIlCAISCAoGAQEBAQEBEgASABIECgIIARIDCgEBEgMKAQESAwoBCDsAD0RFRkFVTFRMT0NBVElPTgIPQWZyaWNhX0ZfQWZyaWNhAA9sb2NJZHhDb250aW5lbnQAAAAKbG9jSWR4VHlwZQABARRrZXlTdGFrZWREdWNrQnlPd25lcgEJb3duZXJBZGRyCQCsAgICEnN0YWtlZER1Y2tCeU93bmVyXwUJb3duZXJBZGRyAQ9rZXlEdWNrTG9jYXRpb24BC2R1Y2tBc3NldElkCQCsAgICDWR1Y2tMb2NhdGlvbl8FC2R1Y2tBc3NldElkAA1sYXN0VG91cklkS2V5Ag4lc19fbGFzdFRvdXJJZAEVa2V5VG91clN0YXRpY0RhdGFCeUlkAQN0SWQJAKwCAgIWJXMlZF9fdG91clN0YXRpY0RhdGFfXwkApAMBBQN0SWQBFmtleVRvdXJEeW5hbWljRGF0YUJ5SWQBA3RJZAkArAICAhclcyVkX190b3VyRHluYW1pY0RhdGFfXwkApAMBBQN0SWQBE2tleVNjb3JlQm9hcmRCeVRvdXIBA3RJZAkArAICAhIlcyVkX19zY29yZUJvYXJkX18JAKQDAQUDdElkARJrZXlTdW1TY29yZXNCeVRvdXIBA3RJZAkArAICAhElcyVkX19zdW1TY29yZXNfXwkApAMBBQN0SWQBFmtleVVucGFpZFJld2FyZHNCeVRvdXIBA3RJZAkArAICAhUlcyVkX191bnBhaWRSZXdhcmRzX18JAKQDAQUDdElkARtrZXlMYXN0UmVnaXN0ZXJlZFRvdXJCeUR1Y2sBC2R1Y2tBc3NldElkCQCsAgICICVzJXNfX2xhc3RSZWdpc3RlcmVkVG91ckJ5RHVja19fBQtkdWNrQXNzZXRJZAEca2V5SXNSZWdpc3RlcmVkQnlUb3VyQW5kRHVjawIDdElkC2R1Y2tBc3NldElkCQC5CQIJAMwIAgIhJXMlZCVzX19pc1JlZ2lzdGVyZWRCeVRvdXJBbmREdWNrCQDMCAIJAKQDAQUDdElkCQDMCAIFC2R1Y2tBc3NldElkBQNuaWwCAl9fARlrZXlJc0F3YXJkZWRCeVRvdXJBbmREdWNrAgN0SWQLZHVja0Fzc2V0SWQJALkJAgkAzAgCAh4lcyVkJXNfX2lzQXdhcmRlZEJ5VG91ckFuZER1Y2sJAMwIAgkApAMBBQN0SWQJAMwIAgULZHVja0Fzc2V0SWQFA25pbAICX18BG2tleUxhc3RBdHRlbXB0QnlUb3VyQW5kRHVjawIDdElkC2R1Y2tBc3NldElkCQC5CQIJAMwIAgIgJXMlZCVzX19sYXN0QXR0ZW1wdEJ5VG91ckFuZER1Y2sJAMwIAgkApAMBBQN0SWQJAMwIAgULZHVja0Fzc2V0SWQFA25pbAICX18BGmtleUJlc3RSZXN1bHRCeVRvdXJBbmREdWNrAgN0SWQLZHVja0Fzc2V0SWQJALkJAgkAzAgCAh8lcyVkJXNfX2Jlc3RSZXN1bHRCeVRvdXJBbmREdWNrCQDMCAIJAKQDAQUDdElkCQDMCAIFC2R1Y2tBc3NldElkBQNuaWwCAl9fARZrZXlCZXN0VHhCeVRvdXJBbmREdWNrAgN0SWQLZHVja0Fzc2V0SWQJALkJAgkAzAgCAhslcyVkJXNfX2Jlc3RUeEJ5VG91ckFuZER1Y2sJAMwIAgkApAMBBQN0SWQJAMwIAgULZHVja0Fzc2V0SWQFA25pbAICX18ACWlkeFN0YXRpYwAAAAppZHhEeW5hbWljAAEAE3RTdGF0aWNSZWdpc3RlckNvc3QAAgASdFN0YXRpY0F0dGVtcHRDb3N0AAMADHRTdGF0aWNTdGFydAAFAAp0U3RhdGljRW5kAAYAEHRTdGF0aWNOdW1HcmFuZHMABwAQdFN0YXRpY1ByaXplRnVuZAAIAA50RHluYW1pY1N0YXR1cwABAA90RHluYW1pY0xlYWRlcnMAAgARdER5bmFtaWNXaW5SZXN1bHQAAwAVdER5bmFtaWNUb3RhbFJlZ0NvdW50AAQAFXREeW5hbWljVG90YWxBdHRlbXB0cwAFAQtnZXRUb3VyRGF0YQIMdG91ckNvbnRyYWN0A3RJZAQGc3RhdGljCQC1CQIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQx0b3VyQ29udHJhY3QJARVrZXlUb3VyU3RhdGljRGF0YUJ5SWQBBQN0SWQJAKwCAgkArAICAhlFcnJvciByZWFkaW5nIHRvdXJuYW1lbnQgCQCkAwEFA3RJZAIFIGRhdGECAl9fBAdkeW5hbWljCQC8CQIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQx0b3VyQ29udHJhY3QJARZrZXlUb3VyRHluYW1pY0RhdGFCeUlkAQUDdElkCQCsAgIJAKwCAgIZRXJyb3IgcmVhZGluZyB0b3VybmFtZW50IAkApAMBBQN0SWQCBSBkYXRhAgJfXwkAzAgCBQZzdGF0aWMJAMwIAgUHZHluYW1pYwUDbmlsAQ5pc0luVG91cm5hbWVudAIMdG91ckNvbnRyYWN0CGxvY2F0aW9uBAZsYXN0SWQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUMdG91ckNvbnRyYWN0BQ1sYXN0VG91cklkS2V5AAAEA2xvYwkAtQkCBQhsb2NhdGlvbgIBXwQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQFdERhdGEJAQtnZXRUb3VyRGF0YQIFDHRvdXJDb250cmFjdAUGbGFzdElkBAZzdGF0aWMJAJEDAgUFdERhdGEFCWlkeFN0YXRpYwQHZHluYW1pYwkAkQMCBQV0RGF0YQUKaWR4RHluYW1pYwMDAwkAAAIJAJEDAgUDbG9jBQpsb2NJZHhUeXBlAgFUCQAAAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFA2xvYwUPbG9jSWR4Q29udGluZW50BQZsYXN0SWQHCQAAAgkAkQMCBQdkeW5hbWljBQ50RHluYW1pY1N0YXR1cwIKSU5QUk9HUkVTUwcJAGYCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGc3RhdGljBQp0U3RhdGljRW5kBQNub3cHAAVjaGFpbgkAyQECCQDKAQIIBQR0aGlzBWJ5dGVzAAEAAQAVZGVmYXVsdFJlc3RBZGRyZXNzU3RyBAckbWF0Y2gwBQVjaGFpbgMJAAACAQFXBQckbWF0Y2gwAiMzUFFDdXZGYnZoNExrUFVucm5VMXozam5iQTFwOW0zV05odgMJAAACAQFUBQckbWF0Y2gwAiMzTXVta0dHenRDS0FYcFdEcXhrZGRvZnFYU1VicVFrdlNKeQkAAgECDVVua25vd24gY2hhaW4AA1NFUAICX18BD2dldFN0cmluZ09yRmFpbAIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQdhZGRyZXNzBQNrZXkJALkJAgkAzAgCAgptYW5kYXRvcnkgCQDMCAIJAKUIAQUHYWRkcmVzcwkAzAgCAgEuCQDMCAIFA2tleQkAzAgCAg8gaXMgbm90IGRlZmluZWQFA25pbAIAABFJZHhDZmdTdGFraW5nRGFwcAABAA1JZHhDZmdXbGdEYXBwAAQBCmtleVJlc3RDZmcAAg4lc19fcmVzdENvbmZpZwEOa2V5UmVzdEFkZHJlc3MAAgwlc19fcmVzdEFkZHIBEXJlYWRSZXN0Q2ZnT3JGYWlsAQRyZXN0CQC8CQIJAQ9nZXRTdHJpbmdPckZhaWwCBQRyZXN0CQEKa2V5UmVzdENmZwAFA1NFUAEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgdyZXN0Q2ZnA2lkeAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgUHcmVzdENmZwUDaWR4CQCsAgICKlJlc3QgY2ZnIGRvZXNuJ3QgY29udGFpbiBhZGRyZXNzIGF0IGluZGV4IAkApAMBBQNpZHgADHJlc3RDb250cmFjdAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzCQEOa2V5UmVzdEFkZHJlc3MABRVkZWZhdWx0UmVzdEFkZHJlc3NTdHIAB3Jlc3RDZmcJARFyZWFkUmVzdENmZ09yRmFpbAEFDHJlc3RDb250cmFjdAAPc3Rha2luZ0NvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUHcmVzdENmZwURSWR4Q2ZnU3Rha2luZ0RhcHAAC3dsZ0NvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUHcmVzdENmZwUNSWR4Q2ZnV2xnRGFwcAANd2xnQXNzZXRJZEtleQILd2xnX2Fzc2V0SWQACndsZ0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnAgCBQt3bGdDb250cmFjdAUNd2xnQXNzZXRJZEtleQIYV0xHT0xEIGlzIG5vdCBpc3N1ZWQgeWV0AQhhc1N0cmluZwEBdgQHJG1hdGNoMAUBdgMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAFAXMJAAIBAhhmYWlsIHRvIGNhc3QgaW50byBTdHJpbmcBBWFzSW50AQF2BAckbWF0Y2gwBQF2AwkAAQIFByRtYXRjaDACA0ludAQBbgUHJG1hdGNoMAUBbgkAAgECFWZhaWwgdG8gY2FzdCBpbnRvIEludAEKZml4ZWRQb2ludAIDdmFsCGRlY2ltYWxzBAZ0ZW5Qb3cJAGwGAAoAAAUIZGVjaW1hbHMAAAAABQRET1dOBAdsb3dQYXJ0CQCkAwEJAGoCBQN2YWwFBnRlblBvdwQGemVyb2VzCQCwAgIJAKQDAQUGdGVuUG93CQBkAgABCQCxAgEFB2xvd1BhcnQJAKwCAgkArAICCQCsAgIJAKQDAQkAaQIFA3ZhbAUGdGVuUG93AgEuBQZ6ZXJvZXMFB2xvd1BhcnQBBHBhZEwCA3ZhbANsZW4EBHZhbFMJAKQDAQUDdmFsBAZ6ZXJvZXMJALACAgkApAMBCQBsBgAKAAAJAGUCBQNsZW4JALECAQUEdmFsUwAAAAAFBERPV04AAQkArAICBQZ6ZXJvZXMFBHZhbFMAE01BWFRPVVJOQU1FTlRMRU5HVEgAgIiyoAIABEhPVVIAgN3bAQAKYWRtaW5zTGlzdAkAzAgCCQClCAEFBHRoaXMJAMwIAgQHJG1hdGNoMAUFY2hhaW4DCQAAAgEBVwUHJG1hdGNoMAIjM1BFZTJSRUxVSENGQ0JzbVNDTmNCSjhOM1VSTFZRZW5kZTcDCQAAAgEBVAUHJG1hdGNoMAIjM010QmdKVGFMeFBCM0M3VUpEMVVFOHFqa0h0aGZLdkZRWVkJAAIBAg1Vbmtub3duIGNoYWluBQNuaWwBCnN0YXRpY0RhdGEIBHR4SWQMcmVnaXN0ZXJDb3N0C2F0dGVtcHRDb3N0DGNyZWF0aW9uVGltZQlzdGFydFRpbWUHZW5kVGltZQludW1HcmFuZHMJcHJpemVGdW5kCQC5CQIJAMwIAgIQJXMlZCVkJWQlZCVkJWQlZAkAzAgCBQR0eElkCQDMCAIJAKQDAQUMcmVnaXN0ZXJDb3N0CQDMCAIJAKQDAQULYXR0ZW1wdENvc3QJAMwIAgkApAMBBQxjcmVhdGlvblRpbWUJAMwIAgkApAMBBQlzdGFydFRpbWUJAMwIAgkApAMBBQdlbmRUaW1lCQDMCAIJAKQDAQUJbnVtR3JhbmRzCQDMCAIJAKQDAQUJcHJpemVGdW5kBQNuaWwFA1NFUAELZHluYW1pY0RhdGEFBnN0YXR1cwdsZWFkZXJzCXdpblJlc3VsdAl0b3RhbFJlZ3MNdG90YWxBdHRlbXB0cwkAugkCCQDMCAICCiVzJXMlZCVkJWQJAMwIAgUGc3RhdHVzCQDMCAIFB2xlYWRlcnMJAMwIAgkApAMBBQl3aW5SZXN1bHQJAMwIAgkApAMBBQl0b3RhbFJlZ3MJAMwIAgkApAMBBQ10b3RhbEF0dGVtcHRzBQNuaWwFA1NFUAEGcHJvbG9nAAkBBWFzSW50AQkA/QcEBQ9zdGFraW5nQ29udHJhY3QCCnNhdmVMYXN0VHgFA25pbAUDbmlsAQxkdWNrQnlDYWxsZXIBBmNhbGxlcgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFD3N0YWtpbmdDb250cmFjdAkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQkApQgBBQZjYWxsZXICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQHAWkBEGNyZWF0ZVRvdXJuYW1lbnQGCXN0YXJ0VGltZQdlbmRUaW1lDHJlZ2lzdGVyQ29zdAthdHRlbXB0Q29zdAludW1HcmFuZHMJcHJpemVGdW5kBAZjYWxsZXIJAKUIAQgFAWkGY2FsbGVyAwkBASEBCQEPY29udGFpbnNFbGVtZW50AgUKYWRtaW5zTGlzdAUGY2FsbGVyCQACAQIRUGVybWlzc2lvbiBkZW5pZWQEBmxhc3RJZAkAnwgBBQ1sYXN0VG91cklkS2V5BAN0SWQDCQEJaXNEZWZpbmVkAQUGbGFzdElkBApsYXN0VG91cklkCQEFdmFsdWUBBQZsYXN0SWQEB2R5bmFtaWMJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEWa2V5VG91ckR5bmFtaWNEYXRhQnlJZAEFCmxhc3RUb3VySWQJAKwCAgkArAICAhlFcnJvciByZWFkaW5nIHRvdXJuYW1lbnQgCQCkAwEFCmxhc3RUb3VySWQCBSBkYXRhBAZzdGF0dXMJAJEDAgkAtQkCBQdkeW5hbWljBQNTRVAFDnREeW5hbWljU3RhdHVzAwMJAQIhPQIFBnN0YXR1cwIIQVJDSElWRUQJAQIhPQIFBnN0YXR1cwIKUFJPQ0VTU0lORwcJAAIBCQCsAgICLEN1cnJlbnQgdG91cm5lbWVudCBpcyBub3QgY29tcGxldGVkLCBzdGF0dXM9BQZzdGF0dXMJAGQCBQpsYXN0VG91cklkAAEAAQQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAMJAGYCBQNub3cFCXN0YXJ0VGltZQkAAgEJAKwCAgkArAICCQCsAgICCnN0YXJ0VGltZT0JAKQDAQUJc3RhcnRUaW1lAhAgPCBjcmVhdGlvblRpbWU9CQCkAwEFA25vdwMJAGYCBQlzdGFydFRpbWUFB2VuZFRpbWUJAAIBCQCsAgIJAKwCAgkArAICAghlbmRUaW1lPQkApAMBBQdlbmRUaW1lAg0gPCBzdGFydFRpbWU9CQCkAwEFCXN0YXJ0VGltZQMJAGYCCQBlAgUHZW5kVGltZQUJc3RhcnRUaW1lBRNNQVhUT1VSTkFNRU5UTEVOR1RICQACAQkArAICCQCsAgIJAKwCAgIfVG91cm5hbWVudCBwZXJpb2QgZXhjZWVkcyBtYXg6IAkApAMBCQBlAgUHZW5kVGltZQUJc3RhcnRUaW1lAgMgPiAJAKQDAQUTTUFYVE9VUk5BTUVOVExFTkdUSAMDCQBmAgAABQxyZWdpc3RlckNvc3QGCQBmAgAABQthdHRlbXB0Q29zdAkAAgEJAKwCAgkArAICCQCsAgICJENvc3Qgc2hvdWxkIGJlIHBvc2l0aXZlLCBidXQgcGFzc2VkIAkApAMBBQxyZWdpc3RlckNvc3QCBSBhbmQgCQCkAwEFC2F0dGVtcHRDb3N0AwkAZgIAAAUJbnVtR3JhbmRzCQACAQItTnVtYmVyIG9mIEdyYW5kIFByaXplcyBzaG91bGQgYmUgbm9uLW5lZ2F0aXZlAwkAZgIAAAUJcHJpemVGdW5kCQACAQIhUHJpemUgRnVuZCBzaG91bGQgYmUgbm9uLW5lZ2F0aXZlCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIFDWxhc3RUb3VySWRLZXkFA3RJZAkAzAgCCQELU3RyaW5nRW50cnkCCQEVa2V5VG91clN0YXRpY0RhdGFCeUlkAQUDdElkCQEKc3RhdGljRGF0YQgJANgEAQgFAWkNdHJhbnNhY3Rpb25JZAUMcmVnaXN0ZXJDb3N0BQthdHRlbXB0Q29zdAUDbm93BQlzdGFydFRpbWUFB2VuZFRpbWUFCW51bUdyYW5kcwUJcHJpemVGdW5kCQDMCAIJAQtTdHJpbmdFbnRyeQIJARZrZXlUb3VyRHluYW1pY0RhdGFCeUlkAQUDdElkCQELZHluYW1pY0RhdGEFAgdDUkVBVEVEAgEgAAAAAAAABQNuaWwFA3RJZAFpAQhyZWdpc3RlcgAEDHByb2xvZ1Jlc3VsdAkBBnByb2xvZwADCQAAAgUMcHJvbG9nUmVzdWx0BQxwcm9sb2dSZXN1bHQEBmxhc3RJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEFDWxhc3RUb3VySWRLZXkCFU5vIGFjdGl2ZSB0b3VybmFtZW50cwQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQFdERhdGEJAQtnZXRUb3VyRGF0YQIFBHRoaXMFBmxhc3RJZAQGc3RhdGljCQCRAwIFBXREYXRhBQlpZHhTdGF0aWMEB2R5bmFtaWMJAJEDAgUFdERhdGEFCmlkeER5bmFtaWMEBnN0YXR1cwkAkQMCBQdkeW5hbWljBQ50RHluYW1pY1N0YXR1cwMJAQEhAQMDAwkAAAIFBnN0YXR1cwIHQ1JFQVRFRAkAZgIFA25vdwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnN0YXRpYwUMdFN0YXRpY1N0YXJ0BwkAZgIJAGUCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGc3RhdGljBQp0U3RhdGljRW5kBQRIT1VSBQNub3cHBgMJAAACBQZzdGF0dXMCCklOUFJPR1JFU1MJAGYCCQBlAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnN0YXRpYwUKdFN0YXRpY0VuZAUESE9VUgUDbm93BwkAAgECE0Nhbm5vdCByZWdpc3RlciBub3cEB3JlZ0Nvc3QJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZzdGF0aWMFE3RTdGF0aWNSZWdpc3RlckNvc3QEBndsZ0FtdAMJAGYCBQdyZWdDb3N0AAADCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAiJleGFjdGx5IDEgcGF5bWVudCBtdXN0IGJlIGF0dGFjaGVkBANwbXQJAJEDAggFAWkIcGF5bWVudHMAAAMDCQEBIQEJAQlpc0RlZmluZWQBCAUDcG10B2Fzc2V0SWQGCQECIT0CCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQFCndsZ0Fzc2V0SWQJAAIBAhVXTEdPTEQgcGF5bWVudHMgb25seSEIBQNwbXQGYW1vdW50AwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIUTm8gcGF5bWVudHMgcmVxdWlyZWQAAAMJAQIhPQIFBndsZ0FtdAUHcmVnQ29zdAkAAgEJAKwCAgkArAICAhBOZWVkIHBheW1lbnQgb2YgCQEKZml4ZWRQb2ludAIFB3JlZ0Nvc3QACAIHIFdMR09MRAQLZHVja0Fzc2V0SWQJAQxkdWNrQnlDYWxsZXIBCAUBaQxvcmlnaW5DYWxsZXIECHNjb3JlS2V5CQETa2V5U2NvcmVCb2FyZEJ5VG91cgEFBmxhc3RJZAQNb2xkU2NvcmVCb2FyZAkBC3ZhbHVlT3JFbHNlAgkAoggBBQhzY29yZUtleQIAAwMJAQt2YWx1ZU9yRWxzZQIJAKAIAQkBHGtleUlzUmVnaXN0ZXJlZEJ5VG91ckFuZER1Y2sCBQZsYXN0SWQFC2R1Y2tBc3NldElkBwYJAQhjb250YWlucwIFDW9sZFNjb3JlQm9hcmQFC2R1Y2tBc3NldElkCQACAQkArAICCQCsAgIJAKwCAgIKWW91ciBkdWNrIAULZHVja0Fzc2V0SWQCJSBpcyBhbHJlYWR5IHJlZ2lzdGVyZWQgYXQgdG91cm5hbWVudCAJAKQDAQUGbGFzdElkBBJ1cGRhdGVkRHluYW1pY0RhdGEJAQtkeW5hbWljRGF0YQUCCklOUFJPR1JFU1MJAJEDAgUHZHluYW1pYwUPdER5bmFtaWNMZWFkZXJzCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHZHluYW1pYwURdER5bmFtaWNXaW5SZXN1bHQJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHZHluYW1pYwUVdER5bmFtaWNUb3RhbFJlZ0NvdW50AAEJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdkeW5hbWljBRV0RHluYW1pY1RvdGFsQXR0ZW1wdHMJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBG2tleUxhc3RSZWdpc3RlcmVkVG91ckJ5RHVjawEFC2R1Y2tBc3NldElkBQZsYXN0SWQJAMwIAgkBDEJvb2xlYW5FbnRyeQIJARxrZXlJc1JlZ2lzdGVyZWRCeVRvdXJBbmREdWNrAgUGbGFzdElkBQtkdWNrQXNzZXRJZAYJAMwIAgkBC1N0cmluZ0VudHJ5AgUIc2NvcmVLZXkDCQAAAgUNb2xkU2NvcmVCb2FyZAIACQCsAgIFC2R1Y2tBc3NldElkAgQ6MDAwCQCsAgIJAKwCAgkArAICBQ1vbGRTY29yZUJvYXJkAgFfBQtkdWNrQXNzZXRJZAIEOjAwMAkAzAgCCQELU3RyaW5nRW50cnkCCQEWa2V5VG91ckR5bmFtaWNEYXRhQnlJZAEFBmxhc3RJZAUSdXBkYXRlZER5bmFtaWNEYXRhBQNuaWwFDHByb2xvZ1Jlc3VsdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQpuZXdBdHRlbXB0AAQMcHJvbG9nUmVzdWx0CQEGcHJvbG9nAAMJAAACBQxwcm9sb2dSZXN1bHQFDHByb2xvZ1Jlc3VsdAQLZHVja0Fzc2V0SWQJAQxkdWNrQnlDYWxsZXIBCAUBaQxvcmlnaW5DYWxsZXIEBmxhc3RJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEFDWxhc3RUb3VySWRLZXkCFU5vIGFjdGl2ZSB0b3VybmFtZW50cwQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQFdERhdGEJAQtnZXRUb3VyRGF0YQIFBHRoaXMFBmxhc3RJZAQGc3RhdGljCQCRAwIFBXREYXRhBQlpZHhTdGF0aWMEB2R5bmFtaWMJAJEDAgUFdERhdGEFCmlkeER5bmFtaWMEBnN0YXR1cwkAkQMCBQdkeW5hbWljBQ50RHluYW1pY1N0YXR1cwMJAQEhAQMJAAACBQZzdGF0dXMCCklOUFJPR1JFU1MJAGYCCQBlAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnN0YXRpYwUKdFN0YXRpY0VuZAUESE9VUgUDbm93BwkAAgECF0F0dGVtcHQgaXMgbm90IHBvc3NpYmxlAwkBASEBCQELdmFsdWVPckVsc2UCCQCgCAEJARxrZXlJc1JlZ2lzdGVyZWRCeVRvdXJBbmREdWNrAgUGbGFzdElkBQtkdWNrQXNzZXRJZAcJAAIBCQCsAgIJAKwCAgkArAICAgpZb3VyIGR1Y2sgBQtkdWNrQXNzZXRJZAIhIGlzIG5vdCByZWdpc3RlcmVkIGF0IHRvdXJuYW1lbnQgCQCkAwEFBmxhc3RJZAQTYXR0ZW1wdHNJdGVyYXRvcktleQkBG2tleUxhc3RBdHRlbXB0QnlUb3VyQW5kRHVjawIFBmxhc3RJZAULZHVja0Fzc2V0SWQEC2xhc3RBdHRlbXB0CQCfCAEFE2F0dGVtcHRzSXRlcmF0b3JLZXkECyR0MDYzOTA2OTgxAwkBASEBCQEJaXNEZWZpbmVkAQULbGFzdEF0dGVtcHQJAJQKAgAAAAADCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAiJleGFjdGx5IDEgcGF5bWVudCBtdXN0IGJlIGF0dGFjaGVkBANwbXQJAJEDAggFAWkIcGF5bWVudHMAAAQGd2xnQW10CAUDcG10BmFtb3VudAMDCQEBIQEJAQlpc0RlZmluZWQBCAUDcG10B2Fzc2V0SWQGCQECIT0CCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQFCndsZ0Fzc2V0SWQJAAIBAhVXTEdPTEQgcGF5bWVudHMgb25seSEEB2F0dENvc3QJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZzdGF0aWMFEnRTdGF0aWNBdHRlbXB0Q29zdAMJAQIhPQIFBndsZ0FtdAUHYXR0Q29zdAkAAgEJAKwCAgkArAICAhBOZWVkIHBheW1lbnQgb2YgCQEKZml4ZWRQb2ludAIFB2F0dENvc3QACAIHIFdMR09MRAkAlAoCCQBkAgkBBXZhbHVlAQULbGFzdEF0dGVtcHQAAQABBA1wYXllZEF0dGVtcHRzCAULJHQwNjM5MDY5ODECXzEECWluY3JlbWVudAgFCyR0MDYzOTA2OTgxAl8yBBJ1cGRhdGVkRHluYW1pY0RhdGEJAQtkeW5hbWljRGF0YQUCCklOUFJPR1JFU1MJAJEDAgUHZHluYW1pYwUPdER5bmFtaWNMZWFkZXJzCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHZHluYW1pYwURdER5bmFtaWNXaW5SZXN1bHQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdkeW5hbWljBRV0RHluYW1pY1RvdGFsUmVnQ291bnQJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHZHluYW1pYwUVdER5bmFtaWNUb3RhbEF0dGVtcHRzBQlpbmNyZW1lbnQEB3RvdXJMb2MJAQhhc1N0cmluZwEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0AhNpbml0RHVja1RvdXJBdHRlbXB0CQDMCAIFC2R1Y2tBc3NldElkBQNuaWwFA25pbAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRNhdHRlbXB0c0l0ZXJhdG9yS2V5BQ1wYXllZEF0dGVtcHRzCQDMCAIJAQtTdHJpbmdFbnRyeQIJARZrZXlUb3VyRHluYW1pY0RhdGFCeUlkAQUGbGFzdElkBRJ1cGRhdGVkRHluYW1pY0RhdGEFA25pbAkAzAgCBQxwcm9sb2dSZXN1bHQJAMwIAgUNcGF5ZWRBdHRlbXB0cwkAzAgCBQd0b3VyTG9jBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEOc2F2ZUR1Y2tSZXN1bHQCC2R1Y2tBc3NldElkC2R1Y2tOZXdCZXN0AwkBAiE9AggFAWkGY2FsbGVyBQ9zdGFraW5nQ29udHJhY3QJAAIBAg1BY2Nlc3MgZGVuaWVkBAZsYXN0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBBQ1sYXN0VG91cklkS2V5AhVObyBhY3RpdmUgdG91cm5hbWVudHMEBXREYXRhCQELZ2V0VG91ckRhdGECBQR0aGlzBQZsYXN0SWQEBnN0YXRpYwkAkQMCBQV0RGF0YQUJaWR4U3RhdGljBAdkeW5hbWljCQCRAwIFBXREYXRhBQppZHhEeW5hbWljBAtjdXJMb2NhdGlvbgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAUPREVGQVVMVExPQ0FUSU9OBA1iZXN0UmVzdWx0S2V5CQEaa2V5QmVzdFJlc3VsdEJ5VG91ckFuZER1Y2sCBQZsYXN0SWQFC2R1Y2tBc3NldElkBAxzdW1TY29yZXNLZXkJARJrZXlTdW1TY29yZXNCeVRvdXIBBQZsYXN0SWQEDG9sZFN1bVNjb3JlcwkBC3ZhbHVlT3JFbHNlAgkAnwgBBQxzdW1TY29yZXNLZXkAAAMJAQ5pc0luVG91cm5hbWVudAIFBHRoaXMFC2N1ckxvY2F0aW9uBAtkdWNrT2xkQmVzdAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQ1iZXN0UmVzdWx0S2V5AAAECHNjb3JlS2V5CQETa2V5U2NvcmVCb2FyZEJ5VG91cgEFBmxhc3RJZAQNb2xkU2NvcmVCb2FyZAkBC3ZhbHVlT3JFbHNlAgkAoggBBQhzY29yZUtleQIABAskdDA4NDc0OTYzNQMJAGYCBQtkdWNrTmV3QmVzdAULZHVja09sZEJlc3QDCQEBIQEJAQhjb250YWlucwIFDW9sZFNjb3JlQm9hcmQFC2R1Y2tBc3NldElkCQACAQkArAICAhxzY29yZUJvYXJkIGRvZXMgbm90IGNvbnRhaW4gBQtkdWNrQXNzZXRJZAQHb2xkQmVzdAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFB2R5bmFtaWMFEXREeW5hbWljV2luUmVzdWx0BAdsZWFkZXJzCQCRAwIFB2R5bmFtaWMFD3REeW5hbWljTGVhZGVycwQOb2xkTGVhZGVyc0xpc3QDAwkAAAIFB2xlYWRlcnMCAAYJAAACBQdsZWFkZXJzAgEgBQNuaWwJALwJAgUHbGVhZGVycwIBLAQObmV3TGVhZGVyc0xpc3QDCQBmAgULZHVja05ld0Jlc3QFB29sZEJlc3QJAMwIAgULZHVja0Fzc2V0SWQFA25pbAMDCQBmAgUHb2xkQmVzdAULZHVja05ld0Jlc3QGCQEPY29udGFpbnNFbGVtZW50AgUOb2xkTGVhZGVyc0xpc3QFC2R1Y2tBc3NldElkBQ5vbGRMZWFkZXJzTGlzdAkAzQgCBQ5vbGRMZWFkZXJzTGlzdAULZHVja0Fzc2V0SWQEEnVwZGF0ZWREeW5hbWljRGF0YQkBC2R5bmFtaWNEYXRhBQIKSU5QUk9HUkVTUwkAugkCBQ5uZXdMZWFkZXJzTGlzdAIBLAkAlgMBCQDMCAIFC2R1Y2tOZXdCZXN0CQDMCAIFB29sZEJlc3QFA25pbAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFB2R5bmFtaWMFFXREeW5hbWljVG90YWxSZWdDb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFB2R5bmFtaWMFFXREeW5hbWljVG90YWxBdHRlbXB0cwQFcGFydHMJAL0JAgUNb2xkU2NvcmVCb2FyZAULZHVja0Fzc2V0SWQJAJUKAwkArAICCQCsAgIJAKwCAgkArAICCQCRAwIFBXBhcnRzAAAFC2R1Y2tBc3NldElkAgE6CQEEcGFkTAIFC2R1Y2tOZXdCZXN0AAMJALACAgkAkQMCBQVwYXJ0cwABAAQJAGUCCQBkAgUMb2xkU3VtU2NvcmVzBQtkdWNrTmV3QmVzdAULZHVja09sZEJlc3QJAMwIAgkBC1N0cmluZ0VudHJ5AgkBFmtleVRvdXJEeW5hbWljRGF0YUJ5SWQBBQZsYXN0SWQFEnVwZGF0ZWREeW5hbWljRGF0YQUDbmlsCQCVCgMFDW9sZFNjb3JlQm9hcmQFDG9sZFN1bVNjb3JlcwUDbmlsBA1uZXdTY29yZUJvYXJkCAULJHQwODQ3NDk2MzUCXzEEDG5ld1N1bVNjb3JlcwgFCyR0MDg0NzQ5NjM1Al8yBA1nbG9iYWxBY3Rpb25zCAULJHQwODQ3NDk2MzUCXzMJAJQKAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ1iZXN0UmVzdWx0S2V5CQCWAwEJAMwIAgULZHVja09sZEJlc3QJAMwIAgULZHVja05ld0Jlc3QFA25pbAkAzAgCCQEMSW50ZWdlckVudHJ5AgUMc3VtU2NvcmVzS2V5BQxuZXdTdW1TY29yZXMJAMwIAgkBC1N0cmluZ0VudHJ5AgkBFmtleUJlc3RUeEJ5VG91ckFuZER1Y2sCBQZsYXN0SWQFC2R1Y2tBc3NldElkCQDYBAEIBQFpDXRyYW5zYWN0aW9uSWQJAMwIAgkBC1N0cmluZ0VudHJ5AgUIc2NvcmVLZXkFDW5ld1Njb3JlQm9hcmQFA25pbAUNZ2xvYmFsQWN0aW9ucwAACQCUCgIFA25pbAAAAWkBEXByb2Nlc3NUb3VybmFtZW50AQN0SWQEBmNhbGxlcgkApQgBCAUBaQZjYWxsZXIDCQEBIQEJAQ9jb250YWluc0VsZW1lbnQCBQphZG1pbnNMaXN0BQZjYWxsZXIJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQFdERhdGEJAQtnZXRUb3VyRGF0YQIFBHRoaXMFA3RJZAQGc3RhdGljCQCRAwIFBXREYXRhBQlpZHhTdGF0aWMEB2R5bmFtaWMJAJEDAgUFdERhdGEFCmlkeER5bmFtaWMEBnN0YXR1cwkAkQMCBQdkeW5hbWljBQ50RHluYW1pY1N0YXR1cwQNcmVnaXN0cmF0aW9ucwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFB2R5bmFtaWMFFXREeW5hbWljVG90YWxSZWdDb3VudAQMcGFpZEF0dGVtcHRzCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHZHluYW1pYwUVdER5bmFtaWNUb3RhbEF0dGVtcHRzBAdyZWdDb3N0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGc3RhdGljBRN0U3RhdGljUmVnaXN0ZXJDb3N0BAdhdHRDb3N0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGc3RhdGljBRJ0U3RhdGljQXR0ZW1wdENvc3QDCQAAAgUGc3RhdHVzAghBUkNISVZFRAkAAgEJAKwCAgkArAICAgtUb3VybmFtZW50IAkApAMBBQN0SWQCFCBpcyBhbHJlYWR5IEFSQ0hJVkVEAwMJAAACBQZzdGF0dXMCCklOUFJPR1JFU1MJAGYCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGc3RhdGljBQp0U3RhdGljRW5kBQNub3cHCQACAQkArAICCQCsAgICC1RvdXJuYW1lbnQgCQCkAwEFA3RJZAIQIGlzIG5vdCBvdmVyIHlldAQSdXBkYXRlZER5bmFtaWNEYXRhCQELZHluYW1pY0RhdGEFAgpQUk9DRVNTSU5HCQCRAwIFB2R5bmFtaWMFD3REeW5hbWljTGVhZGVycwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFB2R5bmFtaWMFEXREeW5hbWljV2luUmVzdWx0BQ1yZWdpc3RyYXRpb25zBQxwYWlkQXR0ZW1wdHMECXByaXplRnVuZAMJAGYCCQCQAwEFBnN0YXRpYwUQdFN0YXRpY1ByaXplRnVuZAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnN0YXRpYwUQdFN0YXRpY1ByaXplRnVuZAAABAZ1bnBhaWQJAGQCCQBpAgkAZAIJAGgCBQ1yZWdpc3RyYXRpb25zBQdyZWdDb3N0CQBoAgUMcGFpZEF0dGVtcHRzBQdhdHRDb3N0AAIFCXByaXplRnVuZAkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIJARZrZXlUb3VyRHluYW1pY0RhdGFCeUlkAQUDdElkBRJ1cGRhdGVkRHluYW1pY0RhdGEJAMwIAgkBDEludGVnZXJFbnRyeQIJARZrZXlVbnBhaWRSZXdhcmRzQnlUb3VyAQUDdElkBQZ1bnBhaWQFA25pbAAAAWkBCmNsYWltUHJpemUBA3RJZAQMcHJvbG9nUmVzdWx0CQEGcHJvbG9nAAMJAAACBQxwcm9sb2dSZXN1bHQFDHByb2xvZ1Jlc3VsdAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBAV0RGF0YQkBC2dldFRvdXJEYXRhAgUEdGhpcwUDdElkBAZzdGF0aWMJAJEDAgUFdERhdGEFCWlkeFN0YXRpYwQHZHluYW1pYwkAkQMCBQV0RGF0YQUKaWR4RHluYW1pYwQGc3RhdHVzCQCRAwIFB2R5bmFtaWMFDnREeW5hbWljU3RhdHVzAwkBAiE9AgUGc3RhdHVzAgpQUk9DRVNTSU5HCQACAQkArAICCQCsAgICC1RvdXJuYW1lbnQgCQCkAwEFA3RJZAISIGlzIG5vdCBQUk9DRVNTSU5HBA1yZWdpc3RyYXRpb25zCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHZHluYW1pYwUVdER5bmFtaWNUb3RhbFJlZ0NvdW50BAxwYWlkQXR0ZW1wdHMJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdkeW5hbWljBRV0RHluYW1pY1RvdGFsQXR0ZW1wdHMEB3JlZ0Nvc3QJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZzdGF0aWMFE3RTdGF0aWNSZWdpc3RlckNvc3QEB2F0dENvc3QJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZzdGF0aWMFEnRTdGF0aWNBdHRlbXB0Q29zdAQJcHJpemVGdW5kAwkAZgIJAJADAQUGc3RhdGljBRB0U3RhdGljUHJpemVGdW5kCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGc3RhdGljBRB0U3RhdGljUHJpemVGdW5kAAAECmF3YXJkRnVuZHMJAGQCCQBpAgkAZAIJAGgCBQ1yZWdpc3RyYXRpb25zBQdyZWdDb3N0CQBoAgUMcGFpZEF0dGVtcHRzBQdhdHRDb3N0AAIFCXByaXplRnVuZAQJdW5wYWlkS2V5CQEWa2V5VW5wYWlkUmV3YXJkc0J5VG91cgEFA3RJZAQLdW5wYWlkRnVuZHMJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJdW5wYWlkS2V5AAAEC2R1Y2tBc3NldElkCQEMZHVja0J5Q2FsbGVyAQgFAWkMb3JpZ2luQ2FsbGVyAwkBASEBCQELdmFsdWVPckVsc2UCCQCgCAEJARxrZXlJc1JlZ2lzdGVyZWRCeVRvdXJBbmREdWNrAgUDdElkBQtkdWNrQXNzZXRJZAcJAAIBCQCsAgIJAKwCAgkArAICAgpZb3VyIGR1Y2sgBQtkdWNrQXNzZXRJZAIhIGlzIG5vdCByZWdpc3RlcmVkIGF0IHRvdXJuYW1lbnQgCQCkAwEFA3RJZAQNYmVzdFJlc3VsdEtleQkBGmtleUJlc3RSZXN1bHRCeVRvdXJBbmREdWNrAgUDdElkBQtkdWNrQXNzZXRJZAQIZHVja0Jlc3QJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUNYmVzdFJlc3VsdEtleQAAAwkAAAIFCGR1Y2tCZXN0AAAJAAIBAhhZb3VyIGR1Y2sgZ290IHplcm8gc2NvcmUECmF3YXJkZWRLZXkJARlrZXlJc0F3YXJkZWRCeVRvdXJBbmREdWNrAgUDdElkBQtkdWNrQXNzZXRJZAMJAQt2YWx1ZU9yRWxzZQIJAKAIAQUKYXdhcmRlZEtleQcJAAIBCQCsAgIJAKwCAgkArAICAgpZb3VyIGR1Y2sgBQtkdWNrQXNzZXRJZAIiIGlzIGFscmVhZHkgYXdhcmRlZCBhdCB0b3VybmFtZW50IAkApAMBBQN0SWQEDHN1bVNjb3Jlc0tleQkBEmtleVN1bVNjb3Jlc0J5VG91cgEFA3RJZAQJc3VtU2NvcmVzCQELdmFsdWVPckVsc2UCCQCfCAEFDHN1bVNjb3Jlc0tleQAABAdsZWFkZXJzCQCRAwIFB2R5bmFtaWMFD3REeW5hbWljTGVhZGVycwQLbGVhZGVyc0xpc3QDAwkAAAIFB2xlYWRlcnMCAAYJAAACBQdsZWFkZXJzAgEgBQNuaWwJALwJAgUHbGVhZGVycwIBLAQKbnVtTGVhZGVycwkAkAMBBQtsZWFkZXJzTGlzdAMJAAACBQpudW1MZWFkZXJzAAAJAAIBCQCsAgICGU5vIGxlYWRlcnMgYXQgdG91cm5hbWVudCAJAKQDAQUDdElkBAludW1HcmFuZHMJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZzdGF0aWMFEHRTdGF0aWNOdW1HcmFuZHMECXdpblJlc3VsdAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFB2R5bmFtaWMFEXREeW5hbWljV2luUmVzdWx0BA9zdW1MZWFkZXJTY29yZXMDCQBmAgUKbnVtTGVhZGVycwUJbnVtR3JhbmRzAAADCQEPY29udGFpbnNFbGVtZW50AgULbGVhZGVyc0xpc3QFC2R1Y2tBc3NldElkCQACAQIwQXMgb25lIG9mIHdpbm5lcnMsIHlvdSB3aWxsIGJlIGF3YXJkZWQgYnkgYWRtaW5zCQBoAgUKbnVtTGVhZGVycwUJd2luUmVzdWx0BAp5b3VyQW1vdW50CQCXAwEJAMwIAgkAawMFCGR1Y2tCZXN0BQphd2FyZEZ1bmRzCQBlAgUJc3VtU2NvcmVzBQ9zdW1MZWFkZXJTY29yZXMJAMwIAgULdW5wYWlkRnVuZHMFA25pbAQPbmV3VW5wYWlkQW1vdW50CQBlAgULdW5wYWlkRnVuZHMFCnlvdXJBbW91bnQEEnVwZGF0ZWREeW5hbWljRGF0YQkBC2R5bmFtaWNEYXRhBQIIQVJDSElWRUQJAJEDAgUHZHluYW1pYwUPdER5bmFtaWNMZWFkZXJzBQl3aW5SZXN1bHQFDXJlZ2lzdHJhdGlvbnMFDHBhaWRBdHRlbXB0cwQNYXJjaGl2ZUFjdGlvbgMJAGcCAAAFD25ld1VucGFpZEFtb3VudAkAzAgCCQELU3RyaW5nRW50cnkCCQEWa2V5VG91ckR5bmFtaWNEYXRhQnlJZAEFA3RJZAUSdXBkYXRlZER5bmFtaWNEYXRhBQNuaWwFA25pbAkAlAoCCQDOCAIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQp5b3VyQW1vdW50BQp3bGdBc3NldElkCQDMCAIJAQxCb29sZWFuRW50cnkCBQphd2FyZGVkS2V5BgkAzAgCCQEMSW50ZWdlckVudHJ5AgUJdW5wYWlkS2V5BQ9uZXdVbnBhaWRBbW91bnQFA25pbAUNYXJjaGl2ZUFjdGlvbgAACQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCWF3YXJkTGFuZAENd2lubmVyQWRkcmVzcwQGY2FsbGVyCQClCAEIBQFpBmNhbGxlcgMJAQEhAQkBD2NvbnRhaW5zRWxlbWVudAIFCmFkbWluc0xpc3QFBmNhbGxlcgkAAgECEVBlcm1pc3Npb24gZGVuaWVkBAtsYW5kQXNzZXRJZAkBCGFzU3RyaW5nAQkA/AcEBQ9zdGFraW5nQ29udHJhY3QCCmF3YXJkU0xhbmQJAMwIAgUNd2lubmVyQWRkcmVzcwUDbmlsBQNuaWwJAJQKAgUDbmlsBQtsYW5kQXNzZXRJZAASgdJ5", "height": 2798551, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 6aRBuV1Ucg3aPwvTtC3gB2tR521TtmcmDNk9c6JYTa3m Next: E12a71AZd9yp46ZWNsXucXHCdH5QDLe2HXkb7v3KriQu Diff:
OldNewDifferences
173173 }
174174
175175
176-let MAXTOURNAMENTLENGTH = 432000000
176+let MAXTOURNAMENTLENGTH = 604800000
177177
178178 let HOUR = 3600000
179179
192192 func dynamicData (status,leaders,winResult,totalRegs,totalAttempts) = makeString_2C(["%s%s%d%d%d", status, leaders, toString(winResult), toString(totalRegs), toString(totalAttempts)], SEP)
193193
194194
195-func prolog () = asInt(invoke(stakingContract, "saveLastTx", nil, nil))
195+func prolog () = asInt(reentrantInvoke(stakingContract, "saveLastTx", nil, nil))
196196
197197
198198 func duckByCaller (caller) = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(caller))), "You don't have a duck staked")
241241 @Callable(i)
242242 func register () = {
243243 let prologResult = prolog()
244- let lastId = valueOrErrorMessage(getInteger(lastTourIdKey), "No active tournaments")
245- let now = lastBlock.timestamp
246- let tData = getTourData(this, lastId)
247- let static = tData[idxStatic]
248- let dynamic = tData[idxDynamic]
249- let status = dynamic[tDynamicStatus]
250- if (!(if (if (if ((status == "CREATED"))
251- then (now > parseIntValue(static[tStaticStart]))
252- else false)
253- then ((parseIntValue(static[tStaticEnd]) - HOUR) > now)
254- else false)
255- then true
256- else if ((status == "INPROGRESS"))
257- then ((parseIntValue(static[tStaticEnd]) - HOUR) > now)
258- else false))
259- then throw("Cannot register now")
260- else {
261- let regCost = parseIntValue(static[tStaticRegisterCost])
262- let wlgAmt = if ((regCost > 0))
263- then if ((size(i.payments) != 1))
264- then throw("exactly 1 payment must be attached")
265- else {
266- let pmt = i.payments[0]
267- if (if (!(isDefined(pmt.assetId)))
268- then true
269- else (value(pmt.assetId) != wlgAssetId))
270- then throw("WLGOLD payments only!")
271- else pmt.amount
272- }
273- else if ((size(i.payments) != 0))
274- then throw("No payments required")
275- else 0
276- if ((wlgAmt != regCost))
277- then throw((("Need payment of " + fixedPoint(regCost, 8)) + " WLGOLD"))
244+ if ((prologResult == prologResult))
245+ then {
246+ let lastId = valueOrErrorMessage(getInteger(lastTourIdKey), "No active tournaments")
247+ let now = lastBlock.timestamp
248+ let tData = getTourData(this, lastId)
249+ let static = tData[idxStatic]
250+ let dynamic = tData[idxDynamic]
251+ let status = dynamic[tDynamicStatus]
252+ if (!(if (if (if ((status == "CREATED"))
253+ then (now > parseIntValue(static[tStaticStart]))
254+ else false)
255+ then ((parseIntValue(static[tStaticEnd]) - HOUR) > now)
256+ else false)
257+ then true
258+ else if ((status == "INPROGRESS"))
259+ then ((parseIntValue(static[tStaticEnd]) - HOUR) > now)
260+ else false))
261+ then throw("Cannot register now")
278262 else {
279- let duckAssetId = duckByCaller(i.originCaller)
280- let scoreKey = keyScoreBoardByTour(lastId)
281- let oldScoreBoard = valueOrElse(getString(scoreKey), "")
282- if (if (valueOrElse(getBoolean(keyIsRegisteredByTourAndDuck(lastId, duckAssetId)), false))
283- then true
284- else contains(oldScoreBoard, duckAssetId))
285- then throw(((("Your duck " + duckAssetId) + " is already registered at tournament ") + toString(lastId)))
263+ let regCost = parseIntValue(static[tStaticRegisterCost])
264+ let wlgAmt = if ((regCost > 0))
265+ then if ((size(i.payments) != 1))
266+ then throw("exactly 1 payment must be attached")
267+ else {
268+ let pmt = i.payments[0]
269+ if (if (!(isDefined(pmt.assetId)))
270+ then true
271+ else (value(pmt.assetId) != wlgAssetId))
272+ then throw("WLGOLD payments only!")
273+ else pmt.amount
274+ }
275+ else if ((size(i.payments) != 0))
276+ then throw("No payments required")
277+ else 0
278+ if ((wlgAmt != regCost))
279+ then throw((("Need payment of " + fixedPoint(regCost, 8)) + " WLGOLD"))
286280 else {
287- let updatedDynamicData = dynamicData("INPROGRESS", dynamic[tDynamicLeaders], parseIntValue(dynamic[tDynamicWinResult]), (parseIntValue(dynamic[tDynamicTotalRegCount]) + 1), parseIntValue(dynamic[tDynamicTotalAttempts]))
288- $Tuple2([IntegerEntry(keyLastRegisteredTourByDuck(duckAssetId), lastId), BooleanEntry(keyIsRegisteredByTourAndDuck(lastId, duckAssetId), true), StringEntry(scoreKey, if ((oldScoreBoard == ""))
289- then (duckAssetId + ":000")
290- else (((oldScoreBoard + "_") + duckAssetId) + ":000")), StringEntry(keyTourDynamicDataById(lastId), updatedDynamicData)], prologResult)
281+ let duckAssetId = duckByCaller(i.originCaller)
282+ let scoreKey = keyScoreBoardByTour(lastId)
283+ let oldScoreBoard = valueOrElse(getString(scoreKey), "")
284+ if (if (valueOrElse(getBoolean(keyIsRegisteredByTourAndDuck(lastId, duckAssetId)), false))
285+ then true
286+ else contains(oldScoreBoard, duckAssetId))
287+ then throw(((("Your duck " + duckAssetId) + " is already registered at tournament ") + toString(lastId)))
288+ else {
289+ let updatedDynamicData = dynamicData("INPROGRESS", dynamic[tDynamicLeaders], parseIntValue(dynamic[tDynamicWinResult]), (parseIntValue(dynamic[tDynamicTotalRegCount]) + 1), parseIntValue(dynamic[tDynamicTotalAttempts]))
290+ $Tuple2([IntegerEntry(keyLastRegisteredTourByDuck(duckAssetId), lastId), BooleanEntry(keyIsRegisteredByTourAndDuck(lastId, duckAssetId), true), StringEntry(scoreKey, if ((oldScoreBoard == ""))
291+ then (duckAssetId + ":000")
292+ else (((oldScoreBoard + "_") + duckAssetId) + ":000")), StringEntry(keyTourDynamicDataById(lastId), updatedDynamicData)], prologResult)
293+ }
291294 }
292295 }
293296 }
297+ else throw("Strict value is not equal to itself.")
294298 }
295299
296300
298302 @Callable(i)
299303 func newAttempt () = {
300304 let prologResult = prolog()
301- let duckAssetId = duckByCaller(i.originCaller)
302- let lastId = valueOrErrorMessage(getInteger(lastTourIdKey), "No active tournaments")
303- let now = lastBlock.timestamp
304- let tData = getTourData(this, lastId)
305- let static = tData[idxStatic]
306- let dynamic = tData[idxDynamic]
307- let status = dynamic[tDynamicStatus]
308- if (!(if ((status == "INPROGRESS"))
309- then ((parseIntValue(static[tStaticEnd]) - HOUR) > now)
310- else false))
311- then throw("Attempt is not possible")
312- else if (!(valueOrElse(getBoolean(keyIsRegisteredByTourAndDuck(lastId, duckAssetId)), false)))
313- then throw(((("Your duck " + duckAssetId) + " is not registered at tournament ") + toString(lastId)))
314- else {
315- let attemptsIteratorKey = keyLastAttemptByTourAndDuck(lastId, duckAssetId)
316- let lastAttempt = getInteger(attemptsIteratorKey)
317- let $t063756966 = if (!(isDefined(lastAttempt)))
318- then $Tuple2(0, 0)
319- else if ((size(i.payments) != 1))
320- then throw("exactly 1 payment must be attached")
321- else {
322- let pmt = i.payments[0]
323- let wlgAmt = pmt.amount
324- if (if (!(isDefined(pmt.assetId)))
325- then true
326- else (value(pmt.assetId) != wlgAssetId))
327- then throw("WLGOLD payments only!")
305+ if ((prologResult == prologResult))
306+ then {
307+ let duckAssetId = duckByCaller(i.originCaller)
308+ let lastId = valueOrErrorMessage(getInteger(lastTourIdKey), "No active tournaments")
309+ let now = lastBlock.timestamp
310+ let tData = getTourData(this, lastId)
311+ let static = tData[idxStatic]
312+ let dynamic = tData[idxDynamic]
313+ let status = dynamic[tDynamicStatus]
314+ if (!(if ((status == "INPROGRESS"))
315+ then ((parseIntValue(static[tStaticEnd]) - HOUR) > now)
316+ else false))
317+ then throw("Attempt is not possible")
318+ else if (!(valueOrElse(getBoolean(keyIsRegisteredByTourAndDuck(lastId, duckAssetId)), false)))
319+ then throw(((("Your duck " + duckAssetId) + " is not registered at tournament ") + toString(lastId)))
320+ else {
321+ let attemptsIteratorKey = keyLastAttemptByTourAndDuck(lastId, duckAssetId)
322+ let lastAttempt = getInteger(attemptsIteratorKey)
323+ let $t063906981 = if (!(isDefined(lastAttempt)))
324+ then $Tuple2(0, 0)
325+ else if ((size(i.payments) != 1))
326+ then throw("exactly 1 payment must be attached")
328327 else {
329- let attCost = parseIntValue(static[tStaticAttemptCost])
330- if ((wlgAmt != attCost))
331- then throw((("Need payment of " + fixedPoint(attCost, 8)) + " WLGOLD"))
332- else $Tuple2((value(lastAttempt) + 1), 1)
328+ let pmt = i.payments[0]
329+ let wlgAmt = pmt.amount
330+ if (if (!(isDefined(pmt.assetId)))
331+ then true
332+ else (value(pmt.assetId) != wlgAssetId))
333+ then throw("WLGOLD payments only!")
334+ else {
335+ let attCost = parseIntValue(static[tStaticAttemptCost])
336+ if ((wlgAmt != attCost))
337+ then throw((("Need payment of " + fixedPoint(attCost, 8)) + " WLGOLD"))
338+ else $Tuple2((value(lastAttempt) + 1), 1)
339+ }
333340 }
334- }
335- let payedAttempts = $t063756966._1
336- let increment = $t063756966._2
337- let updatedDynamicData = dynamicData("INPROGRESS", dynamic[tDynamicLeaders], parseIntValue(dynamic[tDynamicWinResult]), parseIntValue(dynamic[tDynamicTotalRegCount]), (parseIntValue(dynamic[tDynamicTotalAttempts]) + increment))
338- let tourLoc = asString(invoke(stakingContract, "initDuckTourAttempt", [duckAssetId], nil))
339- $Tuple2([IntegerEntry(attemptsIteratorKey, payedAttempts), StringEntry(keyTourDynamicDataById(lastId), updatedDynamicData)], [prologResult, payedAttempts, tourLoc])
340- }
341+ let payedAttempts = $t063906981._1
342+ let increment = $t063906981._2
343+ let updatedDynamicData = dynamicData("INPROGRESS", dynamic[tDynamicLeaders], parseIntValue(dynamic[tDynamicWinResult]), parseIntValue(dynamic[tDynamicTotalRegCount]), (parseIntValue(dynamic[tDynamicTotalAttempts]) + increment))
344+ let tourLoc = asString(invoke(stakingContract, "initDuckTourAttempt", [duckAssetId], nil))
345+ $Tuple2([IntegerEntry(attemptsIteratorKey, payedAttempts), StringEntry(keyTourDynamicDataById(lastId), updatedDynamicData)], [prologResult, payedAttempts, tourLoc])
346+ }
347+ }
348+ else throw("Strict value is not equal to itself.")
341349 }
342350
343351
359367 let duckOldBest = valueOrElse(getInteger(bestResultKey), 0)
360368 let scoreKey = keyScoreBoardByTour(lastId)
361369 let oldScoreBoard = valueOrElse(getString(scoreKey), "")
362- let $t084599620 = if ((duckNewBest > duckOldBest))
370+ let $t084749635 = if ((duckNewBest > duckOldBest))
363371 then if (!(contains(oldScoreBoard, duckAssetId)))
364372 then throw(("scoreBoard does not contain " + duckAssetId))
365373 else {
382390 $Tuple3(((((parts[0] + duckAssetId) + ":") + padL(duckNewBest, 3)) + drop(parts[1], 4)), ((oldSumScores + duckNewBest) - duckOldBest), [StringEntry(keyTourDynamicDataById(lastId), updatedDynamicData)])
383391 }
384392 else $Tuple3(oldScoreBoard, oldSumScores, nil)
385- let newScoreBoard = $t084599620._1
386- let newSumScores = $t084599620._2
387- let globalActions = $t084599620._3
393+ let newScoreBoard = $t084749635._1
394+ let newSumScores = $t084749635._2
395+ let globalActions = $t084749635._3
388396 $Tuple2(([IntegerEntry(bestResultKey, max([duckOldBest, duckNewBest])), IntegerEntry(sumScoresKey, newSumScores), StringEntry(keyBestTxByTourAndDuck(lastId, duckAssetId), toBase58String(i.transactionId)), StringEntry(scoreKey, newScoreBoard)] ++ globalActions), 0)
389397 }
390398 else $Tuple2(nil, 0)
429437 @Callable(i)
430438 func claimPrize (tId) = {
431439 let prologResult = prolog()
432- if ((size(i.payments) != 0))
433- then throw("No payments required")
434- else {
435- let tData = getTourData(this, tId)
436- let static = tData[idxStatic]
437- let dynamic = tData[idxDynamic]
438- let status = dynamic[tDynamicStatus]
439- if ((status != "PROCESSING"))
440- then throw((("Tournament " + toString(tId)) + " is not PROCESSING"))
441- else {
442- let registrations = parseIntValue(dynamic[tDynamicTotalRegCount])
443- let paidAttempts = parseIntValue(dynamic[tDynamicTotalAttempts])
444- let regCost = parseIntValue(static[tStaticRegisterCost])
445- let attCost = parseIntValue(static[tStaticAttemptCost])
446- let prizeFund = if ((size(static) > tStaticPrizeFund))
447- then parseIntValue(static[tStaticPrizeFund])
448- else 0
449- let awardFunds = ((((registrations * regCost) + (paidAttempts * attCost)) / 2) + prizeFund)
450- let unpaidKey = keyUnpaidRewardsByTour(tId)
451- let unpaidFunds = valueOrElse(getInteger(unpaidKey), 0)
452- let duckAssetId = duckByCaller(i.originCaller)
453- if (!(valueOrElse(getBoolean(keyIsRegisteredByTourAndDuck(tId, duckAssetId)), false)))
454- then throw(((("Your duck " + duckAssetId) + " is not registered at tournament ") + toString(tId)))
455- else {
456- let bestResultKey = keyBestResultByTourAndDuck(tId, duckAssetId)
457- let duckBest = valueOrElse(getInteger(bestResultKey), 0)
458- if ((duckBest == 0))
459- then throw("Your duck got zero score")
460- else {
461- let awardedKey = keyIsAwardedByTourAndDuck(tId, duckAssetId)
462- if (valueOrElse(getBoolean(awardedKey), false))
463- then throw(((("Your duck " + duckAssetId) + " is already awarded at tournament ") + toString(tId)))
464- else {
465- let sumScoresKey = keySumScoresByTour(tId)
466- let sumScores = valueOrElse(getInteger(sumScoresKey), 0)
467- let leaders = dynamic[tDynamicLeaders]
468- let leadersList = if (if ((leaders == ""))
469- then true
470- else (leaders == " "))
471- then nil
472- else split_4C(leaders, ",")
473- let numLeaders = size(leadersList)
474- if ((numLeaders == 0))
475- then throw(("No leaders at tournament " + toString(tId)))
476- else {
477- let numGrands = parseIntValue(static[tStaticNumGrands])
478- let winResult = parseIntValue(dynamic[tDynamicWinResult])
479- let sumLeaderScores = if ((numLeaders > numGrands))
480- then 0
481- else if (containsElement(leadersList, duckAssetId))
482- then throw("As one of winners, you will be awarded by admins")
483- else (numLeaders * winResult)
484- let yourAmount = min([fraction(duckBest, awardFunds, (sumScores - sumLeaderScores)), unpaidFunds])
485- let newUnpaidAmount = (unpaidFunds - yourAmount)
486- let updatedDynamicData = dynamicData("ARCHIVED", dynamic[tDynamicLeaders], winResult, registrations, paidAttempts)
487- let archiveAction = if ((0 >= newUnpaidAmount))
488- then [StringEntry(keyTourDynamicDataById(tId), updatedDynamicData)]
489- else nil
490- $Tuple2(([ScriptTransfer(i.caller, yourAmount, wlgAssetId), BooleanEntry(awardedKey, true), IntegerEntry(unpaidKey, newUnpaidAmount)] ++ archiveAction), 0)
491- }
492- }
493- }
494- }
495- }
496- }
440+ if ((prologResult == prologResult))
441+ then if ((size(i.payments) != 0))
442+ then throw("No payments required")
443+ else {
444+ let tData = getTourData(this, tId)
445+ let static = tData[idxStatic]
446+ let dynamic = tData[idxDynamic]
447+ let status = dynamic[tDynamicStatus]
448+ if ((status != "PROCESSING"))
449+ then throw((("Tournament " + toString(tId)) + " is not PROCESSING"))
450+ else {
451+ let registrations = parseIntValue(dynamic[tDynamicTotalRegCount])
452+ let paidAttempts = parseIntValue(dynamic[tDynamicTotalAttempts])
453+ let regCost = parseIntValue(static[tStaticRegisterCost])
454+ let attCost = parseIntValue(static[tStaticAttemptCost])
455+ let prizeFund = if ((size(static) > tStaticPrizeFund))
456+ then parseIntValue(static[tStaticPrizeFund])
457+ else 0
458+ let awardFunds = ((((registrations * regCost) + (paidAttempts * attCost)) / 2) + prizeFund)
459+ let unpaidKey = keyUnpaidRewardsByTour(tId)
460+ let unpaidFunds = valueOrElse(getInteger(unpaidKey), 0)
461+ let duckAssetId = duckByCaller(i.originCaller)
462+ if (!(valueOrElse(getBoolean(keyIsRegisteredByTourAndDuck(tId, duckAssetId)), false)))
463+ then throw(((("Your duck " + duckAssetId) + " is not registered at tournament ") + toString(tId)))
464+ else {
465+ let bestResultKey = keyBestResultByTourAndDuck(tId, duckAssetId)
466+ let duckBest = valueOrElse(getInteger(bestResultKey), 0)
467+ if ((duckBest == 0))
468+ then throw("Your duck got zero score")
469+ else {
470+ let awardedKey = keyIsAwardedByTourAndDuck(tId, duckAssetId)
471+ if (valueOrElse(getBoolean(awardedKey), false))
472+ then throw(((("Your duck " + duckAssetId) + " is already awarded at tournament ") + toString(tId)))
473+ else {
474+ let sumScoresKey = keySumScoresByTour(tId)
475+ let sumScores = valueOrElse(getInteger(sumScoresKey), 0)
476+ let leaders = dynamic[tDynamicLeaders]
477+ let leadersList = if (if ((leaders == ""))
478+ then true
479+ else (leaders == " "))
480+ then nil
481+ else split_4C(leaders, ",")
482+ let numLeaders = size(leadersList)
483+ if ((numLeaders == 0))
484+ then throw(("No leaders at tournament " + toString(tId)))
485+ else {
486+ let numGrands = parseIntValue(static[tStaticNumGrands])
487+ let winResult = parseIntValue(dynamic[tDynamicWinResult])
488+ let sumLeaderScores = if ((numLeaders > numGrands))
489+ then 0
490+ else if (containsElement(leadersList, duckAssetId))
491+ then throw("As one of winners, you will be awarded by admins")
492+ else (numLeaders * winResult)
493+ let yourAmount = min([fraction(duckBest, awardFunds, (sumScores - sumLeaderScores)), unpaidFunds])
494+ let newUnpaidAmount = (unpaidFunds - yourAmount)
495+ let updatedDynamicData = dynamicData("ARCHIVED", dynamic[tDynamicLeaders], winResult, registrations, paidAttempts)
496+ let archiveAction = if ((0 >= newUnpaidAmount))
497+ then [StringEntry(keyTourDynamicDataById(tId), updatedDynamicData)]
498+ else nil
499+ $Tuple2(([ScriptTransfer(i.caller, yourAmount, wlgAssetId), BooleanEntry(awardedKey, true), IntegerEntry(unpaidKey, newUnpaidAmount)] ++ archiveAction), 0)
500+ }
501+ }
502+ }
503+ }
504+ }
505+ }
506+ else throw("Strict value is not equal to itself.")
497507 }
498508
499509
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let DEFAULTLOCATION = "Africa_F_Africa"
55
66 let locIdxContinent = 0
77
88 let locIdxType = 1
99
1010 func keyStakedDuckByOwner (ownerAddr) = ("stakedDuckByOwner_" + ownerAddr)
1111
1212
1313 func keyDuckLocation (duckAssetId) = ("duckLocation_" + duckAssetId)
1414
1515
1616 let lastTourIdKey = "%s__lastTourId"
1717
1818 func keyTourStaticDataById (tId) = ("%s%d__tourStaticData__" + toString(tId))
1919
2020
2121 func keyTourDynamicDataById (tId) = ("%s%d__tourDynamicData__" + toString(tId))
2222
2323
2424 func keyScoreBoardByTour (tId) = ("%s%d__scoreBoard__" + toString(tId))
2525
2626
2727 func keySumScoresByTour (tId) = ("%s%d__sumScores__" + toString(tId))
2828
2929
3030 func keyUnpaidRewardsByTour (tId) = ("%s%d__unpaidRewards__" + toString(tId))
3131
3232
3333 func keyLastRegisteredTourByDuck (duckAssetId) = ("%s%s__lastRegisteredTourByDuck__" + duckAssetId)
3434
3535
3636 func keyIsRegisteredByTourAndDuck (tId,duckAssetId) = makeString(["%s%d%s__isRegisteredByTourAndDuck", toString(tId), duckAssetId], "__")
3737
3838
3939 func keyIsAwardedByTourAndDuck (tId,duckAssetId) = makeString(["%s%d%s__isAwardedByTourAndDuck", toString(tId), duckAssetId], "__")
4040
4141
4242 func keyLastAttemptByTourAndDuck (tId,duckAssetId) = makeString(["%s%d%s__lastAttemptByTourAndDuck", toString(tId), duckAssetId], "__")
4343
4444
4545 func keyBestResultByTourAndDuck (tId,duckAssetId) = makeString(["%s%d%s__bestResultByTourAndDuck", toString(tId), duckAssetId], "__")
4646
4747
4848 func keyBestTxByTourAndDuck (tId,duckAssetId) = makeString(["%s%d%s__bestTxByTourAndDuck", toString(tId), duckAssetId], "__")
4949
5050
5151 let idxStatic = 0
5252
5353 let idxDynamic = 1
5454
5555 let tStaticRegisterCost = 2
5656
5757 let tStaticAttemptCost = 3
5858
5959 let tStaticStart = 5
6060
6161 let tStaticEnd = 6
6262
6363 let tStaticNumGrands = 7
6464
6565 let tStaticPrizeFund = 8
6666
6767 let tDynamicStatus = 1
6868
6969 let tDynamicLeaders = 2
7070
7171 let tDynamicWinResult = 3
7272
7373 let tDynamicTotalRegCount = 4
7474
7575 let tDynamicTotalAttempts = 5
7676
7777 func getTourData (tourContract,tId) = {
7878 let static = split(valueOrErrorMessage(getString(tourContract, keyTourStaticDataById(tId)), (("Error reading tournament " + toString(tId)) + " data")), "__")
7979 let dynamic = split_4C(valueOrErrorMessage(getString(tourContract, keyTourDynamicDataById(tId)), (("Error reading tournament " + toString(tId)) + " data")), "__")
8080 [static, dynamic]
8181 }
8282
8383
8484 func isInTournament (tourContract,location) = {
8585 let lastId = valueOrElse(getInteger(tourContract, lastTourIdKey), 0)
8686 let loc = split(location, "_")
8787 let now = lastBlock.timestamp
8888 let tData = getTourData(tourContract, lastId)
8989 let static = tData[idxStatic]
9090 let dynamic = tData[idxDynamic]
9191 if (if (if ((loc[locIdxType] == "T"))
9292 then (parseIntValue(loc[locIdxContinent]) == lastId)
9393 else false)
9494 then (dynamic[tDynamicStatus] == "INPROGRESS")
9595 else false)
9696 then (parseIntValue(static[tStaticEnd]) > now)
9797 else false
9898 }
9999
100100
101101 let chain = take(drop(this.bytes, 1), 1)
102102
103103 let defaultRestAddressStr = match chain {
104104 case _ =>
105105 if ((base58'2W' == $match0))
106106 then "3PQCuvFbvh4LkPUnrnU1z3jnbA1p9m3WNhv"
107107 else if ((base58'2T' == $match0))
108108 then "3MumkGGztCKAXpWDqxkddofqXSUbqQkvSJy"
109109 else throw("Unknown chain")
110110 }
111111
112112 let SEP = "__"
113113
114114 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
115115
116116
117117 let IdxCfgStakingDapp = 1
118118
119119 let IdxCfgWlgDapp = 4
120120
121121 func keyRestCfg () = "%s__restConfig"
122122
123123
124124 func keyRestAddress () = "%s__restAddr"
125125
126126
127127 func readRestCfgOrFail (rest) = split_4C(getStringOrFail(rest, keyRestCfg()), SEP)
128128
129129
130130 func getContractAddressOrFail (restCfg,idx) = valueOrErrorMessage(addressFromString(restCfg[idx]), ("Rest cfg doesn't contain address at index " + toString(idx)))
131131
132132
133133 let restContract = addressFromStringValue(valueOrElse(getString(this, keyRestAddress()), defaultRestAddressStr))
134134
135135 let restCfg = readRestCfgOrFail(restContract)
136136
137137 let stakingContract = getContractAddressOrFail(restCfg, IdxCfgStakingDapp)
138138
139139 let wlgContract = getContractAddressOrFail(restCfg, IdxCfgWlgDapp)
140140
141141 let wlgAssetIdKey = "wlg_assetId"
142142
143143 let wlgAssetId = valueOrErrorMessage(getBinary(wlgContract, wlgAssetIdKey), "WLGOLD is not issued yet")
144144
145145 func asString (v) = match v {
146146 case s: String =>
147147 s
148148 case _ =>
149149 throw("fail to cast into String")
150150 }
151151
152152
153153 func asInt (v) = match v {
154154 case n: Int =>
155155 n
156156 case _ =>
157157 throw("fail to cast into Int")
158158 }
159159
160160
161161 func fixedPoint (val,decimals) = {
162162 let tenPow = pow(10, 0, decimals, 0, 0, DOWN)
163163 let lowPart = toString((val % tenPow))
164164 let zeroes = drop(toString(tenPow), (1 + size(lowPart)))
165165 (((toString((val / tenPow)) + ".") + zeroes) + lowPart)
166166 }
167167
168168
169169 func padL (val,len) = {
170170 let valS = toString(val)
171171 let zeroes = drop(toString(pow(10, 0, (len - size(valS)), 0, 0, DOWN)), 1)
172172 (zeroes + valS)
173173 }
174174
175175
176-let MAXTOURNAMENTLENGTH = 432000000
176+let MAXTOURNAMENTLENGTH = 604800000
177177
178178 let HOUR = 3600000
179179
180180 let adminsList = [toString(this), match chain {
181181 case _ =>
182182 if ((base58'2W' == $match0))
183183 then "3PEe2RELUHCFCBsmSCNcBJ8N3URLVQende7"
184184 else if ((base58'2T' == $match0))
185185 then "3MtBgJTaLxPB3C7UJD1UE8qjkHthfKvFQYY"
186186 else throw("Unknown chain")
187187 }]
188188
189189 func staticData (txId,registerCost,attemptCost,creationTime,startTime,endTime,numGrands,prizeFund) = makeString(["%s%d%d%d%d%d%d%d", txId, toString(registerCost), toString(attemptCost), toString(creationTime), toString(startTime), toString(endTime), toString(numGrands), toString(prizeFund)], SEP)
190190
191191
192192 func dynamicData (status,leaders,winResult,totalRegs,totalAttempts) = makeString_2C(["%s%s%d%d%d", status, leaders, toString(winResult), toString(totalRegs), toString(totalAttempts)], SEP)
193193
194194
195-func prolog () = asInt(invoke(stakingContract, "saveLastTx", nil, nil))
195+func prolog () = asInt(reentrantInvoke(stakingContract, "saveLastTx", nil, nil))
196196
197197
198198 func duckByCaller (caller) = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(caller))), "You don't have a duck staked")
199199
200200
201201 @Callable(i)
202202 func createTournament (startTime,endTime,registerCost,attemptCost,numGrands,prizeFund) = {
203203 let caller = toString(i.caller)
204204 if (!(containsElement(adminsList, caller)))
205205 then throw("Permission denied")
206206 else {
207207 let lastId = getInteger(lastTourIdKey)
208208 let tId = if (isDefined(lastId))
209209 then {
210210 let lastTourId = value(lastId)
211211 let dynamic = valueOrErrorMessage(getString(keyTourDynamicDataById(lastTourId)), (("Error reading tournament " + toString(lastTourId)) + " data"))
212212 let status = split(dynamic, SEP)[tDynamicStatus]
213213 if (if ((status != "ARCHIVED"))
214214 then (status != "PROCESSING")
215215 else false)
216216 then throw(("Current tournement is not completed, status=" + status))
217217 else (lastTourId + 1)
218218 }
219219 else 1
220220 let now = lastBlock.timestamp
221221 if ((now > startTime))
222222 then throw(((("startTime=" + toString(startTime)) + " < creationTime=") + toString(now)))
223223 else if ((startTime > endTime))
224224 then throw(((("endTime=" + toString(endTime)) + " < startTime=") + toString(startTime)))
225225 else if (((endTime - startTime) > MAXTOURNAMENTLENGTH))
226226 then throw(((("Tournament period exceeds max: " + toString((endTime - startTime))) + " > ") + toString(MAXTOURNAMENTLENGTH)))
227227 else if (if ((0 > registerCost))
228228 then true
229229 else (0 > attemptCost))
230230 then throw(((("Cost should be positive, but passed " + toString(registerCost)) + " and ") + toString(attemptCost)))
231231 else if ((0 > numGrands))
232232 then throw("Number of Grand Prizes should be non-negative")
233233 else if ((0 > prizeFund))
234234 then throw("Prize Fund should be non-negative")
235235 else $Tuple2([IntegerEntry(lastTourIdKey, tId), StringEntry(keyTourStaticDataById(tId), staticData(toBase58String(i.transactionId), registerCost, attemptCost, now, startTime, endTime, numGrands, prizeFund)), StringEntry(keyTourDynamicDataById(tId), dynamicData("CREATED", " ", 0, 0, 0))], tId)
236236 }
237237 }
238238
239239
240240
241241 @Callable(i)
242242 func register () = {
243243 let prologResult = prolog()
244- let lastId = valueOrErrorMessage(getInteger(lastTourIdKey), "No active tournaments")
245- let now = lastBlock.timestamp
246- let tData = getTourData(this, lastId)
247- let static = tData[idxStatic]
248- let dynamic = tData[idxDynamic]
249- let status = dynamic[tDynamicStatus]
250- if (!(if (if (if ((status == "CREATED"))
251- then (now > parseIntValue(static[tStaticStart]))
252- else false)
253- then ((parseIntValue(static[tStaticEnd]) - HOUR) > now)
254- else false)
255- then true
256- else if ((status == "INPROGRESS"))
257- then ((parseIntValue(static[tStaticEnd]) - HOUR) > now)
258- else false))
259- then throw("Cannot register now")
260- else {
261- let regCost = parseIntValue(static[tStaticRegisterCost])
262- let wlgAmt = if ((regCost > 0))
263- then if ((size(i.payments) != 1))
264- then throw("exactly 1 payment must be attached")
265- else {
266- let pmt = i.payments[0]
267- if (if (!(isDefined(pmt.assetId)))
268- then true
269- else (value(pmt.assetId) != wlgAssetId))
270- then throw("WLGOLD payments only!")
271- else pmt.amount
272- }
273- else if ((size(i.payments) != 0))
274- then throw("No payments required")
275- else 0
276- if ((wlgAmt != regCost))
277- then throw((("Need payment of " + fixedPoint(regCost, 8)) + " WLGOLD"))
244+ if ((prologResult == prologResult))
245+ then {
246+ let lastId = valueOrErrorMessage(getInteger(lastTourIdKey), "No active tournaments")
247+ let now = lastBlock.timestamp
248+ let tData = getTourData(this, lastId)
249+ let static = tData[idxStatic]
250+ let dynamic = tData[idxDynamic]
251+ let status = dynamic[tDynamicStatus]
252+ if (!(if (if (if ((status == "CREATED"))
253+ then (now > parseIntValue(static[tStaticStart]))
254+ else false)
255+ then ((parseIntValue(static[tStaticEnd]) - HOUR) > now)
256+ else false)
257+ then true
258+ else if ((status == "INPROGRESS"))
259+ then ((parseIntValue(static[tStaticEnd]) - HOUR) > now)
260+ else false))
261+ then throw("Cannot register now")
278262 else {
279- let duckAssetId = duckByCaller(i.originCaller)
280- let scoreKey = keyScoreBoardByTour(lastId)
281- let oldScoreBoard = valueOrElse(getString(scoreKey), "")
282- if (if (valueOrElse(getBoolean(keyIsRegisteredByTourAndDuck(lastId, duckAssetId)), false))
283- then true
284- else contains(oldScoreBoard, duckAssetId))
285- then throw(((("Your duck " + duckAssetId) + " is already registered at tournament ") + toString(lastId)))
263+ let regCost = parseIntValue(static[tStaticRegisterCost])
264+ let wlgAmt = if ((regCost > 0))
265+ then if ((size(i.payments) != 1))
266+ then throw("exactly 1 payment must be attached")
267+ else {
268+ let pmt = i.payments[0]
269+ if (if (!(isDefined(pmt.assetId)))
270+ then true
271+ else (value(pmt.assetId) != wlgAssetId))
272+ then throw("WLGOLD payments only!")
273+ else pmt.amount
274+ }
275+ else if ((size(i.payments) != 0))
276+ then throw("No payments required")
277+ else 0
278+ if ((wlgAmt != regCost))
279+ then throw((("Need payment of " + fixedPoint(regCost, 8)) + " WLGOLD"))
286280 else {
287- let updatedDynamicData = dynamicData("INPROGRESS", dynamic[tDynamicLeaders], parseIntValue(dynamic[tDynamicWinResult]), (parseIntValue(dynamic[tDynamicTotalRegCount]) + 1), parseIntValue(dynamic[tDynamicTotalAttempts]))
288- $Tuple2([IntegerEntry(keyLastRegisteredTourByDuck(duckAssetId), lastId), BooleanEntry(keyIsRegisteredByTourAndDuck(lastId, duckAssetId), true), StringEntry(scoreKey, if ((oldScoreBoard == ""))
289- then (duckAssetId + ":000")
290- else (((oldScoreBoard + "_") + duckAssetId) + ":000")), StringEntry(keyTourDynamicDataById(lastId), updatedDynamicData)], prologResult)
281+ let duckAssetId = duckByCaller(i.originCaller)
282+ let scoreKey = keyScoreBoardByTour(lastId)
283+ let oldScoreBoard = valueOrElse(getString(scoreKey), "")
284+ if (if (valueOrElse(getBoolean(keyIsRegisteredByTourAndDuck(lastId, duckAssetId)), false))
285+ then true
286+ else contains(oldScoreBoard, duckAssetId))
287+ then throw(((("Your duck " + duckAssetId) + " is already registered at tournament ") + toString(lastId)))
288+ else {
289+ let updatedDynamicData = dynamicData("INPROGRESS", dynamic[tDynamicLeaders], parseIntValue(dynamic[tDynamicWinResult]), (parseIntValue(dynamic[tDynamicTotalRegCount]) + 1), parseIntValue(dynamic[tDynamicTotalAttempts]))
290+ $Tuple2([IntegerEntry(keyLastRegisteredTourByDuck(duckAssetId), lastId), BooleanEntry(keyIsRegisteredByTourAndDuck(lastId, duckAssetId), true), StringEntry(scoreKey, if ((oldScoreBoard == ""))
291+ then (duckAssetId + ":000")
292+ else (((oldScoreBoard + "_") + duckAssetId) + ":000")), StringEntry(keyTourDynamicDataById(lastId), updatedDynamicData)], prologResult)
293+ }
291294 }
292295 }
293296 }
297+ else throw("Strict value is not equal to itself.")
294298 }
295299
296300
297301
298302 @Callable(i)
299303 func newAttempt () = {
300304 let prologResult = prolog()
301- let duckAssetId = duckByCaller(i.originCaller)
302- let lastId = valueOrErrorMessage(getInteger(lastTourIdKey), "No active tournaments")
303- let now = lastBlock.timestamp
304- let tData = getTourData(this, lastId)
305- let static = tData[idxStatic]
306- let dynamic = tData[idxDynamic]
307- let status = dynamic[tDynamicStatus]
308- if (!(if ((status == "INPROGRESS"))
309- then ((parseIntValue(static[tStaticEnd]) - HOUR) > now)
310- else false))
311- then throw("Attempt is not possible")
312- else if (!(valueOrElse(getBoolean(keyIsRegisteredByTourAndDuck(lastId, duckAssetId)), false)))
313- then throw(((("Your duck " + duckAssetId) + " is not registered at tournament ") + toString(lastId)))
314- else {
315- let attemptsIteratorKey = keyLastAttemptByTourAndDuck(lastId, duckAssetId)
316- let lastAttempt = getInteger(attemptsIteratorKey)
317- let $t063756966 = if (!(isDefined(lastAttempt)))
318- then $Tuple2(0, 0)
319- else if ((size(i.payments) != 1))
320- then throw("exactly 1 payment must be attached")
321- else {
322- let pmt = i.payments[0]
323- let wlgAmt = pmt.amount
324- if (if (!(isDefined(pmt.assetId)))
325- then true
326- else (value(pmt.assetId) != wlgAssetId))
327- then throw("WLGOLD payments only!")
305+ if ((prologResult == prologResult))
306+ then {
307+ let duckAssetId = duckByCaller(i.originCaller)
308+ let lastId = valueOrErrorMessage(getInteger(lastTourIdKey), "No active tournaments")
309+ let now = lastBlock.timestamp
310+ let tData = getTourData(this, lastId)
311+ let static = tData[idxStatic]
312+ let dynamic = tData[idxDynamic]
313+ let status = dynamic[tDynamicStatus]
314+ if (!(if ((status == "INPROGRESS"))
315+ then ((parseIntValue(static[tStaticEnd]) - HOUR) > now)
316+ else false))
317+ then throw("Attempt is not possible")
318+ else if (!(valueOrElse(getBoolean(keyIsRegisteredByTourAndDuck(lastId, duckAssetId)), false)))
319+ then throw(((("Your duck " + duckAssetId) + " is not registered at tournament ") + toString(lastId)))
320+ else {
321+ let attemptsIteratorKey = keyLastAttemptByTourAndDuck(lastId, duckAssetId)
322+ let lastAttempt = getInteger(attemptsIteratorKey)
323+ let $t063906981 = if (!(isDefined(lastAttempt)))
324+ then $Tuple2(0, 0)
325+ else if ((size(i.payments) != 1))
326+ then throw("exactly 1 payment must be attached")
328327 else {
329- let attCost = parseIntValue(static[tStaticAttemptCost])
330- if ((wlgAmt != attCost))
331- then throw((("Need payment of " + fixedPoint(attCost, 8)) + " WLGOLD"))
332- else $Tuple2((value(lastAttempt) + 1), 1)
328+ let pmt = i.payments[0]
329+ let wlgAmt = pmt.amount
330+ if (if (!(isDefined(pmt.assetId)))
331+ then true
332+ else (value(pmt.assetId) != wlgAssetId))
333+ then throw("WLGOLD payments only!")
334+ else {
335+ let attCost = parseIntValue(static[tStaticAttemptCost])
336+ if ((wlgAmt != attCost))
337+ then throw((("Need payment of " + fixedPoint(attCost, 8)) + " WLGOLD"))
338+ else $Tuple2((value(lastAttempt) + 1), 1)
339+ }
333340 }
334- }
335- let payedAttempts = $t063756966._1
336- let increment = $t063756966._2
337- let updatedDynamicData = dynamicData("INPROGRESS", dynamic[tDynamicLeaders], parseIntValue(dynamic[tDynamicWinResult]), parseIntValue(dynamic[tDynamicTotalRegCount]), (parseIntValue(dynamic[tDynamicTotalAttempts]) + increment))
338- let tourLoc = asString(invoke(stakingContract, "initDuckTourAttempt", [duckAssetId], nil))
339- $Tuple2([IntegerEntry(attemptsIteratorKey, payedAttempts), StringEntry(keyTourDynamicDataById(lastId), updatedDynamicData)], [prologResult, payedAttempts, tourLoc])
340- }
341+ let payedAttempts = $t063906981._1
342+ let increment = $t063906981._2
343+ let updatedDynamicData = dynamicData("INPROGRESS", dynamic[tDynamicLeaders], parseIntValue(dynamic[tDynamicWinResult]), parseIntValue(dynamic[tDynamicTotalRegCount]), (parseIntValue(dynamic[tDynamicTotalAttempts]) + increment))
344+ let tourLoc = asString(invoke(stakingContract, "initDuckTourAttempt", [duckAssetId], nil))
345+ $Tuple2([IntegerEntry(attemptsIteratorKey, payedAttempts), StringEntry(keyTourDynamicDataById(lastId), updatedDynamicData)], [prologResult, payedAttempts, tourLoc])
346+ }
347+ }
348+ else throw("Strict value is not equal to itself.")
341349 }
342350
343351
344352
345353 @Callable(i)
346354 func saveDuckResult (duckAssetId,duckNewBest) = if ((i.caller != stakingContract))
347355 then throw("Access denied")
348356 else {
349357 let lastId = valueOrErrorMessage(getInteger(lastTourIdKey), "No active tournaments")
350358 let tData = getTourData(this, lastId)
351359 let static = tData[idxStatic]
352360 let dynamic = tData[idxDynamic]
353361 let curLocation = valueOrElse(getString(stakingContract, keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
354362 let bestResultKey = keyBestResultByTourAndDuck(lastId, duckAssetId)
355363 let sumScoresKey = keySumScoresByTour(lastId)
356364 let oldSumScores = valueOrElse(getInteger(sumScoresKey), 0)
357365 if (isInTournament(this, curLocation))
358366 then {
359367 let duckOldBest = valueOrElse(getInteger(bestResultKey), 0)
360368 let scoreKey = keyScoreBoardByTour(lastId)
361369 let oldScoreBoard = valueOrElse(getString(scoreKey), "")
362- let $t084599620 = if ((duckNewBest > duckOldBest))
370+ let $t084749635 = if ((duckNewBest > duckOldBest))
363371 then if (!(contains(oldScoreBoard, duckAssetId)))
364372 then throw(("scoreBoard does not contain " + duckAssetId))
365373 else {
366374 let oldBest = parseIntValue(dynamic[tDynamicWinResult])
367375 let leaders = dynamic[tDynamicLeaders]
368376 let oldLeadersList = if (if ((leaders == ""))
369377 then true
370378 else (leaders == " "))
371379 then nil
372380 else split_4C(leaders, ",")
373381 let newLeadersList = if ((duckNewBest > oldBest))
374382 then [duckAssetId]
375383 else if (if ((oldBest > duckNewBest))
376384 then true
377385 else containsElement(oldLeadersList, duckAssetId))
378386 then oldLeadersList
379387 else (oldLeadersList :+ duckAssetId)
380388 let updatedDynamicData = dynamicData("INPROGRESS", makeString_2C(newLeadersList, ","), max([duckNewBest, oldBest]), parseIntValue(dynamic[tDynamicTotalRegCount]), parseIntValue(dynamic[tDynamicTotalAttempts]))
381389 let parts = split_51C(oldScoreBoard, duckAssetId)
382390 $Tuple3(((((parts[0] + duckAssetId) + ":") + padL(duckNewBest, 3)) + drop(parts[1], 4)), ((oldSumScores + duckNewBest) - duckOldBest), [StringEntry(keyTourDynamicDataById(lastId), updatedDynamicData)])
383391 }
384392 else $Tuple3(oldScoreBoard, oldSumScores, nil)
385- let newScoreBoard = $t084599620._1
386- let newSumScores = $t084599620._2
387- let globalActions = $t084599620._3
393+ let newScoreBoard = $t084749635._1
394+ let newSumScores = $t084749635._2
395+ let globalActions = $t084749635._3
388396 $Tuple2(([IntegerEntry(bestResultKey, max([duckOldBest, duckNewBest])), IntegerEntry(sumScoresKey, newSumScores), StringEntry(keyBestTxByTourAndDuck(lastId, duckAssetId), toBase58String(i.transactionId)), StringEntry(scoreKey, newScoreBoard)] ++ globalActions), 0)
389397 }
390398 else $Tuple2(nil, 0)
391399 }
392400
393401
394402
395403 @Callable(i)
396404 func processTournament (tId) = {
397405 let caller = toString(i.caller)
398406 if (!(containsElement(adminsList, caller)))
399407 then throw("Permission denied")
400408 else {
401409 let now = lastBlock.timestamp
402410 let tData = getTourData(this, tId)
403411 let static = tData[idxStatic]
404412 let dynamic = tData[idxDynamic]
405413 let status = dynamic[tDynamicStatus]
406414 let registrations = parseIntValue(dynamic[tDynamicTotalRegCount])
407415 let paidAttempts = parseIntValue(dynamic[tDynamicTotalAttempts])
408416 let regCost = parseIntValue(static[tStaticRegisterCost])
409417 let attCost = parseIntValue(static[tStaticAttemptCost])
410418 if ((status == "ARCHIVED"))
411419 then throw((("Tournament " + toString(tId)) + " is already ARCHIVED"))
412420 else if (if ((status == "INPROGRESS"))
413421 then (parseIntValue(static[tStaticEnd]) > now)
414422 else false)
415423 then throw((("Tournament " + toString(tId)) + " is not over yet"))
416424 else {
417425 let updatedDynamicData = dynamicData("PROCESSING", dynamic[tDynamicLeaders], parseIntValue(dynamic[tDynamicWinResult]), registrations, paidAttempts)
418426 let prizeFund = if ((size(static) > tStaticPrizeFund))
419427 then parseIntValue(static[tStaticPrizeFund])
420428 else 0
421429 let unpaid = ((((registrations * regCost) + (paidAttempts * attCost)) / 2) + prizeFund)
422430 $Tuple2([StringEntry(keyTourDynamicDataById(tId), updatedDynamicData), IntegerEntry(keyUnpaidRewardsByTour(tId), unpaid)], 0)
423431 }
424432 }
425433 }
426434
427435
428436
429437 @Callable(i)
430438 func claimPrize (tId) = {
431439 let prologResult = prolog()
432- if ((size(i.payments) != 0))
433- then throw("No payments required")
434- else {
435- let tData = getTourData(this, tId)
436- let static = tData[idxStatic]
437- let dynamic = tData[idxDynamic]
438- let status = dynamic[tDynamicStatus]
439- if ((status != "PROCESSING"))
440- then throw((("Tournament " + toString(tId)) + " is not PROCESSING"))
441- else {
442- let registrations = parseIntValue(dynamic[tDynamicTotalRegCount])
443- let paidAttempts = parseIntValue(dynamic[tDynamicTotalAttempts])
444- let regCost = parseIntValue(static[tStaticRegisterCost])
445- let attCost = parseIntValue(static[tStaticAttemptCost])
446- let prizeFund = if ((size(static) > tStaticPrizeFund))
447- then parseIntValue(static[tStaticPrizeFund])
448- else 0
449- let awardFunds = ((((registrations * regCost) + (paidAttempts * attCost)) / 2) + prizeFund)
450- let unpaidKey = keyUnpaidRewardsByTour(tId)
451- let unpaidFunds = valueOrElse(getInteger(unpaidKey), 0)
452- let duckAssetId = duckByCaller(i.originCaller)
453- if (!(valueOrElse(getBoolean(keyIsRegisteredByTourAndDuck(tId, duckAssetId)), false)))
454- then throw(((("Your duck " + duckAssetId) + " is not registered at tournament ") + toString(tId)))
455- else {
456- let bestResultKey = keyBestResultByTourAndDuck(tId, duckAssetId)
457- let duckBest = valueOrElse(getInteger(bestResultKey), 0)
458- if ((duckBest == 0))
459- then throw("Your duck got zero score")
460- else {
461- let awardedKey = keyIsAwardedByTourAndDuck(tId, duckAssetId)
462- if (valueOrElse(getBoolean(awardedKey), false))
463- then throw(((("Your duck " + duckAssetId) + " is already awarded at tournament ") + toString(tId)))
464- else {
465- let sumScoresKey = keySumScoresByTour(tId)
466- let sumScores = valueOrElse(getInteger(sumScoresKey), 0)
467- let leaders = dynamic[tDynamicLeaders]
468- let leadersList = if (if ((leaders == ""))
469- then true
470- else (leaders == " "))
471- then nil
472- else split_4C(leaders, ",")
473- let numLeaders = size(leadersList)
474- if ((numLeaders == 0))
475- then throw(("No leaders at tournament " + toString(tId)))
476- else {
477- let numGrands = parseIntValue(static[tStaticNumGrands])
478- let winResult = parseIntValue(dynamic[tDynamicWinResult])
479- let sumLeaderScores = if ((numLeaders > numGrands))
480- then 0
481- else if (containsElement(leadersList, duckAssetId))
482- then throw("As one of winners, you will be awarded by admins")
483- else (numLeaders * winResult)
484- let yourAmount = min([fraction(duckBest, awardFunds, (sumScores - sumLeaderScores)), unpaidFunds])
485- let newUnpaidAmount = (unpaidFunds - yourAmount)
486- let updatedDynamicData = dynamicData("ARCHIVED", dynamic[tDynamicLeaders], winResult, registrations, paidAttempts)
487- let archiveAction = if ((0 >= newUnpaidAmount))
488- then [StringEntry(keyTourDynamicDataById(tId), updatedDynamicData)]
489- else nil
490- $Tuple2(([ScriptTransfer(i.caller, yourAmount, wlgAssetId), BooleanEntry(awardedKey, true), IntegerEntry(unpaidKey, newUnpaidAmount)] ++ archiveAction), 0)
491- }
492- }
493- }
494- }
495- }
496- }
440+ if ((prologResult == prologResult))
441+ then if ((size(i.payments) != 0))
442+ then throw("No payments required")
443+ else {
444+ let tData = getTourData(this, tId)
445+ let static = tData[idxStatic]
446+ let dynamic = tData[idxDynamic]
447+ let status = dynamic[tDynamicStatus]
448+ if ((status != "PROCESSING"))
449+ then throw((("Tournament " + toString(tId)) + " is not PROCESSING"))
450+ else {
451+ let registrations = parseIntValue(dynamic[tDynamicTotalRegCount])
452+ let paidAttempts = parseIntValue(dynamic[tDynamicTotalAttempts])
453+ let regCost = parseIntValue(static[tStaticRegisterCost])
454+ let attCost = parseIntValue(static[tStaticAttemptCost])
455+ let prizeFund = if ((size(static) > tStaticPrizeFund))
456+ then parseIntValue(static[tStaticPrizeFund])
457+ else 0
458+ let awardFunds = ((((registrations * regCost) + (paidAttempts * attCost)) / 2) + prizeFund)
459+ let unpaidKey = keyUnpaidRewardsByTour(tId)
460+ let unpaidFunds = valueOrElse(getInteger(unpaidKey), 0)
461+ let duckAssetId = duckByCaller(i.originCaller)
462+ if (!(valueOrElse(getBoolean(keyIsRegisteredByTourAndDuck(tId, duckAssetId)), false)))
463+ then throw(((("Your duck " + duckAssetId) + " is not registered at tournament ") + toString(tId)))
464+ else {
465+ let bestResultKey = keyBestResultByTourAndDuck(tId, duckAssetId)
466+ let duckBest = valueOrElse(getInteger(bestResultKey), 0)
467+ if ((duckBest == 0))
468+ then throw("Your duck got zero score")
469+ else {
470+ let awardedKey = keyIsAwardedByTourAndDuck(tId, duckAssetId)
471+ if (valueOrElse(getBoolean(awardedKey), false))
472+ then throw(((("Your duck " + duckAssetId) + " is already awarded at tournament ") + toString(tId)))
473+ else {
474+ let sumScoresKey = keySumScoresByTour(tId)
475+ let sumScores = valueOrElse(getInteger(sumScoresKey), 0)
476+ let leaders = dynamic[tDynamicLeaders]
477+ let leadersList = if (if ((leaders == ""))
478+ then true
479+ else (leaders == " "))
480+ then nil
481+ else split_4C(leaders, ",")
482+ let numLeaders = size(leadersList)
483+ if ((numLeaders == 0))
484+ then throw(("No leaders at tournament " + toString(tId)))
485+ else {
486+ let numGrands = parseIntValue(static[tStaticNumGrands])
487+ let winResult = parseIntValue(dynamic[tDynamicWinResult])
488+ let sumLeaderScores = if ((numLeaders > numGrands))
489+ then 0
490+ else if (containsElement(leadersList, duckAssetId))
491+ then throw("As one of winners, you will be awarded by admins")
492+ else (numLeaders * winResult)
493+ let yourAmount = min([fraction(duckBest, awardFunds, (sumScores - sumLeaderScores)), unpaidFunds])
494+ let newUnpaidAmount = (unpaidFunds - yourAmount)
495+ let updatedDynamicData = dynamicData("ARCHIVED", dynamic[tDynamicLeaders], winResult, registrations, paidAttempts)
496+ let archiveAction = if ((0 >= newUnpaidAmount))
497+ then [StringEntry(keyTourDynamicDataById(tId), updatedDynamicData)]
498+ else nil
499+ $Tuple2(([ScriptTransfer(i.caller, yourAmount, wlgAssetId), BooleanEntry(awardedKey, true), IntegerEntry(unpaidKey, newUnpaidAmount)] ++ archiveAction), 0)
500+ }
501+ }
502+ }
503+ }
504+ }
505+ }
506+ else throw("Strict value is not equal to itself.")
497507 }
498508
499509
500510
501511 @Callable(i)
502512 func awardLand (winnerAddress) = {
503513 let caller = toString(i.caller)
504514 if (!(containsElement(adminsList, caller)))
505515 then throw("Permission denied")
506516 else {
507517 let landAssetId = asString(invoke(stakingContract, "awardSLand", [winnerAddress], nil))
508518 $Tuple2(nil, landAssetId)
509519 }
510520 }
511521
512522

github/deemru/w8io/169f3d6 
76.44 ms