tx · 3nEMToSs3pKzGWEf1EzP2ixzKeehxPMfaEe7LGbHUabs

3PHKakPzqb1Cv5pus26WtncRXNFBY24ecuw:  -0.02700000 Waves

2023.09.30 19:10 [3844211] smart account 3PHKakPzqb1Cv5pus26WtncRXNFBY24ecuw > SELF 0.00000000 Waves

{ "type": 13, "id": "3nEMToSs3pKzGWEf1EzP2ixzKeehxPMfaEe7LGbHUabs", "fee": 2700000, "feeAssetId": null, "timestamp": 1696090254872, "version": 2, "chainId": 87, "sender": "3PHKakPzqb1Cv5pus26WtncRXNFBY24ecuw", "senderPublicKey": "GoRsyn2dKroV8yS3MeciCPbkFe8cqdhiXxrDFWDS6hGf", "proofs": [ "2viStGDJbttSjVtjimFVJJG761QtUuAdtf7txrE77SgkA5MZJMXTSpnRvDxLG2zBmU9U7fifS4pjPCVZdwexR86L" ], "script": "base64:BgI6CAISCAoGCAgICAgBEgASABIAEgMKAQQSAwoBBBIAEgMKAQESABIDCgEIEgQKAggBEgMKAQgSAwoBCDwAB1ZFUlNJT04CDVBaLTEuMC4xIFRFU1QAC3VzZG5Bc3NldElkASC2JinDBPXOU5GkDkt1JC9kjFGx+t+vVCm9SNIdKrKq0QANcHV6emxlQXNzZXRJZAEg8Rr+Jf72mTj0aSrE3+ES1keyxsoOujcJr3dtH46i5WMAC3VzZHRBc3NldElkASAelAcTUnahJZX9yGGogl8Qf986Tym7/JpGP1r9Nk+fkQAOdXNkdFBwdEFzc2V0SWQBIITaerIIAz9O0bvKju6Lk7zJgt0LXfoHlqjUI/moD/+5AA51c2RuQXNzZXRJZFN0cgIsREcyeEZrUGREd0tVb0JrekdBaFF0THBTR3pmWExpQ1lQRXplS0gyQWQyNHAAEHB1enpsZUFzc2V0SWRTdHICLEhFQjhRYXc5eHJXcFdzOHRIc2lBVFlHQldEQnRQMlM3a2NQQUxyTXU0M0FTAA51c2R0QXNzZXRJZFN0cgIsMzROOVljRUVUTFduOTNxWVE2NEVzUDF4ODl0U3J1SlU0NFJyRU1TWFhFUEoAEXVzZHRQcHRBc3NldElkU3RyAiw5d2MzTFhOQTRURUJzWHlLdG9MRTltcmJERDdXTUhYdlhyQ2padmFiTEFzaQAVc3VwcG9ydGVkRmVlQXNzZXRzU3RyCQDMCAICLERHMnhGa1BkRHdLVW9Ca3pHQWhRdExwU0d6ZlhMaUNZUEV6ZUtIMkFkMjRwCQDMCAICLEhFQjhRYXc5eHJXcFdzOHRIc2lBVFlHQldEQnRQMlM3a2NQQUxyTXU0M0FTCQDMCAICLDM0TjlZY0VFVExXbjkzcVlRNjRFc1AxeDg5dFNydUpVNDRSckVNU1hYRVBKCQDMCAICLDl3YzNMWE5BNFRFQnNYeUt0b0xFOW1yYkREN1dNSFh2WHJDalp2YWJMQXNpBQNuaWwAEXBhcmVudFBvb2xBZGRyZXNzCQEHQWRkcmVzcwEBGgFXkcbqKep5Zw/ZhO8ydpSzwHVC5DWDwdNYAA1tYXN0ZXJBZGRyZXNzCQEHQWRkcmVzcwEBGgFXzlfzJNEHpLNO/tK64iisxZCW1orRbQXuAAxtYXN0ZXJQdWJLZXkBIDs1TW4/n774VJyWRAeAVqsv4hNgRcR78j8XQ/RCBSZdAA1vcmFjbGVBZGRyZXNzCQEHQWRkcmVzcwEBGgFXSWbQy/OK9Vd6rfwhb3HFW4mIK9CBs7F/AA5zdGFraW5nQWRkcmVzcwkBB0FkZHJlc3MBARoBV5RojPnuormqn9b1jrypj2canAb0FimJuwALZmVlc0FkZHJlc3MJAQdBZGRyZXNzAQEaAVeU5ISHFWTLuQRB3aicpqg6P12UiNjZbxoAD3NodXRkb3duQWRkcmVzcwkBB0FkZHJlc3MBARoBV414U3qfFdI9lTSLgnlk2BnTJx6b8jVaqAENdHJ5R2V0SW50ZWdlcgEDa2V5BAckbWF0Y2gwCQCaCAIFBHRoaXMFA2tleQMJAAECBQckbWF0Y2gwAgNJbnQEAWIFByRtYXRjaDAFAWIAAAEMdHJ5R2V0QmluYXJ5AQNrZXkEByRtYXRjaDAJAJwIAgUEdGhpcwUDa2V5AwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAWIFByRtYXRjaDAFAWIBAAEMdHJ5R2V0U3RyaW5nAQNrZXkEByRtYXRjaDAJAJ0IAgUEdGhpcwUDa2V5AwkAAQIFByRtYXRjaDACBlN0cmluZwQBYgUHJG1hdGNoMAUBYgIAAQ5nZXRBc3NldFN0cmluZwEHYXNzZXRJZAQHJG1hdGNoMAUHYXNzZXRJZAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAFiBQckbWF0Y2gwCQDYBAEFAWICBVdBVkVTAQ1nZXRBc3NldEJ5dGVzAQphc3NldElkU3RyAwkAAAIFCmFzc2V0SWRTdHICBVdBVkVTBQR1bml0CQDZBAEFCmFzc2V0SWRTdHIBE2FkZEFzc2V0Qnl0ZXNUb0xpc3QCBWFjY3VtBGl0ZW0JAM4IAgUFYWNjdW0JAMwIAgkBDWdldEFzc2V0Qnl0ZXMBBQRpdGVtBQNuaWwBFGFkZEFzc2V0V2VpZ2h0VG9MaXN0AgVhY2N1bQRpdGVtCQDOCAIFBWFjY3VtCQDMCAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18JAQ5nZXRBc3NldFN0cmluZwEFBGl0ZW0CB193ZWlnaHQFA25pbAEWYWRkQXNzZXREZWNpbWFsc1RvTGlzdAIFYWNjdW0EaXRl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cm5lZEFzc2V0cwUIYXNzZXRJZHMBCmlzU2h1dGRvd24ABAckbWF0Y2gwCQCbCAIFD3NodXRkb3duQWRkcmVzcwILaXNfc2h1dGRvd24DCQABAgUHJG1hdGNoMAIHQm9vbGVhbgQBeAUHJG1hdGNoMAUBeAcBFmdldEN1cnJlbnRUb2tlbkJhbGFuY2UBCHRva2VuTnVtBAp0b2tlbklkU3RyCQEOZ2V0QXNzZXRTdHJpbmcBCQCRAwIFCGFzc2V0SWRzBQh0b2tlbk51bQkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHZ2xvYmFsXwUKdG9rZW5JZFN0cgIIX2JhbGFuY2UBCGdldEtNdWx0AAQHJG1hdGNoMAkAnwgBAgxzdGF0aWNfS011bHQDCQABAgUHJG1hdGNoMAIDSW50BAF4BQckbWF0Y2gwBQF4BQdTY2FsZTE2ARlnZXRWaXJ0dWFsUG9vbFRva2VuQW1vdW50AAkAawMJAQ10cnlHZXRJbnRlZ2VyAQIXZ2xvYmFsX3Bvb2xUb2tlbl9hbW91bnQJAQhnZXRLTXVsdAAFB1NjYWxlMTYBEGNhbGN1bGF0ZVBJc3N1ZWQCBmFtb3VudAd0b2tlbklkBAdQc3VwcGx5CQEZZ2V0VmlydHVhbFBvb2xUb2tlbkFtb3VudAAEB0JhbGFuY2UJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB2dsb2JhbF8JAQ5nZXRBc3NldFN0cmluZwEFB3Rva2VuSWQCCF9iYWxhbmNlCQBuBAUGYW1vdW50BQdQc3VwcGx5BQdCYWxhbmNlBQRET1dOAQ1nZXRNaW5QSXNzdWVkAQhwYXltZW50cwoBB2hhbmRsZXICBWFjY3VtB2N1cnJlbnQEB1BJc3N1ZWQJARBjYWxjdWxhdGVQSXNzdWVkAggFB2N1cnJlbnQGYW1vdW50CAUHY3VycmVudAdhc3NldElkAwkAAAIFB1BJc3N1ZWQAAAkAAgECJG9uZSBvZiB0aGUgdG9rZW5zIGFtb3VudHMgaXMgdG9vIGxvdwMDCQAAAgUFYWNjdW0AAAYJAGYCBQVhY2N1bQUHUElzc3VlZAUHUElzc3VlZAUFYWNjdW0ECW1pblBJc3NlZAoAAiRsBQhwYXltZW50cwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAAAAoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHaGFuZGxlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgUJbWluUElzc2VkARJjYWxjdWxhdGVVc2RuVmFsdWUEB2Fzc2V0SWQGYW1vdW50CGFCYWxhbmNlEGdpdmVuVXNkbkJhbGFuY2UECnVzZG5JblBvb2wJAM8IAgUIYXNzZXRJZHMFC3VzZG5Bc3NldElkBAxwdXp6bGVJblBvb2wJAM8IAgUIYXNzZXRJZHMFDXB1enpsZUFzc2V0SWQECnVzZHRJblBvb2wJAM8IAgUIYXNzZXRJZHMFC3VzZHRBc3NldElkBA11c2R0UHB0SW5Qb29sCQDPCAIFCGFzc2V0SWRzBQ51c2R0UHB0QXNzZXRJZAQLd2F2ZXNJblBvb2wJAM8IAgUIYXNzZXRJZHMFBHVuaXQEC2Fzc2V0V2VpZ2h0CQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfCQEOZ2V0QXNzZXRTdHJpbmcBBQdhc3NldElkAgdfd2VpZ2h0BAtmZWVBc3NldFN0cgkBDHRyeUdldFN0cmluZwECD3N0YXRpY19mZWVUb2tlbgMJAAACBQtmZWVBc3NldFN0cgUQcHV6emxlQXNzZXRJZFN0cgQMcHV6emxlV2VpZ2h0CQCRAwIFDUFzc2V0c1dlaWdodHMJAQV2YWx1ZQEJAM8IAgUIYXNzZXRJZHMFDXB1enpsZUFzc2V0SWQEDXB1enpsZUJhbGFuY2UJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB2dsb2JhbF8FEHB1enpsZUFzc2V0SWRTdHICCF9iYWxhbmNlBA5hbW91bnRJblB1enpsZQkAawMFBmFtb3VudAkAaQIFDXB1enpsZUJhbGFuY2UFDHB1enpsZVdlaWdodAkAaQIFCGFCYWxhbmNlBQthc3NldFdlaWdodAQLcHV6emxlUHJpY2UJARFAZXh0ck5hdGl2ZSgxMDUwKQIFEXBhcmVudFBvb2xBZGRyZXNzAhZnbG9iYWxfbGFzdFB1enpsZVByaWNlCQBrAwkAaAIFDmFtb3VudEluUHV6emxlBQtwdXp6bGVQcmljZQABBQZTY2FsZTgDCQAAAgULZmVlQXNzZXRTdHIFDnVzZHRBc3NldElkU3RyBAp1c2R0V2VpZ2h0CQCRAwIFDUFzc2V0c1dlaWdodHMJAQV2YWx1ZQEFCnVzZHRJblBvb2wEC3VzZHRCYWxhbmNlCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdnbG9iYWxfBQ51c2R0QXNzZXRJZFN0cgIIX2JhbGFuY2UJAGsDBQZhbW91bnQJAGkCBQt1c2R0QmFsYW5jZQUKdXNkdFdlaWdodAkAaQIFCGFCYWxhbmNlBQthc3NldFdlaWdodAMJAAACBQtmZWVBc3NldFN0cgURdXNkdFBwdEFzc2V0SWRTdHIECnVzZHRXZWlnaHQJAJEDAgUNQXNzZXRzV2VpZ2h0cwkBBXZhbHVlAQUNdXNkdFBwdEluUG9vbAQLdXNkdEJhbGFuY2UJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB2dsb2JhbF8FEXVzZHRQcHRBc3NldElkU3RyAghfYmFsYW5jZQkAawMFBmFtb3VudAkAaQIFC3VzZHRCYWxhbmNlBQp1c2R0V2VpZ2h0CQBpAgUIYUJhbGFuY2UFC2Fzc2V0V2VpZ2h0AwkAAAIFC2ZlZUFzc2V0U3RyBQ51c2RuQXNzZXRJZFN0cgQKdXNkbldlaWdodAkAkQMCBQ1Bc3NldHNXZWlnaHRzCQEFdmFsdWUBCQDPCAIFCGFzc2V0SWRzBQt1c2RuQXNzZXRJZAQLdXNkbkJhbGFuY2UEByRtYXRjaDAFEGdpdmVuVXNkbkJhbGFuY2UDCQABAgUHJG1hdGNoMAIDSW50BAF4BQckbWF0Y2gwBRBnaXZlblVzZG5CYWxhbmNlCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdnbG9iYWxfCQEOZ2V0QXNzZXRTdHJpbmcBBQt1c2RuQXNzZXRJZAIIX2JhbGFuY2UJAGsDBQZhbW91bnQJAGkCCQEFdmFsdWUBBQt1c2RuQmFsYW5jZQUKdXNkbldlaWdodAkAaQIFCGFCYWxhbmNlBQthc3NldFdlaWdodAQLd2F2ZXNXZWlnaHQAuBcECHdCYWxhbmNlCQBpAgkBDXRyeUdldEludGVnZXIBAhRnbG9iYWxfV0FWRVNfYmFsYW5jZQAyCQBrAwUGYW1vdW50CQBpAgUId0JhbGFuY2UFC3dhdmVzV2VpZ2h0CQBpAgUIYUJhbGFuY2UFC2Fzc2V0V2VpZ2h0ARJnZXRQcmljZUZyb21PcmFjbGUBCmFzc2V0SWRTdHIEByRtYXRjaDAJAJoIAgUNb3JhY2xlQWRkcmVzcwkArAICBQphc3NldElkU3RyAgdfdHdhcDVCAwkAAQIFByRtYXRjaDACA0ludAQBeAUHJG1hdGNoMAUBeAAAARFjYWxjdWxhdGVVc2RWYWx1ZQMHYXNzZXRJZAZhbW91bnQIYUJhbGFuY2UEC2Fzc2V0V2VpZ2h0CQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfCQEOZ2V0QXNzZXRTdHJpbmcBBQdhc3NldElkAgdfd2VpZ2h0BAtmZWVBc3NldFN0cgkBDHRyeUdldFN0cmluZwECD3N0YXRpY19mZWVUb2tlbgQNZmVlQXNzZXRTY2FsZQkBEUBleHRyTmF0aXZlKDEwNTApAgUEdGhpcwkArAICCQCsAgICB3N0YXRpY18FC2ZlZUFzc2V0U3RyAgZfc2NhbGUEC2ZlZUFzc2V0TnVtCQEFdmFsdWUBCQDPCAIFCGFzc2V0SWRzCQENZ2V0QXNzZXRCeXRlcwEFC2ZlZUFzc2V0U3RyBA5mZWVBc3NldFdlaWdodAkAkQMCBQ1Bc3NldHNXZWlnaHRzBQtmZWVBc3NldE51bQQPZmVlQXNzZXRCYWxhbmNlCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdnbG9iYWxfBQtmZWVBc3NldFN0cgIIX2JhbGFuY2UEDXZhbEluRmVlQXNzZXQJAGsDBQZhbW91bnQJAGkCBQ9mZWVBc3NldEJhbGFuY2UFDmZlZUFzc2V0V2VpZ2h0CQBpAgUIYUJhbGFuY2UFC2Fzc2V0V2VpZ2h0BA1mZWVBc3NldFByaWNlCQESZ2V0UHJpY2VGcm9tT3JhY2xlAQULZmVlQXNzZXRTdHIJAGsDBQ12YWxJbkZlZUFzc2V0BQ1mZWVBc3NldFByaWNlBQ1mZWVBc3NldFNjYWxlARNjaGVja1Rva2Vuc1ZhbGlkaXR5AQhwYXltZW50cwoBCGhhbmRsZXIxAgVhY2N1bQdwYXltZW50CQDOCAIFBWFjY3VtCQDMCAIIBQdwYXltZW50B2Fzc2V0SWQFA25pbAQDaWRzCgACJGwFCHBheW1lbnRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQhoYW5kbGVyMQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgMJAAACBQNpZHMFA2lkcwoBCGhhbmRsZXIyAgVhY2N1bQdhc3NldElkAwkBAiE9AgkAzwgCBQNpZHMFB2Fzc2V0SWQFBHVuaXQJAGQCBQVhY2N1bQABCQACAQkArAICAhRhc3NldCBub3QgYXR0YWNoZWQ6IAkBDmdldEFzc2V0U3RyaW5nAQUHYXNzZXRJZAQGY2hlY2tzCgACJGwFCGFzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAAACgEFJGY1XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQhoYW5kbGVyMgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNV8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjVfMgIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgMJAAACBQZjaGVja3MFBmNoZWNrcwYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BE2hhbmRsZVBvb2xUb2tlbnNBZGQEB1BJc3N1ZWQIcGF5bWVudHMLdXNlckFkZHJlc3MKbmVlZENoYW5nZQoBFWdldFRva2VuUGF5bWVudEFtb3VudAEHdG9rZW5JZAoBB2hhbmRsZXICBWFjY3VtB3BheW1lbnQDCQAAAggFB3BheW1lbnQHYXNzZXRJZAUHdG9rZW5JZAgFB3BheW1lbnQGYW1vdW50BQVhY2N1bQoAAiRsBQhwYXltZW50cwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAAAAoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHaGFuZGxlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgoBEWhhbmRsZVRva2VuQ2hhbmdlAgVhY2N1bQd0b2tlbklkBAJCawkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHZ2xvYmFsXwkBDmdldEFzc2V0U3RyaW5nAQUHdG9rZW5JZAIIX2JhbGFuY2UEB1BTdXBwbHkJARlnZXRWaXJ0dWFsUG9vbFRva2VuQW1vdW50AAQNdG9rZW5EZWNpbWFscwkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwkBDmdldEFzc2V0U3RyaW5nAQUHdG9rZW5JZAIGX3NjYWxlBAJEawkAbgQJAGUCCQBuBAkAZAIFB1BTdXBwbHkFB1BJc3N1ZWQFDXRva2VuRGVjaW1hbHMFB1BTdXBwbHkFB0NFSUxJTkcFDXRva2VuRGVjaW1hbHMFAkJrBQ10b2tlbkRlY2ltYWxzBQdDRUlMSU5HBA1wYXltZW50QW1vdW50CQEVZ2V0VG9rZW5QYXltZW50QW1vdW50AQUHdG9rZW5JZAQIdG9SZXR1cm4JAGUCAwkBAiE9AgUNcGF5bWVudEFtb3VudAAABQ1wYXltZW50QW1vdW50AAAFAkRrBAF0AwMFCm5lZWRDaGFuZ2UJAGYCBQh0b1JldHVybgAABwkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQt1c2VyQWRkcmVzcwUIdG9SZXR1cm4FB3Rva2VuSWQFA25pbAUDbmlsCQDOCAIJAM4IAgUFYWNjdW0FAXQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICAgdnbG9iYWxfCQEOZ2V0QXNzZXRTdHJpbmcBBQd0b2tlbklkAghfYmFsYW5jZQkAZAIFAkJrBQJEawUDbmlsCgACJGwFCGFzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARFoYW5kbGVUb2tlbkNoYW5nZQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgEWaGFuZGxlUG9vbFRva2Vuc1JlZGVlbQIJUFJlZGVlbWVkC3VzZXJBZGRyZXNzCgERaGFuZGxlVG9rZW5SZWRlZW0CBWFjY3VtB3Rva2VuSWQEAkJrCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdnbG9iYWxfCQEOZ2V0QXNzZXRTdHJpbmcBBQd0b2tlbklkAghfYmFsYW5jZQQHUFN1cHBseQkBGWdldFZpcnR1YWxQb29sVG9rZW5BbW91bnQABA10b2tlbkRlY2ltYWxzCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfCQEOZ2V0QXNzZXRTdHJpbmcBBQd0b2tlbklkAgZfc2NhbGUEBmFtb3VudAkAoAMBCQC9AgQJALgCAgkAtgIBBQZTY2FsZTgJAL0CBAkAtgIBCQBlAgUHUFN1cHBseQUJUFJlZGVlbWVkCQC2AgEFBlNjYWxlOAkAtgIBBQdQU3VwcGx5BQdDRUlMSU5HCQC2AgEFAkJrCQC2AgEFBlNjYWxlOAUERE9XTgkAzggCBQVhY2N1bQkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgICB2dsb2JhbF8JAQ5nZXRBc3NldFN0cmluZwEFB3Rva2VuSWQCCF9iYWxhbmNlCQBlAgUCQmsFBmFtb3VudAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQt1c2VyQWRkcmVzcwUGYW1vdW50BQd0b2tlbklkBQNuaWwKAAIkbAUIYXNzZXRJZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBEWhhbmRsZVRva2VuUmVkZWVtAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY0XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKARJjYWxjdWxhdGVPdXRBbW91bnQFCEFtb3VudEluB2Fzc2V0SW4IYXNzZXRPdXQJQmFsYW5jZUluCkJhbGFuY2VPdXQEB0luZGV4SW4JAQV2YWx1ZQEJAM8IAgUIYXNzZXRJZHMFB2Fzc2V0SW4ECEluZGV4T3V0CQEFdmFsdWUBCQDPCAIFCGFzc2V0SWRzBQhhc3NldE91dAMJAAACBQdJbmRleEluBQhJbmRleE91dAUIQW1vdW50SW4JAG4EBQpCYWxhbmNlT3V0CQBlAgkAaAIFBlNjYWxlOAUGU2NhbGU4CQCgAwEJAHYGCQC9AgQJALYCAQUJQmFsYW5jZUluCQC2AgEJAGgCBQZTY2FsZTgFBlNjYWxlOAkAtgIBCQBkAgUJQmFsYW5jZUluBQhBbW91bnRJbgUGSEFMRlVQABAJALYCAQkAawMJAJEDAgUNQXNzZXRzV2VpZ2h0cwUHSW5kZXhJbgCQTgkAkQMCBQ1Bc3NldHNXZWlnaHRzBQhJbmRleE91dAAEABAFB0NFSUxJTkcJAGgCBQZTY2FsZTgFBlNjYWxlOAUERE9XTgEPZ2V0VG9rZW5CYWxhbmNlAQdhc3NldElkBAckbWF0Y2gwBQdhc3NldElkAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAXQFByRtYXRjaDAJAPAHAgUEdGhpcwUBdAgJAO8HAQUEdGhpcwlhdmFpbGFibGUBHWNhbGN1bGF0ZUN1cnJlbnRBc3NldEludGVyZXN0BAdhc3NldElkCmFzc2V0SWRTdHIIYUJhbGFuY2UWdG9rZW5FYXJuaW5nc0xhc3RDaGVjawQLdG90YWxTdGFrZWQJAQ10cnlHZXRJbnRlZ2VyAQISZ2xvYmFsX2luZGV4U3Rha2VkBBV0b2tlbkJhbGFuY2VMYXN0Q2hlY2sFFnRva2VuRWFybmluZ3NMYXN0Q2hlY2sEE2N1cnJlbnRCYWxhbmNlRGVsdGEJAGUCCQEPZ2V0VG9rZW5CYWxhbmNlAQUHYXNzZXRJZAUIYUJhbGFuY2UEFGN1cnJlbnRUb2tlbkVhcm5pbmdzAwkAZgIFE2N1cnJlbnRCYWxhbmNlRGVsdGEFFXRva2VuQmFsYW5jZUxhc3RDaGVjawUTY3VycmVudEJhbGFuY2VEZWx0YQUVdG9rZW5CYWxhbmNlTGFzdENoZWNrBAtuZXdFYXJuaW5ncwkAZQIFFGN1cnJlbnRUb2tlbkVhcm5pbmdzBRV0b2tlbkJhbGFuY2VMYXN0Q2hlY2sEC25ld0ludGVyZXN0AwkAAAIFC3RvdGFsU3Rha2VkAAAAAAkAawMFC25ld0Vhcm5pbmdzBQZTY2FsZTgFC3RvdGFsU3Rha2VkBBFsYXN0Q2hlY2tJbnRlcmVzdAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIRZ2xvYmFsX2xhc3RDaGVja18FCmFzc2V0SWRTdHICCV9pbnRlcmVzdAkAZAIFEWxhc3RDaGVja0ludGVyZXN0BQtuZXdJbnRlcmVzdAELY2xhaW1SZXN1bHQBB2FkZHJlc3MECmFkZHJlc3NTdHIJAKUIAQUHYWRkcmVzcwQMcHV6emxlQW1vdW50CQENdHJ5R2V0SW50ZWdlcgEJAKwCAgUKYWRkcmVzc1N0cgIMX2luZGV4U3Rha2VkCgEHaGFuZGxlcgIFYWNjdW0HYXNzZXRJZAQKYXNzZXRJZFN0cgkBDmdldEFzc2V0U3RyaW5nAQUHYXNzZXRJZAQIYUJhbGFuY2UJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB2dsb2JhbF8JAQ5nZXRBc3NldFN0cmluZwEFB2Fzc2V0SWQCCF9iYWxhbmNlBBZ0b2tlbkVhcm5pbmdzTGFzdENoZWNrCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAhFnbG9iYWxfbGFzdENoZWNrXwUKYXNzZXRJZFN0cgIJX2Vhcm5pbmdzBBRjdXJyZW50VG9rZW5JbnRlcmVzdAkBHWNhbGN1bGF0ZUN1cnJlbnRBc3NldEludGVyZXN0BAUHYXNzZXRJZAUKYXNzZXRJZFN0cgUIYUJhbGFuY2UFFnRva2VuRWFybmluZ3NMYXN0Q2hlY2sEFGN1cnJlbnRUb2tlbkVhcm5pbmdzCQCWAwEJAMwIAgUWdG9rZW5FYXJuaW5nc0xhc3RDaGVjawkAzAgCCQBlAgkBD2dldFRva2VuQmFsYW5jZQEFB2Fzc2V0SWQFCGFCYWxhbmNlBQNuaWwEDHJld2FyZEFtb3VudAkAawMFDHB1enpsZUFtb3VudAkAZQIFFGN1cnJlbnRUb2tlbkludGVyZXN0CQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICCQCsAgIFCmFkZHJlc3NTdHICC19sYXN0Q2hlY2tfBQphc3NldElkU3RyAglfaW50ZXJlc3QFBlNjYWxlOAQIdHJhbnNmZXIDCQAAAgUMcmV3YXJkQW1vdW50AAAFA25pbAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQdhZGRyZXNzBQxyZXdhcmRBbW91bnQFB2Fzc2V0SWQFA25pbAkAlAoCCQDOCAIJAM4IAggFBWFjY3VtAl8xBQh0cmFuc2ZlcgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgICEWdsb2JhbF9sYXN0Q2hlY2tfBQphc3NldElkU3RyAglfZWFybmluZ3MJAGUCBRRjdXJyZW50VG9rZW5FYXJuaW5ncwUMcmV3YXJkQW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgIRZ2xvYmFsX2xhc3RDaGVja18FCmFzc2V0SWRTdHICCV9pbnRlcmVzdAUUY3VycmVudFRva2VuSW50ZXJlc3QJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICCQCsAgIFCmFkZHJlc3NTdHICC19sYXN0Q2hlY2tfBQphc3NldElkU3RyAglfaW50ZXJlc3QFFGN1cnJlbnRUb2tlbkludGVyZXN0BQNuaWwJAGQCCAUFYWNjdW0CXzIJARFjYWxjdWxhdGVVc2RWYWx1ZQMFB2Fzc2V0SWQFDHJld2FyZEFtb3VudAUIYUJhbGFuY2UEBWFjY3VtCgACJGwFDGVhcm5lZEFzc2V0cwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgUDbmlsAAAKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBB2hhbmRsZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY0XzICCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoJAJQKAgkAzggCCAUFYWNjdW0CXzEJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUKYWRkcmVzc1N0cgITX2NsYWltZWRSZXdhcmRWYWx1ZQkAZAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICBQphZGRyZXNzU3RyAhNfY2xhaW1lZFJld2FyZFZhbHVlCAUFYWNjdW0CXzIJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUKYWRkcmVzc1N0cgIKX2xhc3RDbGFpbQgFCWxhc3RCbG9jawl0aW1lc3RhbXAFA25pbAgFBWFjY3VtAl8yARBpbmRleFN0YWtlUmVzdWx0AgphZGRyZXNzU3RyBmFtb3VudAQCbGkICQELY2xhaW1SZXN1bHQBCQERQGV4dHJOYXRpdmUoMTA2MikBBQphZGRyZXNzU3RyAl8xCQDOCAIFAmxpCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFCmFkZHJlc3NTdHICDF9pbmRleFN0YWtlZAkAZAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICBQphZGRyZXNzU3RyAgxfaW5kZXhTdGFrZWQFBmFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgISZ2xvYmFsX2luZGV4U3Rha2VkCQBkAgkBDXRyeUdldEludGVnZXIBAhJnbG9iYWxfaW5kZXhTdGFrZWQFBmFtb3VudAUDbmlsAQNzdW0CBWFjY3VtAW4JAGQCBQVhY2N1bQkBDXBhcnNlSW50VmFsdWUBBQFuAQ1jaGVja0ZlZUFzc2V0AgVhY2N1bQRuZXh0AwMJAQIhPQIJAM8IAgUVc3VwcG9ydGVkRmVlQXNzZXRzU3RyBQRuZXh0BQR1bml0CQAAAgUFYWNjdW0CAAcFBG5leHQFBWFjY3VtDQFpAQdwcmVJbml0Bgthc3NldElkc1N0cg9hc3NldFdlaWdodHNTdHIOYmFzZVRva2VuSWRTdHIKcG9vbERvbWFpbglwb29sT3duZXIDZmVlBBBwb29sT3duZXJBZGRyZXNzCQEHQWRkcmVzcwEJANkEAQUJcG9vbE93bmVyBA1hc3NldElkc1N0ckxpCQC1CQIFC2Fzc2V0SWRzU3RyAgEsBAphc3NldElkc0xpCgACJGwFDWFzc2V0SWRzU3RyTGkKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBE2FkZEFzc2V0Qnl0ZXNUb0xpc3QCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY0XzICCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoEC2Zl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aXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmN18yAgkBBSRmN18xAgkBBSRmN18xAgkBBSRmN18xAgkBBSRmN18xAgkBBSRmN18xAgkBBSRmN18xAgkBBSRmN18xAgkBBSRmN18xAgkBBSRmN18xAgkBBSRmN18xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKCQDMCAIJAQtTdHJpbmdFbnRyeQICD3N0YXRpY190b2tlbklkcwULYXNzZXRJZHNTdHIJAMwIAgkBC1N0cmluZ0VudHJ5AgIPc3RhdGljX2ZlZVRva2VuBQtmZWVBc3NldFN0cgkAzAgCCQELU3RyaW5nRW50cnkCAhNzdGF0aWNfdG9rZW5XZWlnaHRzBQ9hc3NldFdlaWdodHNTdHIJAMwIAgkBDEludGVnZXJFbnRyeQICE3N0YXRpY190b2tlbnNBbW91bnQJAJADAQUKYXNzZXRJZHNMaQkAzAgCCQELU3RyaW5nRW50cnkCAhFzdGF0aWNfcG9vbERvbWFpbgUKcG9vbERvbWFpbgkAzAgCCQELU3RyaW5nRW50cnkCAhJzdGF0aWNfYmFzZVRva2VuSWQFDmJhc2VUb2tlbklkU3RyCQDMCAIJAQtTdHJpbmdFbnRyeQICEHN0YXRpY19wb29sT3duZXIFCXBvb2xPd25lcgkAzAgCCQEMSW50ZWdlckVudHJ5AgIKc3RhdGljX2ZlZQUDZmVlCQDMCAIJAQxJbnRlZ2VyRW50cnkCAgxzdGF0aWNfS011bHQFB1NjYWxlMTYFA25pbAFpAQZkZUluaXQAAwkBCmlzU2h1dGRvd24ACQACAQITY29udHJhY3QgaXMgb24gc3RvcAMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECCmFkbWluIG9ubHkJAMwIAgkBDEludGVnZXJFbnRyeQICEGdsb2JhbF93YXNJbml0ZWQAAAUDbmlsAWkBBGluaXQACgELcHJlcGFyZUxpc3QACgEHaGFuZGxlcgIFYWNjdW0BbgkAzggCBQVhY2N1bQkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgICB2dsb2JhbF8JAQ5nZXRBc3NldFN0cmluZwEIBQFuB2Fzc2V0SWQCCF9iYWxhbmNlCAUBbgZhbW91bnQFA25pbAoAAiRsCAUBaQhwYXltZW50cwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHaGFuZGxlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgoBGWNhbGN1bGF0ZVBvb2xUb2tlbnNBbW91bnQBCHBheW1lbnRzCgEHaGFuZGxlcgIFYWNjdW0DcG10BAdhc3NldElkCAUDcG10B2Fzc2V0SWQKAQhoYW5kbGVyMgIFYWNjdW0BbgMJAAACBQFuBQdhc3NldElkCQEFdmFsdWUBCQDPCAIFCGFzc2V0SWRzBQFuBQVhY2N1bQQFVG9rZW4KAAIkbAUIYXNzZXRJZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwAAEKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCGhhbmRsZXIyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY0XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKCQBrAwUFYWNjdW0JAGwGCAUDcG10BmFtb3VudAkAkQMCBQhEZWNpbWFscwUFVG9rZW4JAJEDAgUNQXNzZXRzV2VpZ2h0cwUFVG9rZW4FFUFzc2V0c1dlaWdodHNEZWNpbWFscwAIBQVGTE9PUgUGU2NhbGU4CgACJGwFCHBheW1lbnRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUOUG9vbFRva2VuU2NhbGUKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBB2hhbmRsZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY0XzICCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoDCQEKaXNTaHV0ZG93bgAJAAIBAhNjb250cmFjdCBpcyBvbiBzdG9wAwkAZgIJAQ10cnlHZXRJbnRlZ2VyAQIQZ2xvYmFsX3dhc0luaXRlZAAACQACAQITcG9vbCBhbHJlYWR5IGluaXRlZAQRaW5pdGlhbFBvb2xUb2tlbnMJARljYWxjdWxhdGVQb29sVG9rZW5zQW1vdW50AQgFAWkIcGF5bWVudHMDCQAAAgURaW5pdGlhbFBvb2xUb2tlbnMAAAkAAgECMnlvdSBuZWVkIGEgYmlnZ2VyIHRva2VucyBhbW91bnQgdG8gbGF1bmNoIHRoZSBwb29sBA5wb29sVG9rZW5Jc3N1ZQkAwwgHCQCsAgICA1BaIAkBDHRyeUdldFN0cmluZwECEXN0YXRpY19wb29sRG9tYWluAh1QdXp6bGUgU3dhcDogcG9vbCBpbmRleCB0b2tlbgURaW5pdGlhbFBvb2xUb2tlbnMFEVBvb2xUb2tlbkRlY2ltYWxzBgUEdW5pdAAABAtwb29sVG9rZW5JZAkAuAgBBQ5wb29sVG9rZW5Jc3N1ZQkAzggCCQELcHJlcGFyZUxpc3QACQDMCAIFDnBvb2xUb2tlbklzc3VlCQDMCAIJAQxJbnRlZ2VyRW50cnkCAhdnbG9iYWxfcG9vbFRva2VuX2Ftb3VudAURaW5pdGlhbFBvb2xUb2tlbnMJAMwIAgkBDEludGVnZXJFbnRyeQICEGdsb2JhbF93YXNJbml0ZWQAAQkAzAgCCQELQmluYXJ5RW50cnkCAhNnbG9iYWxfcG9vbFRva2VuX2lkBQtwb29sVG9rZW5JZAkAzAgCCQELU3RyaW5nRW50cnkCAhZzdGF0aWNfcG9vbFRva2VuX2lkU3RyCQEOZ2V0QXNzZXRTdHJpbmcBBQtwb29sVG9rZW5JZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQClCAEIBQFpBmNhbGxlcgIMX2luZGV4U3Rha2VkBRFpbml0aWFsUG9vbFRva2VucwkAzAgCCQEMSW50ZWdlckVudHJ5AgISZ2xvYmFsX2luZGV4U3Rha2VkBRFpbml0aWFsUG9vbFRva2VucwUDbmlsAWkBBXJlc2V0AAkAzAgCCQEMSW50ZWdlckVudHJ5AgIXZ2xvYmFsX3Bvb2xUb2tlbl9hbW91bnQAgISvXwkAzAgCCQEMSW50ZWdlckVudHJ5AgIUZ2xvYmFsX1dBVkVTX2JhbGFuY2UAgIjevgEJAMwIAgkBDEludGVnZXJFbnRyeQICO2dsb2JhbF9IRUI4UWF3OXhyV3BXczh0SHNpQVRZR0JXREJ0UDJTN2tjUEFMck11NDNBU19iYWxhbmNlAIDC1y8FA25pbAFpAQ1nZW5lcmF0ZUluZGV4AQpuZWVkQ2hhbmdlAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwUBVAkAAgEJAKwCAgI7eW91IG5lZWQgdG8gYXR0YWNoIGFsbCBwb29sIHRva2Vucy4gYW1vdW50IG9mIHBvb2wgdG9rZW5zOiAJAKQDAQUBVAMJAQEhAQkBE2NoZWNrVG9rZW5zVmFsaWRpdHkBCAUBaQhwYXltZW50cwkAAgECFXdyb25nIGFzc2V0cyBhdHRhY2hlZAQNUElzc3VlZE5vTXVsdAkBDWdldE1pblBJc3N1ZWQBCAUBaQhwYXltZW50cwQGcmVzdWx0CQETaGFuZGxlUG9vbFRva2Vuc0FkZAQFDVBJc3N1ZWROb011bHQIBQFpCHBheW1lbnRzCAUBaQxvcmlnaW5DYWxsZXIFCm5lZWRDaGFuZ2UED1BJc3N1ZWRXaXRoTXVsdAkAawMFDVBJc3N1ZWROb011bHQFB1NjYWxlMTYJAQhnZXRLTXVsdAAEB3JlaXNzdWUJAQdSZWlzc3VlAwkBEUBleHRyTmF0aXZlKDEwNTcpAQITZ2xvYmFsX3Bvb2xUb2tlbl9pZAUPUElzc3VlZFdpdGhNdWx0BgkAlAoCCQDOCAIFBnJlc3VsdAkAzAgCBQdyZWlzc3VlCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgUPUElzc3VlZFdpdGhNdWx0CQEMdHJ5R2V0QmluYXJ5AQITZ2xvYmFsX3Bvb2xUb2tlbl9pZAkAzAgCCQEMSW50ZWdlckVudHJ5AgIXZ2xvYmFsX3Bvb2xUb2tlbl9hbW91bnQJAGQCCQENdHJ5R2V0SW50ZWdlcgECF2dsb2JhbF9wb29sVG9rZW5fYW1vdW50BQ9QSXNzdWVkV2l0aE11bHQFA25pbAUPUElzc3VlZFdpdGhNdWx0AWkBC3JlZGVlbUluZGV4AQxzZW5kVG9PcmlnaW4EA3BtdAkAkQMCCAUBaQhwYXltZW50cwAAAwkBAiE9AggFA3BtdAdhc3NldElkCQEMdHJ5R2V0QmluYXJ5AQITZ2xvYmFsX3Bvb2xUb2tlbl9pZAkAAgECHnBsZWFzZSBhdHRhY2ggcG9vbCBzaGFyZSB0b2tlbgMJAQppc1NodXRkb3duAAkAAgECE2NvbnRyYWN0IGlzIG9uIHN0b3AEEVBSZWRlZW1lZFdpdGhNdWx0CAUDcG10BmFtb3VudAQTUFJlZGVlbWVkV2l0aE5vTXVsdAkAawMFEVBSZWRlZW1lZFdpdGhNdWx0CQEIZ2V0S011bHQABQdTY2FsZTE2BAZyZXN1bHQJARZoYW5kbGVQb29sVG9rZW5zUmVkZWVtAgUTUFJlZGVlbWVkV2l0aE5vTXVsdAMFDHNlbmRUb09yaWdpbggFAWkMb3JpZ2luQ2FsbGVyCAUBaQZjYWxsZXIJAM4IAgUGcmVzdWx0CQDMCAIJAQRCdXJuAgkBDHRyeUdldEJpbmFyeQECE2dsb2JhbF9wb29sVG9rZW5faWQFEVBSZWRlZW1lZFdpdGhNdWx0CQDMCAIJAQxJbnRlZ2VyRW50cnkCAhdnbG9iYWxfcG9vbFRva2VuX2Ftb3VudAkAZQIJAQ10cnlHZXRJbnRlZ2VyAQIXZ2xvYmFsX3Bvb2xUb2tlbl9hbW91bnQFEVBSZWRlZW1lZFdpdGhNdWx0BQNuaWwBaQEKc3Rha2VJbmRleAAECmFkZHJlc3NTdHIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBANwbXQJAJEDAggFAWkIcGF5bWVudHMAAAMJAQIhPQIJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAkBDHRyeUdldEJpbmFyeQECE2dsb2JhbF9wb29sVG9rZW5faWQJAAIBAhR3cm9uZyBhc3NldCBhdHRhY2hlZAkBEGluZGV4U3Rha2VSZXN1bHQCBQphZGRyZXNzU3RyCAUDcG10BmFtb3VudAFpAQx1bnN0YWtlSW5kZXgBC2luZGV4QW1vdW50BAphZGRyZXNzU3RyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQOaW5kZXhBdmFpbGFibGUJAQ10cnlHZXRJbnRlZ2VyAQkArAICBQphZGRyZXNzU3RyAgxfaW5kZXhTdGFrZWQDCQEKaXNTaHV0ZG93bgAJAAIBAhNjb250cmFjdCBpcyBvbiBzdG9wAwkAZgIFC2luZGV4QW1vdW50BQ5pbmRleEF2YWlsYWJsZQkAAgECJXlvdSBkb24ndCBoYXZlIGluZGV4IHRva2VucyBhdmFpbGFibGUDCQEKaXNTaHV0ZG93bgAJAAIBAhNjb250cmFjdCBpcyBvbiBzdG9wCQDOCAIICQELY2xhaW1SZXN1bHQBCAUBaQxvcmlnaW5DYWxsZXICXzEJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUKYWRkcmVzc1N0cgIMX2luZGV4U3Rha2VkCQBlAgUOaW5kZXhBdmFpbGFibGUFC2luZGV4QW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCAhJnbG9iYWxfaW5kZXhTdGFrZWQJAGUCCQENdHJ5R2V0SW50ZWdlcgECEmdsb2JhbF9pbmRleFN0YWtlZAULaW5kZXhBbW91bnQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQtpbmRleEFtb3VudAkBEUBleHRyTmF0aXZlKDEwNTcpAQITZ2xvYmFsX3Bvb2xUb2tlbl9pZAUDbmlsAWkBEWNsYWltSW5kZXhSZXdhcmRzAAMJAQppc1NodXRkb3duAAkAAgECE2NvbnRyYWN0IGlzIG9uIHN0b3AJAQtjbGFpbVJlc3VsdAEIBQFpBmNhbGxlcgFpAQ1ldmFsdWF0ZUNsYWltAQR1c2VyCQCUCgIFA25pbAgJAQtjbGFpbVJlc3VsdAEJARFAZXh0ck5hdGl2ZSgxMDYyKQEFBHVzZXICXzIBaQEEc3dhcAIIYXNzZXRPdXQHbWluaW11bQQDcG10AwkAAAIJAJADAQgFAWkIcGF5bWVudHMAAQkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAACQACAQIhcGxlYXNlIGF0dGFjaCBleGFjdGx5IG9uZSBwYXltZW50BAhBbW91bnRJbgkBBXZhbHVlAQgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQEB0Fzc2V0SW4IBQNwbXQHYXNzZXRJZAQIQXNzZXRPdXQJAQ1nZXRBc3NldEJ5dGVzAQUIYXNzZXRPdXQEDmZlZUFzc2V0T3V0U3RyCQEMdHJ5R2V0U3RyaW5nAQIPc3RhdGljX2ZlZVRva2VuBAtmZWVBc3NldE91dAMJAAACBQ5mZWVBc3NldE91dFN0cgIABQt1c2RuQXNzZXRJZAkBDWdldEFzc2V0Qnl0ZXMBBQ5mZWVBc3NldE91dFN0cgQOQXNzZXRJbkJhbGFuY2UJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB2dsb2JhbF8JAQ5nZXRBc3NldFN0cmluZwEFB0Fzc2V0SW4CCF9iYWxhbmNlBA9Bc3NldE91dEJhbGFuY2UJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB2dsb2JhbF8FCGFzc2V0T3V0AghfYmFsYW5jZQQLZmVlQW1vdW50SW4JAGsDBQhBbW91bnRJbgUDRmVlBQhGZWVTY2FsZQQNY2xlYW5BbW91bnRJbgkAZQIFCEFtb3VudEluBQtmZWVBbW91bnRJbgQJQW1vdW50T3V0CQESY2FsY3VsYXRlT3V0QW1vdW50BQUNY2xlYW5BbW91bnRJbgUHQXNzZXRJbgUIQXNzZXRPdXQFDkFzc2V0SW5CYWxhbmNlBQ9Bc3NldE91dEJhbGFuY2UEEEFzc2V0T3V0QmFsYW5jZTIJAGUCBQ9Bc3NldE91dEJhbGFuY2UFCUFtb3VudE91dAQPQXNzZXRJbkJhbGFuY2UyCQBkAgUOQXNzZXRJbkJhbGFuY2UFDWNsZWFuQW1vdW50SW4EEmZlZUFzc2V0T3V0QmFsYW5jZQMJAAACBQtmZWVBc3NldE91dAUHQXNzZXRJbgUPQXNzZXRJbkJhbGFuY2UyAwkAAAIFC2ZlZUFzc2V0T3V0BQhBc3NldE91dAUQQXNzZXRPdXRCYWxhbmNlMgkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHZ2xvYmFsXwkBDmdldEFzc2V0U3RyaW5nAQULZmVlQXNzZXRPdXQCCF9iYWxhbmNlBAxmZWVBbW91bnRPdXQJARJjYWxjdWxhdGVPdXRBbW91bnQFBQtmZWVBbW91bnRJbgUHQXNzZXRJbgULZmVlQXNzZXRPdXQFDkFzc2V0SW5CYWxhbmNlBRJmZWVBc3NldE91dEJhbGFuY2UDCQBmAgUHbWluaW11bQUJQW1vdW50T3V0CQACAQIpYW1vdW50IHRvIHJlY2lldmUgaXMgbG93ZXIgdGhhbiBnaXZlbiBvbmUDCQAAAgUIQXNzZXRPdXQFB0Fzc2V0SW4JAAIBAhh0aGlzIHN3YXAgaXMgbm90IGFsbG93ZWQDCQBmAgAACQBlAgUPQXNzZXRPdXRCYWxhbmNlBQlBbW91bnRPdXQJAAIBAhtjb250cmFjdCBpcyBvdXQgb2YgcmVzZXJ2ZXMDCQEKaXNTaHV0ZG93bgAJAAIBAhNjb250cmFjdCBpcyBvbiBzdG9wBApjcmVhdG9yRmVlCQBrAwUMZmVlQW1vdW50T3V0AAEACgQLcHJvdG9jb2xGZWUJAGsDBQxmZWVBbW91bnRPdXQABAAKBAxzdGFraW5nVG9wVXADAwkAAAIFC2ZlZUFzc2V0T3V0BQt1c2RuQXNzZXRJZAYJAAACBQtmZWVBc3NldE91dAUNcHV6emxlQXNzZXRJZAkA/QcEBQ5zdGFraW5nQWRkcmVzcwILdG9wVXBSZXdhcmQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgULZmVlQXNzZXRPdXQFC3Byb3RvY29sRmVlBQNuaWwFBHVuaXQDCQAAAgUMc3Rha2luZ1RvcFVwBQxzdGFraW5nVG9wVXAEDG5ld0JhbGFuY2VJbgUPQXNzZXRJbkJhbGFuY2UyBA1uZXdCYWxhbmNlT3V0CQBlAgUQQXNzZXRPdXRCYWxhbmNlMgMJAAACBQhBc3NldE91dAULZmVlQXNzZXRPdXQFDGZlZUFtb3VudE91dAAABBJuZXdCYWxhbmNlRmVlQXNzZXQDAwkBAiE9AgULZmVlQXNzZXRPdXQFB0Fzc2V0SW4JAQIhPQIFC2ZlZUFzc2V0T3V0BQhBc3NldE91dAcJAGUCBRJmZWVBc3NldE91dEJhbGFuY2UFDGZlZUFtb3VudE91dAUEdW5pdAQNYXNzZXRJbkNoYW5nZQkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICAgdnbG9iYWxfCQEOZ2V0QXNzZXRTdHJpbmcBBQdBc3NldEluAghfYmFsYW5jZQUMbmV3QmFsYW5jZUluBA5hc3NldE91dENoYW5nZQkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICAgdnbG9iYWxfBQhhc3NldE91dAIIX2JhbGFuY2UFDW5ld0JhbGFuY2VPdXQEEWZlZUFzc2V0T3V0Q2hhbmdlAwkBAiE9AgUSbmV3QmFsYW5jZUZlZUFzc2V0BQR1bml0CQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgICB2dsb2JhbF8JAQ5nZXRBc3NldFN0cmluZwEFC2ZlZUFzc2V0T3V0AghfYmFsYW5jZQkBBXZhbHVlAQUSbmV3QmFsYW5jZUZlZUFzc2V0CQELU3RyaW5nRW50cnkCAgVoZWxsbwIFd29ybGQEDHZvbHVtZVVwZGF0ZQkBEmNhbGN1bGF0ZVVzZG5WYWx1ZQQFB0Fzc2V0SW4FCEFtb3VudEluBQ5Bc3NldEluQmFsYW5jZQUSZmVlQXNzZXRPdXRCYWxhbmNlBA92b2x1bWVVc2RVcGRhdGUJARFjYWxjdWxhdGVVc2RWYWx1ZQMFB0Fzc2V0SW4FCEFtb3VudEluBQ5Bc3NldEluQmFsYW5jZQkAlAoCCQDOCAIJAMwIAgUOYXNzZXRPdXRDaGFuZ2UJAMwIAgUNYXNzZXRJbkNoYW5nZQkAzAgCBRFmZWVBc3NldE91dENoYW5nZQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFCUFtb3VudE91dAUIQXNzZXRPdXQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwkBEUBleHRyTmF0aXZlKDEwNjIpAQkBDHRyeUdldFN0cmluZwECEHN0YXRpY19wb29sT3duZXIFCmNyZWF0b3JGZWUFC2ZlZUFzc2V0T3V0CQDMCAIJAQxJbnRlZ2VyRW50cnkCAhRnbG9iYWxfZWFybmVkQnlPd25lcgkAZAIJAQ10cnlHZXRJbnRlZ2VyAQIUZ2xvYmFsX2Vhcm5lZEJ5T3duZXIFCmNyZWF0b3JGZWUJAMwIAgkBDEludGVnZXJFbnRyeQICDWdsb2JhbF92b2x1bWUJAGQCCQENdHJ5R2V0SW50ZWdlcgECDWdsb2JhbF92b2x1bWUFDHZvbHVtZVVwZGF0ZQkAzAgCCQEMSW50ZWdlckVudHJ5AgIRZ2xvYmFsX3ZvbHVtZV91c2QJAGQCCQENdHJ5R2V0SW50ZWdlcgECEWdsb2JhbF92b2x1bWVfdXNkBQ92b2x1bWVVc2RVcGRhdGUFA25pbAMJAAACBQxzdGFraW5nVG9wVXAFBHVuaXQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwULZmVlc0FkZHJlc3MFC3Byb3RvY29sRmVlBQtmZWVBc3NldE91dAUDbmlsBQNuaWwFCUFtb3VudE91dAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARF0cmFuc2Zlck93bmVyc2hpcAEPbmV3T3duZXJBZGRyZXNzAwkBAiE9AgkApQgBCAUBaQZjYWxsZXIJAQx0cnlHZXRTdHJpbmcBAhBzdGF0aWNfcG9vbE93bmVyCQACAQIndGhpcyBjYWxsIGF2YWlsYWJsZSBvbmx5IGZvciBwb29sIG93bmVyCQDMCAIJAQtTdHJpbmdFbnRyeQICEHN0YXRpY19wb29sT3duZXIFD25ld093bmVyQWRkcmVzcwUDbmlsAWkBDWRvUmViYWxhbmNpbmcBD2Fzc2V0V2VpZ2h0c1N0cgQRYXNzZXRXZWlnaHRzU3RyTGkJALUJAgUPYXNzZXRXZWlnaHRzU3RyAgEsBA9hc3NldFdlaWdodHNTdW0KAAIkbAURYXNzZXRXZWlnaHRzU3RyTGkKAAIkcwkAkAMBBQIkbAoABSRhY2MwAAAKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBA3N1bQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgQNYXNzZXRJZHNTdHJMaQkAtQkCCQEMdHJ5R2V0U3RyaW5nAQIPc3RhdGljX3Rva2VuSWRzAgEsAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIidGhpcyBjYWxsIGF2YWlsYWJsZSBvbmx5IGZvciBhZG1pbgMJAQIhPQIFD2Fzc2V0V2VpZ2h0c1N1bQCQTgkAAgECK3N1bSBvZiB0b2tlbiB3ZWlnaHRzIG11c3QgYmUgZXF1YWwgdG8gMTAwMDAECG9sZEtNdWx0CQEIZ2V0S011bHQACgEHaGFuZGxlcgIEcGFycwdhc3NldElkBAVhY2N1bQgFBHBhcnMCXzEECmFzc2V0SWRTdHIJAQ5nZXRBc3NldFN0cmluZwEFB2Fzc2V0SWQKAQhoYW5kbGVyMgIFYWNjdW0BbgMJAAACBQFuBQdhc3NldElkCQEFdmFsdWUBCQDPCAIFCGFzc2V0SWRzBQFuBQVhY2N1bQQFVG9rZW4KAAIkbAUIYXNzZXRJZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwAAEKAQUkZjVfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCGhhbmRsZXIyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY1XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNV8yAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKBAdiYWxhbmNlCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdnbG9iYWxfBQphc3NldElkU3RyAghfYmFsYW5jZQQGd2VpZ2h0AwkAAAIIBQRwYXJzAl8yAgNuZXcJAQ1wYXJzZUludFZhbHVlAQkAkQMCBRFhc3NldFdlaWdodHNTdHJMaQUFVG9rZW4JAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FCmFzc2V0SWRTdHICB193ZWlnaHQJAJQKAgkAawMF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", "height": 3844211, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 5F34x9qkvtHAXJsEybaLQiLGxEHXiY1XzwY4xarVuPzN Next: DwSkaqbBbyeDSJ8mvZ8rSAyXGrg7fsM9MT6mNrh35cDZ Diff:
OldNewDifferences
175175 }
176176
177177
178+func getCurrentTokenBalance (tokenNum) = {
179+ let tokenIdStr = getAssetString(assetIds[tokenNum])
180+ tryGetInteger((("global_" + tokenIdStr) + "_balance"))
181+ }
182+
183+
178184 func getKMult () = match getInteger("static_KMult") {
179185 case x: Int =>
180186 x
183189 }
184190
185191
186-func getVirtualTokenAmount () = fraction(tryGetInteger("global_poolToken_amount"), getKMult(), Scale16)
187-
188-
189-func getCurrentTokenBalance (tokenType) = {
190- let tokenId = getAssetString(assetIds[tokenType])
191- tryGetInteger((("global_" + tokenId) + "_balance"))
192- }
192+func getVirtualPoolTokenAmount () = fraction(tryGetInteger("global_poolToken_amount"), getKMult(), Scale16)
193193
194194
195195 func calculatePIssued (amount,tokenId) = {
196- let Psupply = getVirtualTokenAmount()
196+ let Psupply = getVirtualPoolTokenAmount()
197197 let Balance = tryGetInteger((("global_" + getAssetString(tokenId)) + "_balance"))
198198 fraction(amount, Psupply, Balance, DOWN)
199199 }
364364
365365 func handleTokenChange (accum,tokenId) = {
366366 let Bk = tryGetInteger((("global_" + getAssetString(tokenId)) + "_balance"))
367- let PSupply = getVirtualTokenAmount()
367+ let PSupply = getVirtualPoolTokenAmount()
368368 let tokenDecimals = tryGetInteger((("static_" + getAssetString(tokenId)) + "_scale"))
369369 let Dk = fraction((fraction((PSupply + PIssued), tokenDecimals, PSupply, CEILING) - tokenDecimals), Bk, tokenDecimals, CEILING)
370370 let paymentAmount = getTokenPaymentAmount(tokenId)
397397 func handlePoolTokensRedeem (PRedeemed,userAddress) = {
398398 func handleTokenRedeem (accum,tokenId) = {
399399 let Bk = tryGetInteger((("global_" + getAssetString(tokenId)) + "_balance"))
400- let PSupply = tryGetInteger("global_poolToken_amount")
400+ let PSupply = getVirtualPoolTokenAmount()
401401 let tokenDecimals = tryGetInteger((("static_" + getAssetString(tokenId)) + "_scale"))
402402 let amount = toInt(fraction((toBigInt(Scale8) - fraction(toBigInt((PSupply - PRedeemed)), toBigInt(Scale8), toBigInt(PSupply), CEILING)), toBigInt(Bk), toBigInt(Scale8), DOWN))
403403 (accum ++ [IntegerEntry((("global_" + getAssetString(tokenId)) + "_balance"), (Bk - amount)), ScriptTransfer(userAddress, amount, tokenId)])
706706 else if (isShutdown())
707707 then throw("contract is on stop")
708708 else {
709- let PRedeemed = fraction(pmt.amount, Scale16, getKMult())
710- let result = handlePoolTokensRedeem(PRedeemed, if (sendToOrigin)
709+ let PRedeemedWithMult = pmt.amount
710+ let PRedeemedWithNoMult = fraction(PRedeemedWithMult, getKMult(), Scale16)
711+ let result = handlePoolTokensRedeem(PRedeemedWithNoMult, if (sendToOrigin)
711712 then i.originCaller
712713 else i.caller)
713- (result ++ [Burn(tryGetBinary("global_poolToken_id"), PRedeemed), IntegerEntry("global_poolToken_amount", (tryGetInteger("global_poolToken_amount") - PRedeemed))])
714+ (result ++ [Burn(tryGetBinary("global_poolToken_id"), PRedeemedWithMult), IntegerEntry("global_poolToken_amount", (tryGetInteger("global_poolToken_amount") - PRedeemedWithMult))])
714715 }
715716 }
716717
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let VERSION = "PZ-1.0.1 TEST"
55
66 let usdnAssetId = base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p'
77
88 let puzzleAssetId = base58'HEB8Qaw9xrWpWs8tHsiATYGBWDBtP2S7kcPALrMu43AS'
99
1010 let usdtAssetId = base58'34N9YcEETLWn93qYQ64EsP1x89tSruJU44RrEMSXXEPJ'
1111
1212 let usdtPptAssetId = base58'9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi'
1313
1414 let usdnAssetIdStr = "DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p"
1515
1616 let puzzleAssetIdStr = "HEB8Qaw9xrWpWs8tHsiATYGBWDBtP2S7kcPALrMu43AS"
1717
1818 let usdtAssetIdStr = "34N9YcEETLWn93qYQ64EsP1x89tSruJU44RrEMSXXEPJ"
1919
2020 let usdtPptAssetIdStr = "9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi"
2121
2222 let supportedFeeAssetsStr = ["DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p", "HEB8Qaw9xrWpWs8tHsiATYGBWDBtP2S7kcPALrMu43AS", "34N9YcEETLWn93qYQ64EsP1x89tSruJU44RrEMSXXEPJ", "9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi"]
2323
2424 let parentPoolAddress = Address(base58'3PFDgzu1UtswAkCMxqqQjbTeHaX4cMab8Kh')
2525
2626 let masterAddress = Address(base58'3PLjwHcz9NEuaTo63NZR9B9okQiKQxZSbmf')
2727
2828 let masterPubKey = base58'4z8CKSYQBKkzx7PBb5uBP1YPa6YAHRNTApW1sQVHT5eU'
2929
3030 let oracleAddress = Address(base58'3P8d1E1BLKoD52y3bQJ1bDTd2TD1gpaLn9t')
3131
3232 let stakingAddress = Address(base58'3PFTbywqxtFfukX3HyT881g4iW5K4QL3FAS')
3333
3434 let feesAddress = Address(base58'3PFWAVKmXjfHXyzJb12jCbhP4Uhi9t4uWiD')
3535
3636 let shutdownAddress = Address(base58'3PEpv9hRFWEEBU22WRnLsw1bH4YGtcU728o')
3737
3838 func tryGetInteger (key) = match getInteger(this, key) {
3939 case b: Int =>
4040 b
4141 case _ =>
4242 0
4343 }
4444
4545
4646 func tryGetBinary (key) = match getBinary(this, key) {
4747 case b: ByteVector =>
4848 b
4949 case _ =>
5050 base58''
5151 }
5252
5353
5454 func tryGetString (key) = match getString(this, key) {
5555 case b: String =>
5656 b
5757 case _ =>
5858 ""
5959 }
6060
6161
6262 func getAssetString (assetId) = match assetId {
6363 case b: ByteVector =>
6464 toBase58String(b)
6565 case _ =>
6666 "WAVES"
6767 }
6868
6969
7070 func getAssetBytes (assetIdStr) = if ((assetIdStr == "WAVES"))
7171 then unit
7272 else fromBase58String(assetIdStr)
7373
7474
7575 func addAssetBytesToList (accum,item) = (accum ++ [getAssetBytes(item)])
7676
7777
7878 func addAssetWeightToList (accum,item) = (accum ++ [tryGetInteger((("static_" + getAssetString(item)) + "_weight"))])
7979
8080
8181 func addAssetDecimalsToList (accum,item) = (accum ++ [tryGetInteger((("static_" + getAssetString(item)) + "_decimals"))])
8282
8383
8484 func addAssetScaleToList (accum,item) = (accum ++ [tryGetInteger((("static_" + getAssetString(item)) + "_scale"))])
8585
8686
8787 func addIntToList (accum,item) = (accum ++ [parseIntValue(item)])
8888
8989
9090 let T = tryGetInteger("static_tokensAmount")
9191
9292 let assetIds = {
9393 let $l = split(tryGetString("static_tokenIds"), ",")
9494 let $s = size($l)
9595 let $acc0 = nil
9696 func $f0_1 ($a,$i) = if (($i >= $s))
9797 then $a
9898 else addAssetBytesToList($a, $l[$i])
9999
100100 func $f0_2 ($a,$i) = if (($i >= $s))
101101 then $a
102102 else throw("List size exceeds 10")
103103
104104 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
105105 }
106106
107107 let AssetsWeights = {
108108 let $l = assetIds
109109 let $s = size($l)
110110 let $acc0 = nil
111111 func $f1_1 ($a,$i) = if (($i >= $s))
112112 then $a
113113 else addAssetWeightToList($a, $l[$i])
114114
115115 func $f1_2 ($a,$i) = if (($i >= $s))
116116 then $a
117117 else throw("List size exceeds 10")
118118
119119 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
120120 }
121121
122122 let Decimals = {
123123 let $l = assetIds
124124 let $s = size($l)
125125 let $acc0 = nil
126126 func $f2_1 ($a,$i) = if (($i >= $s))
127127 then $a
128128 else addAssetDecimalsToList($a, $l[$i])
129129
130130 func $f2_2 ($a,$i) = if (($i >= $s))
131131 then $a
132132 else throw("List size exceeds 10")
133133
134134 $f2_2($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
135135 }
136136
137137 let Scales = {
138138 let $l = assetIds
139139 let $s = size($l)
140140 let $acc0 = nil
141141 func $f3_1 ($a,$i) = if (($i >= $s))
142142 then $a
143143 else addAssetScaleToList($a, $l[$i])
144144
145145 func $f3_2 ($a,$i) = if (($i >= $s))
146146 then $a
147147 else throw("List size exceeds 10")
148148
149149 $f3_2($f3_1($f3_1($f3_1($f3_1($f3_1($f3_1($f3_1($f3_1($f3_1($f3_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
150150 }
151151
152152 let Fee = tryGetInteger("static_fee")
153153
154154 let AssetsWeightsDecimals = 4
155155
156156 let Scale = 10000
157157
158158 let Scale8 = 100000000
159159
160160 let Scale16 = 10000000000000000
161161
162162 let FeeScale = 10000
163163
164164 let PoolTokenDecimals = 8
165165
166166 let PoolTokenScale = pow(10, 0, PoolTokenDecimals, 0, 0, HALFUP)
167167
168168 let earnedAssets = assetIds
169169
170170 func isShutdown () = match getBoolean(shutdownAddress, "is_shutdown") {
171171 case x: Boolean =>
172172 x
173173 case _ =>
174174 false
175175 }
176176
177177
178+func getCurrentTokenBalance (tokenNum) = {
179+ let tokenIdStr = getAssetString(assetIds[tokenNum])
180+ tryGetInteger((("global_" + tokenIdStr) + "_balance"))
181+ }
182+
183+
178184 func getKMult () = match getInteger("static_KMult") {
179185 case x: Int =>
180186 x
181187 case _ =>
182188 Scale16
183189 }
184190
185191
186-func getVirtualTokenAmount () = fraction(tryGetInteger("global_poolToken_amount"), getKMult(), Scale16)
187-
188-
189-func getCurrentTokenBalance (tokenType) = {
190- let tokenId = getAssetString(assetIds[tokenType])
191- tryGetInteger((("global_" + tokenId) + "_balance"))
192- }
192+func getVirtualPoolTokenAmount () = fraction(tryGetInteger("global_poolToken_amount"), getKMult(), Scale16)
193193
194194
195195 func calculatePIssued (amount,tokenId) = {
196- let Psupply = getVirtualTokenAmount()
196+ let Psupply = getVirtualPoolTokenAmount()
197197 let Balance = tryGetInteger((("global_" + getAssetString(tokenId)) + "_balance"))
198198 fraction(amount, Psupply, Balance, DOWN)
199199 }
200200
201201
202202 func getMinPIssued (payments) = {
203203 func handler (accum,current) = {
204204 let PIssued = calculatePIssued(current.amount, current.assetId)
205205 if ((PIssued == 0))
206206 then throw("one of the tokens amounts is too low")
207207 else if (if ((accum == 0))
208208 then true
209209 else (accum > PIssued))
210210 then PIssued
211211 else accum
212212 }
213213
214214 let minPIssed = {
215215 let $l = payments
216216 let $s = size($l)
217217 let $acc0 = 0
218218 func $f4_1 ($a,$i) = if (($i >= $s))
219219 then $a
220220 else handler($a, $l[$i])
221221
222222 func $f4_2 ($a,$i) = if (($i >= $s))
223223 then $a
224224 else throw("List size exceeds 10")
225225
226226 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
227227 }
228228 minPIssed
229229 }
230230
231231
232232 func calculateUsdnValue (assetId,amount,aBalance,givenUsdnBalance) = {
233233 let usdnInPool = indexOf(assetIds, usdnAssetId)
234234 let puzzleInPool = indexOf(assetIds, puzzleAssetId)
235235 let usdtInPool = indexOf(assetIds, usdtAssetId)
236236 let usdtPptInPool = indexOf(assetIds, usdtPptAssetId)
237237 let wavesInPool = indexOf(assetIds, unit)
238238 let assetWeight = tryGetInteger((("static_" + getAssetString(assetId)) + "_weight"))
239239 let feeAssetStr = tryGetString("static_feeToken")
240240 if ((feeAssetStr == puzzleAssetIdStr))
241241 then {
242242 let puzzleWeight = AssetsWeights[value(indexOf(assetIds, puzzleAssetId))]
243243 let puzzleBalance = tryGetInteger((("global_" + puzzleAssetIdStr) + "_balance"))
244244 let amountInPuzzle = fraction(amount, (puzzleBalance / puzzleWeight), (aBalance / assetWeight))
245245 let puzzlePrice = getIntegerValue(parentPoolAddress, "global_lastPuzzlePrice")
246246 fraction((amountInPuzzle * puzzlePrice), 1, Scale8)
247247 }
248248 else if ((feeAssetStr == usdtAssetIdStr))
249249 then {
250250 let usdtWeight = AssetsWeights[value(usdtInPool)]
251251 let usdtBalance = tryGetInteger((("global_" + usdtAssetIdStr) + "_balance"))
252252 fraction(amount, (usdtBalance / usdtWeight), (aBalance / assetWeight))
253253 }
254254 else if ((feeAssetStr == usdtPptAssetIdStr))
255255 then {
256256 let usdtWeight = AssetsWeights[value(usdtPptInPool)]
257257 let usdtBalance = tryGetInteger((("global_" + usdtPptAssetIdStr) + "_balance"))
258258 fraction(amount, (usdtBalance / usdtWeight), (aBalance / assetWeight))
259259 }
260260 else if ((feeAssetStr == usdnAssetIdStr))
261261 then {
262262 let usdnWeight = AssetsWeights[value(indexOf(assetIds, usdnAssetId))]
263263 let usdnBalance = match givenUsdnBalance {
264264 case x: Int =>
265265 givenUsdnBalance
266266 case _ =>
267267 tryGetInteger((("global_" + getAssetString(usdnAssetId)) + "_balance"))
268268 }
269269 fraction(amount, (value(usdnBalance) / usdnWeight), (aBalance / assetWeight))
270270 }
271271 else {
272272 let wavesWeight = 3000
273273 let wBalance = (tryGetInteger("global_WAVES_balance") / 50)
274274 fraction(amount, (wBalance / wavesWeight), (aBalance / assetWeight))
275275 }
276276 }
277277
278278
279279 func getPriceFromOracle (assetIdStr) = match getInteger(oracleAddress, (assetIdStr + "_twap5B")) {
280280 case x: Int =>
281281 x
282282 case _ =>
283283 0
284284 }
285285
286286
287287 func calculateUsdValue (assetId,amount,aBalance) = {
288288 let assetWeight = tryGetInteger((("static_" + getAssetString(assetId)) + "_weight"))
289289 let feeAssetStr = tryGetString("static_feeToken")
290290 let feeAssetScale = getIntegerValue(this, (("static_" + feeAssetStr) + "_scale"))
291291 let feeAssetNum = value(indexOf(assetIds, getAssetBytes(feeAssetStr)))
292292 let feeAssetWeight = AssetsWeights[feeAssetNum]
293293 let feeAssetBalance = tryGetInteger((("global_" + feeAssetStr) + "_balance"))
294294 let valInFeeAsset = fraction(amount, (feeAssetBalance / feeAssetWeight), (aBalance / assetWeight))
295295 let feeAssetPrice = getPriceFromOracle(feeAssetStr)
296296 fraction(valInFeeAsset, feeAssetPrice, feeAssetScale)
297297 }
298298
299299
300300 func checkTokensValidity (payments) = {
301301 func handler1 (accum,payment) = (accum ++ [payment.assetId])
302302
303303 let ids = {
304304 let $l = payments
305305 let $s = size($l)
306306 let $acc0 = nil
307307 func $f4_1 ($a,$i) = if (($i >= $s))
308308 then $a
309309 else handler1($a, $l[$i])
310310
311311 func $f4_2 ($a,$i) = if (($i >= $s))
312312 then $a
313313 else throw("List size exceeds 10")
314314
315315 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
316316 }
317317 if ((ids == ids))
318318 then {
319319 func handler2 (accum,assetId) = if ((indexOf(ids, assetId) != unit))
320320 then (accum + 1)
321321 else throw(("asset not attached: " + getAssetString(assetId)))
322322
323323 let checks = {
324324 let $l = assetIds
325325 let $s = size($l)
326326 let $acc0 = 0
327327 func $f5_1 ($a,$i) = if (($i >= $s))
328328 then $a
329329 else handler2($a, $l[$i])
330330
331331 func $f5_2 ($a,$i) = if (($i >= $s))
332332 then $a
333333 else throw("List size exceeds 10")
334334
335335 $f5_2($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
336336 }
337337 if ((checks == checks))
338338 then true
339339 else throw("Strict value is not equal to itself.")
340340 }
341341 else throw("Strict value is not equal to itself.")
342342 }
343343
344344
345345 func handlePoolTokensAdd (PIssued,payments,userAddress,needChange) = {
346346 func getTokenPaymentAmount (tokenId) = {
347347 func handler (accum,payment) = if ((payment.assetId == tokenId))
348348 then payment.amount
349349 else accum
350350
351351 let $l = payments
352352 let $s = size($l)
353353 let $acc0 = 0
354354 func $f4_1 ($a,$i) = if (($i >= $s))
355355 then $a
356356 else handler($a, $l[$i])
357357
358358 func $f4_2 ($a,$i) = if (($i >= $s))
359359 then $a
360360 else throw("List size exceeds 10")
361361
362362 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
363363 }
364364
365365 func handleTokenChange (accum,tokenId) = {
366366 let Bk = tryGetInteger((("global_" + getAssetString(tokenId)) + "_balance"))
367- let PSupply = getVirtualTokenAmount()
367+ let PSupply = getVirtualPoolTokenAmount()
368368 let tokenDecimals = tryGetInteger((("static_" + getAssetString(tokenId)) + "_scale"))
369369 let Dk = fraction((fraction((PSupply + PIssued), tokenDecimals, PSupply, CEILING) - tokenDecimals), Bk, tokenDecimals, CEILING)
370370 let paymentAmount = getTokenPaymentAmount(tokenId)
371371 let toReturn = ((if ((paymentAmount != 0))
372372 then paymentAmount
373373 else 0) - Dk)
374374 let t = if (if (needChange)
375375 then (toReturn > 0)
376376 else false)
377377 then [ScriptTransfer(userAddress, toReturn, tokenId)]
378378 else nil
379379 ((accum ++ t) ++ [IntegerEntry((("global_" + getAssetString(tokenId)) + "_balance"), (Bk + Dk))])
380380 }
381381
382382 let $l = assetIds
383383 let $s = size($l)
384384 let $acc0 = nil
385385 func $f4_1 ($a,$i) = if (($i >= $s))
386386 then $a
387387 else handleTokenChange($a, $l[$i])
388388
389389 func $f4_2 ($a,$i) = if (($i >= $s))
390390 then $a
391391 else throw("List size exceeds 10")
392392
393393 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
394394 }
395395
396396
397397 func handlePoolTokensRedeem (PRedeemed,userAddress) = {
398398 func handleTokenRedeem (accum,tokenId) = {
399399 let Bk = tryGetInteger((("global_" + getAssetString(tokenId)) + "_balance"))
400- let PSupply = tryGetInteger("global_poolToken_amount")
400+ let PSupply = getVirtualPoolTokenAmount()
401401 let tokenDecimals = tryGetInteger((("static_" + getAssetString(tokenId)) + "_scale"))
402402 let amount = toInt(fraction((toBigInt(Scale8) - fraction(toBigInt((PSupply - PRedeemed)), toBigInt(Scale8), toBigInt(PSupply), CEILING)), toBigInt(Bk), toBigInt(Scale8), DOWN))
403403 (accum ++ [IntegerEntry((("global_" + getAssetString(tokenId)) + "_balance"), (Bk - amount)), ScriptTransfer(userAddress, amount, tokenId)])
404404 }
405405
406406 let $l = assetIds
407407 let $s = size($l)
408408 let $acc0 = nil
409409 func $f4_1 ($a,$i) = if (($i >= $s))
410410 then $a
411411 else handleTokenRedeem($a, $l[$i])
412412
413413 func $f4_2 ($a,$i) = if (($i >= $s))
414414 then $a
415415 else throw("List size exceeds 10")
416416
417417 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
418418 }
419419
420420
421421 func calculateOutAmount (AmountIn,assetIn,assetOut,BalanceIn,BalanceOut) = {
422422 let IndexIn = value(indexOf(assetIds, assetIn))
423423 let IndexOut = value(indexOf(assetIds, assetOut))
424424 if ((IndexIn == IndexOut))
425425 then AmountIn
426426 else fraction(BalanceOut, ((Scale8 * Scale8) - toInt(pow(fraction(toBigInt(BalanceIn), toBigInt((Scale8 * Scale8)), toBigInt((BalanceIn + AmountIn)), HALFUP), 16, toBigInt(fraction(AssetsWeights[IndexIn], 10000, AssetsWeights[IndexOut])), 4, 16, CEILING))), (Scale8 * Scale8), DOWN)
427427 }
428428
429429
430430 func getTokenBalance (assetId) = match assetId {
431431 case t: ByteVector =>
432432 assetBalance(this, t)
433433 case _ =>
434434 wavesBalance(this).available
435435 }
436436
437437
438438 func calculateCurrentAssetInterest (assetId,assetIdStr,aBalance,tokenEarningsLastCheck) = {
439439 let totalStaked = tryGetInteger("global_indexStaked")
440440 let tokenBalanceLastCheck = tokenEarningsLastCheck
441441 let currentBalanceDelta = (getTokenBalance(assetId) - aBalance)
442442 let currentTokenEarnings = if ((currentBalanceDelta > tokenBalanceLastCheck))
443443 then currentBalanceDelta
444444 else tokenBalanceLastCheck
445445 let newEarnings = (currentTokenEarnings - tokenBalanceLastCheck)
446446 let newInterest = if ((totalStaked == 0))
447447 then 0
448448 else fraction(newEarnings, Scale8, totalStaked)
449449 let lastCheckInterest = tryGetInteger((("global_lastCheck_" + assetIdStr) + "_interest"))
450450 (lastCheckInterest + newInterest)
451451 }
452452
453453
454454 func claimResult (address) = {
455455 let addressStr = toString(address)
456456 let puzzleAmount = tryGetInteger((addressStr + "_indexStaked"))
457457 func handler (accum,assetId) = {
458458 let assetIdStr = getAssetString(assetId)
459459 let aBalance = tryGetInteger((("global_" + getAssetString(assetId)) + "_balance"))
460460 let tokenEarningsLastCheck = tryGetInteger((("global_lastCheck_" + assetIdStr) + "_earnings"))
461461 let currentTokenInterest = calculateCurrentAssetInterest(assetId, assetIdStr, aBalance, tokenEarningsLastCheck)
462462 let currentTokenEarnings = max([tokenEarningsLastCheck, (getTokenBalance(assetId) - aBalance)])
463463 let rewardAmount = fraction(puzzleAmount, (currentTokenInterest - tryGetInteger((((addressStr + "_lastCheck_") + assetIdStr) + "_interest"))), Scale8)
464464 let transfer = if ((rewardAmount == 0))
465465 then nil
466466 else [ScriptTransfer(address, rewardAmount, assetId)]
467467 $Tuple2(((accum._1 ++ transfer) ++ [IntegerEntry((("global_lastCheck_" + assetIdStr) + "_earnings"), (currentTokenEarnings - rewardAmount)), IntegerEntry((("global_lastCheck_" + assetIdStr) + "_interest"), currentTokenInterest), IntegerEntry((((addressStr + "_lastCheck_") + assetIdStr) + "_interest"), currentTokenInterest)]), (accum._2 + calculateUsdValue(assetId, rewardAmount, aBalance)))
468468 }
469469
470470 let accum = {
471471 let $l = earnedAssets
472472 let $s = size($l)
473473 let $acc0 = $Tuple2(nil, 0)
474474 func $f4_1 ($a,$i) = if (($i >= $s))
475475 then $a
476476 else handler($a, $l[$i])
477477
478478 func $f4_2 ($a,$i) = if (($i >= $s))
479479 then $a
480480 else throw("List size exceeds 10")
481481
482482 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
483483 }
484484 $Tuple2((accum._1 ++ [IntegerEntry((addressStr + "_claimedRewardValue"), (tryGetInteger((addressStr + "_claimedRewardValue")) + accum._2)), IntegerEntry((addressStr + "_lastClaim"), lastBlock.timestamp)]), accum._2)
485485 }
486486
487487
488488 func indexStakeResult (addressStr,amount) = {
489489 let li = claimResult(addressFromStringValue(addressStr))._1
490490 (li ++ [IntegerEntry((addressStr + "_indexStaked"), (tryGetInteger((addressStr + "_indexStaked")) + amount)), IntegerEntry("global_indexStaked", (tryGetInteger("global_indexStaked") + amount))])
491491 }
492492
493493
494494 func sum (accum,n) = (accum + parseIntValue(n))
495495
496496
497497 func checkFeeAsset (accum,next) = if (if ((indexOf(supportedFeeAssetsStr, next) != unit))
498498 then (accum == "")
499499 else false)
500500 then next
501501 else accum
502502
503503
504504 @Callable(i)
505505 func preInit (assetIdsStr,assetWeightsStr,baseTokenIdStr,poolDomain,poolOwner,fee) = {
506506 let poolOwnerAddress = Address(fromBase58String(poolOwner))
507507 let assetIdsStrLi = split(assetIdsStr, ",")
508508 let assetIdsLi = {
509509 let $l = assetIdsStrLi
510510 let $s = size($l)
511511 let $acc0 = nil
512512 func $f4_1 ($a,$i) = if (($i >= $s))
513513 then $a
514514 else addAssetBytesToList($a, $l[$i])
515515
516516 func $f4_2 ($a,$i) = if (($i >= $s))
517517 then $a
518518 else throw("List size exceeds 10")
519519
520520 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
521521 }
522522 let feeAssetStr = {
523523 let $l = assetIdsStrLi
524524 let $s = size($l)
525525 let $acc0 = ""
526526 func $f5_1 ($a,$i) = if (($i >= $s))
527527 then $a
528528 else checkFeeAsset($a, $l[$i])
529529
530530 func $f5_2 ($a,$i) = if (($i >= $s))
531531 then $a
532532 else throw("List size exceeds 10")
533533
534534 $f5_2($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
535535 }
536536 if (isShutdown())
537537 then throw("contract is on stop")
538538 else if ((this != i.caller))
539539 then throw("admin only")
540540 else if ((feeAssetStr == ""))
541541 then throw("pool must have one of the supported fee assets in the composition")
542542 else if ((size(poolDomain) > 13))
543543 then throw("too large pool domain")
544544 else if (if ((fee > 500))
545545 then true
546546 else (50 > fee))
547547 then throw("fee value must be between 50 and 500 (0.5-5%)")
548548 else {
549549 let assetWeightsStrLi = split(assetWeightsStr, ",")
550550 let assetWeightsSum = {
551551 let $l = assetWeightsStrLi
552552 let $s = size($l)
553553 let $acc0 = 0
554554 func $f6_1 ($a,$i) = if (($i >= $s))
555555 then $a
556556 else sum($a, $l[$i])
557557
558558 func $f6_2 ($a,$i) = if (($i >= $s))
559559 then $a
560560 else throw("List size exceeds 10")
561561
562562 $f6_2($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
563563 }
564564 func addTokenDataEntries (accum,assetNum) = if ((assetNum >= size(assetIdsLi)))
565565 then accum
566566 else {
567567 let assetDecimals = match assetIdsLi[assetNum] {
568568 case x: ByteVector =>
569569 value(assetInfo(x)).decimals
570570 case _ =>
571571 8
572572 }
573573 (accum ++ [IntegerEntry((("static_" + assetIdsStrLi[assetNum]) + "_scale"), pow(10, 0, assetDecimals, 0, 0, DOWN)), IntegerEntry((("static_" + assetIdsStrLi[assetNum]) + "_decimals"), assetDecimals), IntegerEntry((("static_" + assetIdsStrLi[assetNum]) + "_weight"), value(parseInt(assetWeightsStrLi[assetNum])))])
574574 }
575575
576576 if ((assetWeightsSum != 10000))
577577 then throw("sum of token weights must be equal to 10000")
578578 else ({
579579 let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
580580 let $s = size($l)
581581 let $acc0 = nil
582582 func $f7_1 ($a,$i) = if (($i >= $s))
583583 then $a
584584 else addTokenDataEntries($a, $l[$i])
585585
586586 func $f7_2 ($a,$i) = if (($i >= $s))
587587 then $a
588588 else throw("List size exceeds 10")
589589
590590 $f7_2($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
591591 } ++ [StringEntry("static_tokenIds", assetIdsStr), StringEntry("static_feeToken", feeAssetStr), StringEntry("static_tokenWeights", assetWeightsStr), IntegerEntry("static_tokensAmount", size(assetIdsLi)), StringEntry("static_poolDomain", poolDomain), StringEntry("static_baseTokenId", baseTokenIdStr), StringEntry("static_poolOwner", poolOwner), IntegerEntry("static_fee", fee), IntegerEntry("static_KMult", Scale16)])
592592 }
593593 }
594594
595595
596596
597597 @Callable(i)
598598 func deInit () = if (isShutdown())
599599 then throw("contract is on stop")
600600 else if ((i.caller != this))
601601 then throw("admin only")
602602 else [IntegerEntry("global_wasInited", 0)]
603603
604604
605605
606606 @Callable(i)
607607 func init () = {
608608 func prepareList () = {
609609 func handler (accum,n) = (accum ++ [IntegerEntry((("global_" + getAssetString(n.assetId)) + "_balance"), n.amount)])
610610
611611 let $l = i.payments
612612 let $s = size($l)
613613 let $acc0 = nil
614614 func $f4_1 ($a,$i) = if (($i >= $s))
615615 then $a
616616 else handler($a, $l[$i])
617617
618618 func $f4_2 ($a,$i) = if (($i >= $s))
619619 then $a
620620 else throw("List size exceeds 10")
621621
622622 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
623623 }
624624
625625 func calculatePoolTokensAmount (payments) = {
626626 func handler (accum,pmt) = {
627627 let assetId = pmt.assetId
628628 func handler2 (accum,n) = if ((n == assetId))
629629 then value(indexOf(assetIds, n))
630630 else accum
631631
632632 let Token = {
633633 let $l = assetIds
634634 let $s = size($l)
635635 let $acc0 = 1
636636 func $f4_1 ($a,$i) = if (($i >= $s))
637637 then $a
638638 else handler2($a, $l[$i])
639639
640640 func $f4_2 ($a,$i) = if (($i >= $s))
641641 then $a
642642 else throw("List size exceeds 10")
643643
644644 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
645645 }
646646 fraction(accum, pow(pmt.amount, Decimals[Token], AssetsWeights[Token], AssetsWeightsDecimals, 8, FLOOR), Scale8)
647647 }
648648
649649 let $l = payments
650650 let $s = size($l)
651651 let $acc0 = PoolTokenScale
652652 func $f4_1 ($a,$i) = if (($i >= $s))
653653 then $a
654654 else handler($a, $l[$i])
655655
656656 func $f4_2 ($a,$i) = if (($i >= $s))
657657 then $a
658658 else throw("List size exceeds 10")
659659
660660 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
661661 }
662662
663663 if (isShutdown())
664664 then throw("contract is on stop")
665665 else if ((tryGetInteger("global_wasInited") > 0))
666666 then throw("pool already inited")
667667 else {
668668 let initialPoolTokens = calculatePoolTokensAmount(i.payments)
669669 if ((initialPoolTokens == 0))
670670 then throw("you need a bigger tokens amount to launch the pool")
671671 else {
672672 let poolTokenIssue = Issue(("PZ " + tryGetString("static_poolDomain")), "Puzzle Swap: pool index token", initialPoolTokens, PoolTokenDecimals, true, unit, 0)
673673 let poolTokenId = calculateAssetId(poolTokenIssue)
674674 (prepareList() ++ [poolTokenIssue, IntegerEntry("global_poolToken_amount", initialPoolTokens), IntegerEntry("global_wasInited", 1), BinaryEntry("global_poolToken_id", poolTokenId), StringEntry("static_poolToken_idStr", getAssetString(poolTokenId)), IntegerEntry((toString(i.caller) + "_indexStaked"), initialPoolTokens), IntegerEntry("global_indexStaked", initialPoolTokens)])
675675 }
676676 }
677677 }
678678
679679
680680
681681 @Callable(i)
682682 func reset () = [IntegerEntry("global_poolToken_amount", 200000000), IntegerEntry("global_WAVES_balance", 400000000), IntegerEntry("global_HEB8Qaw9xrWpWs8tHsiATYGBWDBtP2S7kcPALrMu43AS_balance", 100000000)]
683683
684684
685685
686686 @Callable(i)
687687 func generateIndex (needChange) = if ((size(i.payments) != T))
688688 then throw(("you need to attach all pool tokens. amount of pool tokens: " + toString(T)))
689689 else if (!(checkTokensValidity(i.payments)))
690690 then throw("wrong assets attached")
691691 else {
692692 let PIssuedNoMult = getMinPIssued(i.payments)
693693 let result = handlePoolTokensAdd(PIssuedNoMult, i.payments, i.originCaller, needChange)
694694 let PIssuedWithMult = fraction(PIssuedNoMult, Scale16, getKMult())
695695 let reissue = Reissue(getBinaryValue("global_poolToken_id"), PIssuedWithMult, true)
696696 $Tuple2((result ++ [reissue, ScriptTransfer(i.caller, PIssuedWithMult, tryGetBinary("global_poolToken_id")), IntegerEntry("global_poolToken_amount", (tryGetInteger("global_poolToken_amount") + PIssuedWithMult))]), PIssuedWithMult)
697697 }
698698
699699
700700
701701 @Callable(i)
702702 func redeemIndex (sendToOrigin) = {
703703 let pmt = i.payments[0]
704704 if ((pmt.assetId != tryGetBinary("global_poolToken_id")))
705705 then throw("please attach pool share token")
706706 else if (isShutdown())
707707 then throw("contract is on stop")
708708 else {
709- let PRedeemed = fraction(pmt.amount, Scale16, getKMult())
710- let result = handlePoolTokensRedeem(PRedeemed, if (sendToOrigin)
709+ let PRedeemedWithMult = pmt.amount
710+ let PRedeemedWithNoMult = fraction(PRedeemedWithMult, getKMult(), Scale16)
711+ let result = handlePoolTokensRedeem(PRedeemedWithNoMult, if (sendToOrigin)
711712 then i.originCaller
712713 else i.caller)
713- (result ++ [Burn(tryGetBinary("global_poolToken_id"), PRedeemed), IntegerEntry("global_poolToken_amount", (tryGetInteger("global_poolToken_amount") - PRedeemed))])
714+ (result ++ [Burn(tryGetBinary("global_poolToken_id"), PRedeemedWithMult), IntegerEntry("global_poolToken_amount", (tryGetInteger("global_poolToken_amount") - PRedeemedWithMult))])
714715 }
715716 }
716717
717718
718719
719720 @Callable(i)
720721 func stakeIndex () = {
721722 let addressStr = toString(i.originCaller)
722723 let pmt = i.payments[0]
723724 if ((value(pmt.assetId) != tryGetBinary("global_poolToken_id")))
724725 then throw("wrong asset attached")
725726 else indexStakeResult(addressStr, pmt.amount)
726727 }
727728
728729
729730
730731 @Callable(i)
731732 func unstakeIndex (indexAmount) = {
732733 let addressStr = toString(i.originCaller)
733734 let indexAvailable = tryGetInteger((addressStr + "_indexStaked"))
734735 if (isShutdown())
735736 then throw("contract is on stop")
736737 else if ((indexAmount > indexAvailable))
737738 then throw("you don't have index tokens available")
738739 else if (isShutdown())
739740 then throw("contract is on stop")
740741 else (claimResult(i.originCaller)._1 ++ [IntegerEntry((addressStr + "_indexStaked"), (indexAvailable - indexAmount)), IntegerEntry("global_indexStaked", (tryGetInteger("global_indexStaked") - indexAmount)), ScriptTransfer(i.caller, indexAmount, getBinaryValue("global_poolToken_id"))])
741742 }
742743
743744
744745
745746 @Callable(i)
746747 func claimIndexRewards () = if (isShutdown())
747748 then throw("contract is on stop")
748749 else claimResult(i.caller)
749750
750751
751752
752753 @Callable(i)
753754 func evaluateClaim (user) = $Tuple2(nil, claimResult(addressFromStringValue(user))._2)
754755
755756
756757
757758 @Callable(i)
758759 func swap (assetOut,minimum) = {
759760 let pmt = if ((size(i.payments) == 1))
760761 then value(i.payments[0])
761762 else throw("please attach exactly one payment")
762763 let AmountIn = value(i.payments[0].amount)
763764 let AssetIn = pmt.assetId
764765 let AssetOut = getAssetBytes(assetOut)
765766 let feeAssetOutStr = tryGetString("static_feeToken")
766767 let feeAssetOut = if ((feeAssetOutStr == ""))
767768 then usdnAssetId
768769 else getAssetBytes(feeAssetOutStr)
769770 let AssetInBalance = tryGetInteger((("global_" + getAssetString(AssetIn)) + "_balance"))
770771 let AssetOutBalance = tryGetInteger((("global_" + assetOut) + "_balance"))
771772 let feeAmountIn = fraction(AmountIn, Fee, FeeScale)
772773 let cleanAmountIn = (AmountIn - feeAmountIn)
773774 let AmountOut = calculateOutAmount(cleanAmountIn, AssetIn, AssetOut, AssetInBalance, AssetOutBalance)
774775 let AssetOutBalance2 = (AssetOutBalance - AmountOut)
775776 let AssetInBalance2 = (AssetInBalance + cleanAmountIn)
776777 let feeAssetOutBalance = if ((feeAssetOut == AssetIn))
777778 then AssetInBalance2
778779 else if ((feeAssetOut == AssetOut))
779780 then AssetOutBalance2
780781 else tryGetInteger((("global_" + getAssetString(feeAssetOut)) + "_balance"))
781782 let feeAmountOut = calculateOutAmount(feeAmountIn, AssetIn, feeAssetOut, AssetInBalance, feeAssetOutBalance)
782783 if ((minimum > AmountOut))
783784 then throw("amount to recieve is lower than given one")
784785 else if ((AssetOut == AssetIn))
785786 then throw("this swap is not allowed")
786787 else if ((0 > (AssetOutBalance - AmountOut)))
787788 then throw("contract is out of reserves")
788789 else if (isShutdown())
789790 then throw("contract is on stop")
790791 else {
791792 let creatorFee = fraction(feeAmountOut, 1, 10)
792793 let protocolFee = fraction(feeAmountOut, 4, 10)
793794 let stakingTopUp = if (if ((feeAssetOut == usdnAssetId))
794795 then true
795796 else (feeAssetOut == puzzleAssetId))
796797 then reentrantInvoke(stakingAddress, "topUpReward", nil, [AttachedPayment(feeAssetOut, protocolFee)])
797798 else unit
798799 if ((stakingTopUp == stakingTopUp))
799800 then {
800801 let newBalanceIn = AssetInBalance2
801802 let newBalanceOut = (AssetOutBalance2 - (if ((AssetOut == feeAssetOut))
802803 then feeAmountOut
803804 else 0))
804805 let newBalanceFeeAsset = if (if ((feeAssetOut != AssetIn))
805806 then (feeAssetOut != AssetOut)
806807 else false)
807808 then (feeAssetOutBalance - feeAmountOut)
808809 else unit
809810 let assetInChange = IntegerEntry((("global_" + getAssetString(AssetIn)) + "_balance"), newBalanceIn)
810811 let assetOutChange = IntegerEntry((("global_" + assetOut) + "_balance"), newBalanceOut)
811812 let feeAssetOutChange = if ((newBalanceFeeAsset != unit))
812813 then IntegerEntry((("global_" + getAssetString(feeAssetOut)) + "_balance"), value(newBalanceFeeAsset))
813814 else StringEntry("hello", "world")
814815 let volumeUpdate = calculateUsdnValue(AssetIn, AmountIn, AssetInBalance, feeAssetOutBalance)
815816 let volumeUsdUpdate = calculateUsdValue(AssetIn, AmountIn, AssetInBalance)
816817 $Tuple2(([assetOutChange, assetInChange, feeAssetOutChange, ScriptTransfer(i.caller, AmountOut, AssetOut), ScriptTransfer(addressFromStringValue(tryGetString("static_poolOwner")), creatorFee, feeAssetOut), IntegerEntry("global_earnedByOwner", (tryGetInteger("global_earnedByOwner") + creatorFee)), IntegerEntry("global_volume", (tryGetInteger("global_volume") + volumeUpdate)), IntegerEntry("global_volume_usd", (tryGetInteger("global_volume_usd") + volumeUsdUpdate))] ++ (if ((stakingTopUp == unit))
817818 then [ScriptTransfer(feesAddress, protocolFee, feeAssetOut)]
818819 else nil)), AmountOut)
819820 }
820821 else throw("Strict value is not equal to itself.")
821822 }
822823 }
823824
824825
825826
826827 @Callable(i)
827828 func transferOwnership (newOwnerAddress) = if ((toString(i.caller) != tryGetString("static_poolOwner")))
828829 then throw("this call available only for pool owner")
829830 else [StringEntry("static_poolOwner", newOwnerAddress)]
830831
831832
832833
833834 @Callable(i)
834835 func doRebalancing (assetWeightsStr) = {
835836 let assetWeightsStrLi = split(assetWeightsStr, ",")
836837 let assetWeightsSum = {
837838 let $l = assetWeightsStrLi
838839 let $s = size($l)
839840 let $acc0 = 0
840841 func $f4_1 ($a,$i) = if (($i >= $s))
841842 then $a
842843 else sum($a, $l[$i])
843844
844845 func $f4_2 ($a,$i) = if (($i >= $s))
845846 then $a
846847 else throw("List size exceeds 10")
847848
848849 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
849850 }
850851 let assetIdsStrLi = split(tryGetString("static_tokenIds"), ",")
851852 if ((i.caller != this))
852853 then throw("this call available only for admin")
853854 else if ((assetWeightsSum != 10000))
854855 then throw("sum of token weights must be equal to 10000")
855856 else {
856857 let oldKMult = getKMult()
857858 func handler (pars,assetId) = {
858859 let accum = pars._1
859860 let assetIdStr = getAssetString(assetId)
860861 func handler2 (accum,n) = if ((n == assetId))
861862 then value(indexOf(assetIds, n))
862863 else accum
863864
864865 let Token = {
865866 let $l = assetIds
866867 let $s = size($l)
867868 let $acc0 = 1
868869 func $f5_1 ($a,$i) = if (($i >= $s))
869870 then $a
870871 else handler2($a, $l[$i])
871872
872873 func $f5_2 ($a,$i) = if (($i >= $s))
873874 then $a
874875 else throw("List size exceeds 10")
875876
876877 $f5_2($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
877878 }
878879 let balance = tryGetInteger((("global_" + assetIdStr) + "_balance"))
879880 let weight = if ((pars._2 == "new"))
880881 then parseIntValue(assetWeightsStrLi[Token])
881882 else tryGetInteger((("static_" + assetIdStr) + "_weight"))
882883 $Tuple2(fraction(accum, pow(balance, Decimals[Token], weight, AssetsWeightsDecimals, 8, FLOOR), Scale8), pars._2)
883884 }
884885
885886 let newK = ( let $l = assetIds
886887 let $s = size($l)
887888 let $acc0 = $Tuple2(PoolTokenScale, "new")
888889 func $f5_1 ($a,$i) = if (($i >= $s))
889890 then $a
890891 else handler($a, $l[$i])
891892
892893 func $f5_2 ($a,$i) = if (($i >= $s))
893894 then $a
894895 else throw("List size exceeds 10")
895896
896897 $f5_2($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10))._1
897898 let oldK = ( let $l = assetIds
898899 let $s = size($l)
899900 let $acc0 = $Tuple2(PoolTokenScale, "old")
900901 func $f6_1 ($a,$i) = if (($i >= $s))
901902 then $a
902903 else handler($a, $l[$i])
903904
904905 func $f6_2 ($a,$i) = if (($i >= $s))
905906 then $a
906907 else throw("List size exceeds 10")
907908
908909 $f6_2($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10))._1
909910 let newKMult = fraction(oldKMult, newK, oldK)
910911 func addTokenDataEntries (accum,assetNum) = if ((assetNum >= size(assetWeightsStrLi)))
911912 then accum
912913 else (accum ++ [IntegerEntry((("static_" + assetIdsStrLi[assetNum]) + "_weight"), value(parseInt(assetWeightsStrLi[assetNum])))])
913914
914915 ({
915916 let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
916917 let $s = size($l)
917918 let $acc0 = nil
918919 func $f7_1 ($a,$i) = if (($i >= $s))
919920 then $a
920921 else addTokenDataEntries($a, $l[$i])
921922
922923 func $f7_2 ($a,$i) = if (($i >= $s))
923924 then $a
924925 else throw("List size exceeds 10")
925926
926927 $f7_2($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
927928 } ++ [IntegerEntry("static_KMult", newKMult)])
928929 }
929930 }
930931
931932
932933 @Verifier(tx)
933934 func verify () = if (isShutdown())
934935 then false
935936 else sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
936937

github/deemru/w8io/3ef1775 
96.61 ms