2024.04.24 15:33 [4142872] smart account 3P77iUusNwMMzWFdC8f7bftwpHyG1PBs1gq > SELF 0.00000000 Waves

{ "type": 13, "id": "3ZwhJeVAi25563o5MxS4zBkySNUP1Xokg8MpJ4KDJYEp", "fee": 2200000, "feeAssetId": null, "timestamp": 1713963864812, "version": 2, "chainId": 87, "sender": "3P77iUusNwMMzWFdC8f7bftwpHyG1PBs1gq", "senderPublicKey": "8NWqzYEdBNWAYCHd5hZB5TKhguLM5o6n9ucccjL7Q16o", "proofs": [ "aMNF2h4u8tMSXHRQrWJvnJpnkmoQ7SVLpC7iuRu3JgF92QANfcvAUaLGL5mMG7j4zfkKVQv68ftiMNLKha7ifST", "3yVtFJc8hTqbh1ebx3Fm6nyTWS1Jzp9h7qpcT5SbhMDojinRDCai1UN9uBt4YWL85muyJfQLioEtXsMeaQpiXYbT", "aMNF2h4u8tMSXHRQrWJvnJpnkmoQ7SVLpC7iuRu3JgF92QANfcvAUaLGL5mMG7j4zfkKVQv68ftiMNLKha7ifST", "2K34dfKM4VkLPLMyKBYp6P9YuaT2hraMubzinnBZexwD55ok5XPVFhFBqGt4xqqV9WuX4Fob4jtKZXE8FMXYataC" ], "script": "base64:BgI5CAISBQoDCAgBEgMKAQESBwoFAQEBAQESAwoBARIECgIBAhIDCgEBEgASBQoDAQEBEgcKBQEBAQEBegALcmV2aXNpb25OdW0CAAAJTVVMVFNDQUxFAAgAB1NDQUxFMTYAEAADU0VQAgJfXwAFSEFMRjgAgOHrFwAIRVVMRVJYMTYJALYCAQD0quOekdSkMAAEVFdPWAkAtgIBAAIABU1VTFQ2AMCEPQAGTVVMVFg2CQC2AgEAwIQ9AAVNVUxUOACAwtcvAAZNVUxUWDgJALYCAQCAwtcvAAdNVUxUWDEwCQC2AgEAgMivoCUAB01VTFRYMTYJALYCAQCAgIT+pt7hEQAHV0FWRVNJRAkA2QQBAgVXQVZFUwALa1Jlc3VsdElkeEEAAAAPa1Jlc3VsdElkeFBhdWxCAAEAGWtSZXN1bHRJZHhXUmVzZXJ2ZXNJblVzZG4AAgAQa1Jlc3VsdElkeE11bHRCUgADABNrUmVzdWx0SWR4TXVsdFBvd2VyAAQAG2tSZXN1bHRJZHhNdWx0RXhwSW5Qb3dlclN0cgAFABJrUmVzdWx0SWR4TXVsdEtTdHIABgAPbk1ldHJpY0lkeFByaWNlAAAAG25NZXRyaWNJZHhVc2RuTG9ja2VkQmFsYW5jZQABABxuTWV0cmljSWR4V2F2ZXNMb2NrZWRCYWxhbmNlAAIAEW5NZXRyaWNJZHhSZXNlcnZlAAMAF25NZXRyaWNJZHhSZXNlcnZlSW5Vc2RuAAQAFG5NZXRyaWNJZHhVc2RuU3VwcGx5AAUAEW5NZXRyaWNJZHhTdXJwbHVzAAYAGG5NZXRyaWNJZHhTdXJwbHVzUGVyY2VudAAHAAxuTWV0cmljSWR4QlIACAAUbk1ldHJpY0lkeE5zYnRTdXBwbHkACQAXbk1ldHJpY0lkeE1heE5zYnRTdXBwbHkACgAUbk1ldHJpY0lkeFN1cmZTdXBwbHkACwASbk1ldHJpY1VzZG5Vc2R0UGVnAAwAFm5NZXRyaWNDdXJyZW50UHJpY2VBZGoADQARbk1ldHJpY0Jhc2tldEluZm8ADgESa2V5TmV1dHJpbm9BZGRyZXNzAAIdJXMlc19fY29uZmlnX19uZXV0cmlub0FkZHJlc3MBE2tleVN3YXBBbW91bnRBUGFyYW0AAhglcyVzX19jb25maWdfX3N3YXBBUGFyYW0BE2tleVN3YXBBbW91bnRCUGFyYW0AAhglcyVzX19jb25maWdfX3N3YXBCUGFyYW0BF2tleVVzZG5Td2FwQW1vdW50QVBhcmFtAAIcJXMlc19fY29uZmlnX191c2RuU3dhcEFQYXJhbQEXa2V5VXNkblN3YXBBbW91bnRCUGFyYW0AAhwlcyVzX19jb25maWdfX3VzZG5Td2FwQlBhcmFtARNrZXlQcmljZUFkak1pbkNvZWZmAAIeJXMlc19fcHJpY2VBZGpfX21pbkNvZWZmaWNpZW50ARdrZXlQcmljZUFkakFyYlJlZ3VsYXRvcgACHCVzJXNfX3ByaWNlQWRqX19hcmJSZWd1bGF0b3IBEmtleU5ldXRyaW5vQXNzZXRJZAACEW5ldXRyaW5vX2Fzc2V0X2lkAQ5rZXlOc2J0QXNzZXRJZAACDWJvbmRfYXNzZXRfaWQBDmtleVN1cmZBc3NldElkAAINc3VyZl9hc3NldF9pZAEOa2V5V2luZEFzc2V0SWQAAg13aW5kX2Fzc2V0X2lkARFzd2Fwc1RpbWVmcmFtZUtFWQACD3N3YXBzX3RpbWVmcmFtZQEaa2V5VXNlckxhc3RRdWlja1N3YXBIZWlnaHQBC3VzZXJBZGRyZXNzCQC5CQIJAMwIAgIEJXMlcwkAzAgCAhd1c2VyTGFzdFF1aWNrU3dhcEhlaWdodAkAzAgCBQt1c2VyQWRkcmVzcwUDbmlsBQNTRVABHWtleVF1aWNrU3dhcFVzZXJTcGVudEluUGVyaW9kAQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgIacXVpY2tTd2FwVXNlclNwZW50SW5QZXJpb2QJAMwIAgULdXNlckFkZHJlc3MFA25pbAUDU0VQAQ9iYXNrZXRBc3NldHNLZXkAAholcyVzX19jb21tb25fX2Jhc2tldEFzc2V0cwEIa2V5UHJpY2UAAgVwcmljZQEPa2V5UHJpY2VCeUFzc2V0AQdhc3NldElkCQCsAgICHiVzJXMlc19fY29tbW9uX19wcmljZUJ5QXNzZXRfXwUHYXNzZXRJZAANUnBkQmFsYW5jZUtleQILcnBkX2JhbGFuY2UBEXJwZFVzZXJCYWxhbmNlS2V5AgVvd25lcgdhc3NldElkCQC5CQIJAMwIAgUNUnBkQmFsYW5jZUtleQkAzAgCBQdhc3NldElkCQDMCAIFBW93bmVyBQNuaWwCAV8BD2dldFN0cmluZ09yRmFpbAIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQdhZGRyZXNzBQNrZXkJALkJAgkAzAgCAgptYW5kYXRvcnkgCQDMCAIJAKUIAQUHYWRkcmVzcwkAzAgCAgEuCQDMCAIFA2tleQkAzAgCAg8gaXMgbm90IGRlZmluZWQFA25pbAIAAQxnZXRJbnRPckZhaWwCB2FkZHJlc3MDa2V5CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUHYWRkcmVzcwUDa2V5CQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFB2FkZHJlc3MJAMwIAgIBLgkAzAgCBQNrZXkJAMwIAgIPIGlzIG5vdCBkZWZpbmVkBQNuaWwCAAEOZ2V0TnVtYmVyQnlLZXkCB2FkZHJlc3MDa2V5CQELdmFsdWVPckVsc2UCCQCaCAIFB2FkZHJlc3MFA2tleQAAAQ1nZXRCb29sT3JGYWlsAgdhZGRyZXNzA2tleQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCbCAIFB2FkZHJlc3MFA2tleQkAuQkCCQDMCAICCm1hbmRhdG9yeSAJAMwIAgkApQgBBQdhZGRyZXNzCQDMCAICAS4JAMwIAgUDa2V5CQDMCAICDyBpcyBub3QgZGVmaW5lZAUDbmlsAgABFmNvbnZlcnROZXV0cmlub1RvV2F2ZXMCBmFtb3VudAVwcmljZQkAawMFBmFtb3VudAUFTVVMVDgFBXByaWNlARZjb252ZXJ0V2F2ZXNUb05ldXRyaW5vAgZhbW91bnQFcHJpY2UJAGsDBQZhbW91bnQFBXByaWNlBQVNVUxUOAEFdG9YMTYCB29yaWdWYWwNb3JpZ1NjYWxlTXVsdAkAvAIDCQC2AgEFB29yaWdWYWwFB01VTFRYMTYJALYCAQUNb3JpZ1NjYWxlTXVsdAEHZnJvbVgxNgIDdmFsD3Jlc3VsdFNjYWxlTXVsdAkAoAMBCQC8AgMFA3ZhbAkAtgIBBQ9yZXN1bHRTY2FsZU11bHQFB01VTFRYMTYBCWFzQW55TGlzdAEDdmFsBAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIJTGlzdFtBbnldBAp2YWxBbnlMeXN0BQckbWF0Y2gwBQp2YWxBbnlMeXN0CQACAQIbZmFpbCB0byBjYXN0IGludG8gTGlzdFtBbnldAQVhc0ludAEDdmFsBAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIDSW50BAZ2YWxJbnQFByRtYXRjaDAFBnZhbEludAkAAgECFWZhaWwgdG8gY2FzdCBpbnRvIEludAEIYXNTdHJpbmcBA3ZhbAQHJG1hdGNoMAUDdmFsAwkAAQIFByRtYXRjaDACBlN0cmluZwQGdmFsU3RyBQckbWF0Y2gwBQZ2YWxTdHIJAAIBAhhmYWlsIHRvIGNhc3QgaW50byBTdHJpbmcBDWFzUHJpY2VTVFJVQ1QBAXYEByRtYXRjaDAFAXYDCQABAgUHJG1hdGNoMAIUKEludCwgSW50LCBJbnQsIEludCkEBnN0cnVjdAUHJG1hdGNoMAUGc3RydWN0CQACAQIdZmFpbCB0byBjYXN0IGludG8gUHJpY2VTVFJVQ1QAGUlkeENvbnRyb2xDZmdOZXV0cmlub0RhcHAAAQAYSWR4Q29udHJvbENmZ0F1Y3Rpb25EYXBwAAIAFElkeENvbnRyb2xDZmdScGREYXBwAAMAFUlkeENvbnRyb2xDZmdNYXRoRGFwcAAEABxJZHhDb250cm9sQ2ZnTGlxdWlkYXRpb25EYXBwAAUAFUlkeENvbnRyb2xDZmdSZXN0RGFwcAAGAB1JZHhDb250cm9sQ2ZnTm9kZVJlZ2lzdHJ5RGFwcAAHABxJZHhDb250cm9sQ2ZnTnNidFN0YWtpbmdEYXBwAAgAGUlkeENvbnRyb2xDZmdNZWRpYXRvckRhcHAACQAcSWR4Q29udHJvbENmZ1N1cmZTdGFraW5nRGFwcAAKACBJZHhDb250cm9sQ2ZnR25zYnRDb250cm9sbGVyRGFwcAALABdJZHhDb250cm9sQ2ZnUmVzdFYyRGFwcAAMABtJZHhDb250cm9sQ2ZnR292ZXJuYW5jZURhcHAADQAcSWR4Q29udHJvbENmZ1BlZ1Byb3ZpZGVyRGFwcAAOABpJZHhDb250cm9sQ2ZnV2luZFByb3h5RGFwcAAQARFrZXlDb250cm9sQWRkcmVzcwACHCVzJXNfX2NvbmZpZ19fY29udHJvbEFkZHJlc3MBDWtleUNvbnRyb2xDZmcAAhElc19fY29udHJvbENvbmZpZwEUcmVhZENvbnRyb2xDZmdPckZhaWwBB2NvbnRyb2wJALwJAgkBD2dldFN0cmluZ09yRmFpbAIFB2NvbnRyb2wJAQ1rZXlDb250cm9sQ2ZnAAUDU0VQARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCCmNvbnRyb2xDZmcDaWR4CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQpjb250cm9sQ2ZnBQNpZHgJAKwCAgItQ29udHJvbCBjZmcgZG9lc24ndCBjb250YWluIGFkZHJlc3MgYXQgaW5kZXggCQCkAwEFA2lkeAAPY29udHJvbENvbnRyYWN0CQERQGV4dHJOYXRpdmUoMTA2MikBCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMJARFrZXlDb250cm9sQWRkcmVzcwACIzNQNUJmZDU4UFBmTnZCTTJIeThRZmJjRHFNZU50emc3S2ZQAApjb250cm9sQ2ZnCQEUcmVhZENvbnRyb2xDZmdPckZhaWwBBQ9jb250cm9sQ29udHJhY3QAEG5ldXRyaW5vQ29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQpjb250cm9sQ2ZnBRlJZHhDb250cm9sQ2ZnTmV1dHJpbm9EYXBwAA9hdWN0aW9uQ29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQpjb250cm9sQ2ZnBRhJZHhDb250cm9sQ2ZnQXVjdGlvbkRhcHAAE2xpcXVpZGF0aW9uQ29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQpjb250cm9sQ2ZnBRxJZHhDb250cm9sQ2ZnTGlxdWlkYXRpb25EYXBwABN1c2RuU3Rha2luZ0NvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUKY29udHJvbENmZwUUSWR4Q29udHJvbENmZ1JwZERhcHAAE3BlZ1Byb3ZpZGVyQ29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQpjb250cm9sQ2ZnBRxJZHhDb250cm9sQ2ZnUGVnUHJvdmlkZXJEYXBwABF3aW5kUHJveHlDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFCmNvbnRyb2xDZmcFGklkeENvbnRyb2xDZmdXaW5kUHJveHlEYXBwABJuZXV0cmlub0Fzc2V0SWRTdHIJAQ9nZXRTdHJpbmdPckZhaWwCBRBuZXV0cmlub0NvbnRyYWN0CQESa2V5TmV1dHJpbm9Bc3NldElkAAAPbmV1dHJpbm9Bc3NldElkCQDZBAEFEm5ldXRyaW5vQXNzZXRJZFN0cgALbnNidEFzc2V0SWQJANkEAQkBEUBleHRyTmF0aXZlKDEwNTMpAgUQbmV1dHJpbm9Db250cmFjdAkBDmtleU5zYnRBc3NldElkAAALc3VyZkFzc2V0SWQJANkEAQkBEUBleHRyTmF0aXZlKDEwNTMpAgUPYXVjdGlvbkNvbnRyYWN0CQEOa2V5U3VyZkFzc2V0SWQAAA53aW5kQXNzZXRJZFN0cgkBD2dldFN0cmluZ09yRmFpbAIFEG5ldXRyaW5vQ29udHJhY3QJAQ5rZXlXaW5kQXNzZXRJZAAAC3dpbmRBc3NldElkCQDZBAEFDndpbmRBc3NldElkU3RyARBrZXlCYWxhbmNlTG9ja2VkAAINYmFsYW5jZV9sb2NrXwEOdG90YWxMb2NrZWRLRVkCCHN3YXBUeXBlB2Fzc2V0SWQJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgILYmFsYW5jZUxvY2sJAMwIAgUIc3dhcFR5cGUJAMwIAgUHYXNzZXRJZAUDbmlsBQNTRVABFWtleVRva2VuTG9ja2VkQmFsYW5jZQEHYXNzZXRJZAkBDnRvdGFsTG9ja2VkS0VZAgILb3V0TmV1dHJpbm8FB2Fzc2V0SWQBGGtleU5ldXRyaW5vTG9ja2VkQmFsYW5jZQAJAQ50b3RhbExvY2tlZEtFWQICCG91dE11bHRpBRJuZXV0cmlub0Fzc2V0SWRTdHIBG2tleU9sZE5ldXRyaW5vTG9ja2VkQmFsYW5jZQAJAKwCAgkBEGtleUJhbGFuY2VMb2NrZWQAAghuZXV0cmlubwEYa2V5T2xkV2F2ZXNMb2NrZWRCYWxhbmNlAAkArAICCQEQa2V5QmFsYW5jZUxvY2tlZAACBXdhdmVzARljYWxjVXNkbk91dE9mTWFya2V0U3VwcGx5AAQWb3V0T2ZNYXJrZXRBZGRyZXNzTGlzdAkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ9jb250cm9sQ29udHJhY3QCJSVzJXNfX2NvbnRyb2xfX291dE9mTWFya2V0QWRkcmVzc0xpc3QCAAMJAAACBRZvdXRPZk1hcmtldEFkZHJlc3NMaXN0AgAAAAoBC2JhbGFuY2VzU1VNAhFvdXRPZk1hcmtldFN1cHBseQtuZXh0QWRkcmVzcwkAZAIJAGQCBRFvdXRPZk1hcmtldFN1cHBseQkBC3ZhbHVlT3JFbHNlAgkAmggCBRN1c2RuU3Rha2luZ0NvbnRyYWN0CQERcnBkVXNlckJhbGFuY2VLZXkCBQtuZXh0QWRkcmVzcwUSbmV1dHJpbm9Bc3NldElkU3RyAAAJAPAHAgkBEUBleHRyTmF0aXZlKDEwNjIpAQULbmV4dEFkZHJlc3MFD25ldXRyaW5vQXNzZXRJZAoAAiRsCQC1CQIFFm91dE9mTWFya2V0QWRkcmVzc0xpc3QFA1NFUAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQELYmFsYW5jZXNTVU0CBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDcJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwERcmVhZEN1cnJlbnRBdmdQZWcACAkBDWFzUHJpY2VTVFJVQ1QBCQD8BwQFE3BlZ1Byb3ZpZGVyQ29udHJhY3QCBXByaWNlCQDMCAIABAUDbmlsBQNuaWwCXzIBC2FkanVzdFByaWNlAgdwcmljZVg2DXVzZG5Vc2R0UGVnWDYECm1pbkNvZWZmWDYJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBE2tleVByaWNlQWRqTWluQ29lZmYAAMDPJAQOYXJiUmVndWxhdG9yWDYJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBF2tleVByaWNlQWRqQXJiUmVndWxhdG9yAADwkwkED21heFByaWNlQ29lZmZYNgkAlgMBCQDMCAIFCm1pbkNvZWZmWDYJAMwIAgkAawMJAGQCBQVNVUxUNgUOYXJiUmVndWxhdG9yWDYFDXVzZG5Vc2R0UGVnWDYFBU1VTFQ2BQNuaWwEDHByaWNlQ29lZmZYNgkAlwMBCQDMCAIFD21heFByaWNlQ29lZmZYNgkAzAgCBQVNVUxUNgUDbmlsCQBrAwUHcHJpY2VYNgUFTVVMVDYFDHByaWNlQ29lZmZYNgAMY3VycmVudFByaWNlCQERQGV4dHJOYXRpdmUoMTA1MCkCBQ9jb250cm9sQ29udHJhY3QJAQhrZXlQcmljZQAADXVzZG5Vc2R0UGVnWDYJARFyZWFkQ3VycmVudEF2Z1BlZwAAD2N1cnJlbnRQcmljZUFkagkBC2FkanVzdFByaWNlAgUMY3VycmVudFByaWNlBQ11c2RuVXNkdFBlZ1g2ABVuZXV0cmlub0xvY2tlZEJhbGFuY2UJAGQCCQELdmFsdWVPckVsc2UCCQCaCAIFEG5ldXRyaW5vQ29udHJhY3QJARtrZXlPbGROZXV0cmlub0xvY2tlZEJhbGFuY2UAAAAJAQt2YWx1ZU9yRWxzZQIJAJoIAgUQbmV1dHJpbm9Db250cmFjdAkBGGtleU5ldXRyaW5vTG9ja2VkQmFsYW5jZQAAAAASd2F2ZXNMb2NrZWRCYWxhbmNlCQBkAgkBC3ZhbHVlT3JFbHNlAgkAmggCBRBuZXV0cmlub0NvbnRyYWN0CQEYa2V5T2xkV2F2ZXNMb2NrZWRCYWxhbmNlAAAACQELdmFsdWVPckVsc2UCCQCaCAIFEG5ldXRyaW5vQ29udHJhY3QJARVrZXlUb2tlbkxvY2tlZEJhbGFuY2UBAgVXQVZFUwAAAQdyZXNlcnZlAQdhc3NldElkBAt0ZW1wQXNzZXRJZAkA2QQBBQdhc3NldElkAwkAAAIFC3RlbXBBc3NldElkBQdXQVZFU0lECQBlAggJAO8HAQUQbmV1dHJpbm9Db250cmFjdAdyZWd1bGFyBRJ3YXZlc0xvY2tlZEJhbGFuY2UDCQAAAgULdGVtcEFzc2V0SWQFC3dpbmRBc3NldElkCQBkAgkA8AcCBRBuZXV0cmlub0NvbnRyYWN0BQt0ZW1wQXNzZXRJZAkBBWFzSW50AQkA/AcEBRF3aW5kUHJveHlDb250cmFjdAIPYmFsYW5jZVJFQURPTkxZBQNuaWwFA25pbAkAZQIJAPAHAgUQbmV1dHJpbm9Db250cmFjdAULdGVtcEFzc2V0SWQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUQbmV1dHJpbm9Db250cmFjdAkBFWtleVRva2VuTG9ja2VkQmFsYW5jZQEFB2Fzc2V0SWQAAAENcmVzZXJ2ZXNJblVzZAEHYXNzZXRJZAQDdm9sCQEHcmVzZXJ2ZQEFB2Fzc2V0SWQEAnByCQEFdmFsdWUBCQCaCAIFD2NvbnRyb2xDb250cmFjdAkBD2tleVByaWNlQnlBc3NldAEFB2Fzc2V0SWQJAGsDBQN2b2wFAnByBQVNVUxUOAAZbmV1dHJpbm9PdXRPZk1hcmtldFN1cHBseQkBGWNhbGNVc2RuT3V0T2ZNYXJrZXRTdXBwbHkAABNuZXV0cmlub1RvdGFsU3VwcGx5CQBlAgkAZQIJAGQCBRVuZXV0cmlub0xvY2tlZEJhbGFuY2UICQEFdmFsdWUBCQDsBwEFD25ldXRyaW5vQXNzZXRJZAhxdWFudGl0eQkA8AcCBRBuZXV0cmlub0NvbnRyYWN0BQ9uZXV0cmlub0Fzc2V0SWQJAPAHAgUTbGlxdWlkYXRpb25Db250cmFjdAUPbmV1dHJpbm9Bc3NldElkAA5uZXV0cmlub1N1cHBseQkAZQIFE25ldXRyaW5vVG90YWxTdXBwbHkFGW5ldXRyaW5vT3V0T2ZNYXJrZXRTdXBwbHkBBWdldEJSAAQGYmFza2V0CQC1CQIJAQV2YWx1ZQEJAJ0IAgUQbmV1dHJpbm9Db250cmFjdAkBD2Jhc2tldEFzc2V0c0tleQAFA1NFUAoBBWFkZEJyAgNhY2MHYXNzZXRJZAkAZAIFA2FjYwkBDXJlc2VydmVzSW5Vc2QBBQdhc3NldElkBAtzdW1SZXNlcnZlcwoAAiRsBQZiYXNrZXQKAAIkcwkAkAMBBQIkbAoABSRhY2MwAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBBWFkZEJyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKCQBrAwULc3VtUmVzZXJ2ZXMFBU1VTFQ2BQ5uZXV0cmlub1N1cHBseQACQlIDCQAAAgUObmV1dHJpbm9TdXBwbHkAAAAACQEFZ2V0QlIAAQ1nZXRCYXNrZXRJbmZvAAQMYmFza2V0QXNzZXRzCQEFdmFsdWUBCQCdCAIFEG5ldXRyaW5vQ29udHJhY3QJAQ9iYXNrZXRBc3NldHNLZXkABAZiYXNrZXQJALUJAgUMYmFza2V0QXNzZXRzBQNTRVAKAQp3ZWlnaHRDYWxjAgNhY2MHYXNzZXRJZAQDdm9sCQEHcmVzZXJ2ZQEFB2Fzc2V0SWQEAnByCQEFdmFsdWUBCQCaCAIFD2NvbnRyb2xDb250cmFjdAkBD2tleVByaWNlQnlBc3NldAEFB2Fzc2V0SWQEBHJlc1UJAGsDBQN2b2wFAnByBQVNVUxUOAkAlAoCCQDNCAIIBQNhY2MCXzEJAJYKBAUHYXNzZXRJZAUDdm9sBQRyZXNVBQJwcgkAZAIIBQNhY2MCXzIFBHJlc1UEAXQKAAIkbAUGYmFza2V0CgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlAoCBQNuaWwAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEKd2VpZ2h0Q2FsYwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgoBB2NvbWJpbmUCA2FjYwRpdGVtBAVzaGFyZQMJAAACCAUBdAJfMgAABQVNVUxUNgkAawMIBQRpdGVtAl8zBQVNVUxUNggFAXQCXzIJAM0IAgUDYWNjCQC5CQIJAMwIAggFBGl0ZW0CXzEJAMwIAgkApAMBBQVzaGFyZQkAzAgCCQCkAwEIBQRpdGVtAl80CQDMCAIJAKQDAQgFBGl0ZW0CXzIFA25pbAIBOgQNd2VpZ2h0ZWRQcmljZQMJAAACBQ5uZXV0cmlub1N1cHBseQAAAAAJAGsDCAUBdAJfMgUFTVVMVDYFDm5ldXRyaW5vU3VwcGx5CQCVCgMJALkJAgoAAiRsCAUBdAJfMQoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMV8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHY29tYmluZQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMV8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjFfMgIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgIBXwUNd2VpZ2h0ZWRQcmljZQgFAXQCXzIJAWkBDWNvbnN0cnVjdG9yVjEDD25ldXRyaW5vQWRkcmVzcw9uc2J0TG9ja0FkZHJlc3MQc3dhcEFtb3VudEFQYXJhbQMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECDm5vdCBhdXRob3JpemVkCQDMCAIJAQtTdHJpbmdFbnRyeQIJARJrZXlOZXV0cmlub0FkZHJlc3MABQ9uZXV0cmlub0FkZHJlc3MJAMwIAgkBDEludGVnZXJFbnRyeQIJARNrZXlTd2FwQW1vdW50QVBhcmFtAAUQc3dhcEFtb3VudEFQYXJhbQUDbmlsAWkBFWNhbGNTd2FwTGltaXRSRUFET05MWQELZ05zYnRBbW91bnQEFWxpbWl0QmFza2V0VG9rZW5JblVzZAMJAGcCAAAFC2dOc2J0QW1vdW50AAAECGFQYXJhbVg4CQC2AgEJAQxnZXRJbnRPckZhaWwCBQR0aGlzCQETa2V5U3dhcEFtb3VudEFQYXJhbQAECWJQYXJhbVgxNgkAtgIBCQEMZ2V0SW50T3JGYWlsAgUEdGhpcwkBE2tleVN3YXBBbW91bnRCUGFyYW0ABAlwb3dQYXJ0WDgJAHYGCQC2AgEFC2dOc2J0QW1vdW50AAYFCWJQYXJhbVgxNgAQAAgFB0NFSUxJTkcJAKADAQkAvAIDBQhhUGFyYW1YOAUJcG93UGFydFg4BQdNVUxUWDEwBAlsaW1pdFVzZG4DCQBnAgAABQtnTnNidEFtb3VudAAABAhhUGFyYW1YOAkAtgIBCQEMZ2V0SW50T3JGYWlsAgUEdGhpcwkBF2tleVVzZG5Td2FwQW1vdW50QVBhcmFtAAQJYlBhcmFtWDE2CQC2AgEJAQxnZXRJbnRPckZhaWwCBQR0aGlzCQEXa2V5VXNkblN3YXBBbW91bnRCUGFyYW0ABAlwb3dQYXJ0WDgJAHYGCQC2AgEFC2dOc2J0QW1vdW50AAYFCWJQYXJhbVgxNgAQAAgFB0NFSUxJTkcJAKADAQkAvAIDBQhhUGFyYW1YOAUJcG93UGFydFg4BQdNVUxUWDEwCQCUCgIFA25pbAkAzAgCBRVsaW1pdEJhc2tldFRva2VuSW5Vc2QJAMwIAgAACQDMCAIFCWxpbWl0VXNkbgUDbmlsAWkBEmNhbGN1bGF0ZUtSRUFET05MWQUEd1JhdwR1UmF3BXByaWNlBG1SYXcEc1JhdwQDRVhQCQC2AgEAyfSlAQQIRVhQU0NBTEUABgQBYQkBC3ZhbHVlT3JFbHNlAgkAmggCBQ9hdWN0aW9uQ29udHJhY3QCEG5zYnRDdXJ2ZVBhcmFtX2EAAwQFcGF1bEIJAQt2YWx1ZU9yRWxzZQIJAJoIAgUPYXVjdGlvbkNvbnRyYWN0AhBuc2J0Q3VydmVQYXJhbV9iCQBpAgkAaAIAAwUFTVVMVDYACgQPd1Jlc2VydmVzSW5Vc2RuCQEWY29udmVydFdhdmVzVG9OZXV0cmlubwIFBHdSYXcFBXByaWNlBAZtdWx0QlIJAGsDBQ93UmVzZXJ2ZXNJblVzZG4FBU1VTFQ4BQR1UmF3AwkAZgIFBm11bHRCUgDQ7/fjJwkAAgEJAKwCAgkArAICAgNCUj0JAKQDAQUGbXVsdEJSAicgPiAxMDY3OC41NjQ4MTYlIHdpbGwgb3ZlcmZsb3cgZXhwb25lbnQECW11bHRQb3dlcgkAaAIFAWEJAGUCBQZtdWx0QlIFBU1VTFQ4BA5tdWx0RXhwSW5Qb3dlcgkAdgYFA0VYUAUIRVhQU0NBTEUJALYCAQUJbXVsdFBvd2VyBQlNVUxUU0NBTEUFB1NDQUxFMTYFBERPV04EBW11bHRLCQC8AgMJALYCAQUFcGF1bEIFDm11bHRFeHBJblBvd2VyBQZNVUxUWDYJAJQKAgUDbmlsCQDMCAIFAWEJAMwIAgUFcGF1bEIJAMwIAgUPd1Jlc2VydmVzSW5Vc2RuCQDMCAIFBm11bHRCUgkAzAgCBQltdWx0UG93ZXIJAMwIAgkApgMBBQ5tdWx0RXhwSW5Qb3dlcgkAzAgCCQCmAwEFBW11bHRLBQNuaWwBaQEVY3VydmVGdW5jdGlvblJFQURPTkxZAQt3YXZlc1BheVJhdwQPbmV1dHJpbm9NZXRyaWNzCQEJYXNBbnlMaXN0AQkA/AcEBQR0aGlzAhpjYWxjTmV1dGlub01ldHJpY3NSRUFET05MWQUDbmlsBQNuaWwEBXByaWNlCQEFYXNJbnQBCQCRAwIFD25ldXRyaW5vTWV0cmljcwUPbk1ldHJpY0lkeFByaWNlBAR3UmF3CQEFYXNJbnQBCQCRAwIFD25ldXRyaW5vTWV0cmljcwURbk1ldHJpY0lkeFJlc2VydmUEBHVSYXcJAQVhc0ludAEJAJEDAgUPbmV1dHJpbm9NZXRyaWNzBRRuTWV0cmljSWR4VXNkblN1cHBseQQEc1JhdwkBBWFzSW50AQkAkQMCBQ9uZXV0cmlub01ldHJpY3MFFG5NZXRyaWNJZHhOc2J0U3VwcGx5BARtUmF3CQEFYXNJbnQBCQCRAwIFD25ldXRyaW5vTWV0cmljcwUXbk1ldHJpY0lkeE1heE5zYnRTdXBwbHkECmtDYWxjQXJyYXkJAQlhc0FueUxpc3QBCQD8BwQFBHRoaXMCEmNhbGN1bGF0ZUtSRUFET05MWQkAzAgCBQR3UmF3CQDMCAIFBHVSYXcJAMwIAgUFcHJpY2UJAMwIAgUEbVJhdwkAzAgCBQRzUmF3BQNuaWwFA25pbAQFbXVsdEsJAKcDAQkBCGFzU3RyaW5nAQkAkQMCBQprQ2FsY0FycmF5BRJrUmVzdWx0SWR4TXVsdEtTdHIEB3VzZG5QYXkJARZjb252ZXJ0V2F2ZXNUb05ldXRyaW5vAgULd2F2ZXNQYXlSYXcFBXByaWNlBBBiaWdNYXhOc2J0U3VwcGx5CQC2AgEFBG1SYXcEDWJpZ05zYnRTdXBwbHkJALYCAQkAZQIFBG1SYXcFBHNSYXcEBXN0ZXAxCQC8AgMJALYCAQUHdXNkblBheQUHTVVMVFgxNgUFbXVsdEsEBXN0ZXAyCQC8AgMFBXN0ZXAxBQ1iaWdOc2J0U3VwcGx5BRBiaWdNYXhOc2J0U3VwcGx5BAVzdGVwMwkAoAMBCQC8AgMFDWJpZ05zYnRTdXBwbHkFEGJpZ01heE5zYnRTdXBwbHkJALcCAgUFc3RlcDIFEGJpZ01heE5zYnRTdXBwbHkEDW5zYnRBbW91bnRSYXcJAGUCCQBlAgUEbVJhdwUEc1JhdwUFc3RlcDMJAJQKAgUDbmlsCQDMCAIFDW5zYnRBbW91bnRSYXcJAMwIAgUHdXNkblBheQkAzAgCBQR3UmF3CQDMCAIFBHVSYXcJAMwIAgUEbVJhdwkAzAgCBQRzUmF3CQDMCAIJAQVhc0ludAEJAJEDAgUKa0NhbGNBcnJheQULa1Jlc3VsdElkeEEJAMwIAgkBBWFzSW50AQkAkQMCBQprQ2FsY0FycmF5BQ9rUmVzdWx0SWR4UGF1bEIJAMwIAgkBBWFzSW50AQkAkQMCBQprQ2FsY0FycmF5BRlrUmVzdWx0SWR4V1Jlc2VydmVzSW5Vc2RuCQDMCAIFBXByaWNlCQDMCAIJAQVhc0ludAEJAJEDAgUKa0NhbGNBcnJheQUQa1Jlc3VsdElkeE11bHRCUgkAzAgCCQEFYXNJbnQBCQCRAwIFCmtDYWxjQXJyYXkFE2tSZXN1bHRJZHhNdWx0UG93ZXIJAMwIAgkAkQMCBQprQ2FsY0FycmF5BRtrUmVzdWx0SWR4TXVsdEV4cEluUG93ZXJTdHIJAMwIAgkAkQMCBQprQ2FsY0FycmF5BRJrUmVzdWx0SWR4TXVsdEtTdHIJAMwIAgkApgMBBQVzdGVwMQkAzAgCCQCmAwEFBXN0ZXAyCQDMCAIFBXN0ZXAzBQNuaWwBaQEUc3VyZkZ1bmN0aW9uUkVBRE9OTFkCBmFtb3VudAdhc3NldElkAwkAZgIAAAUGYW1vdW50CQACAQIZYW1vdW50IHNob3VsZCBiZSBwb3NpdGl2ZQQFcHJpY2UFDGN1cnJlbnRQcmljZQQIcHJpY2VCaWcJALYCAQUFcHJpY2UECHJlc2VydmVXCQEHcmVzZXJ2ZQECBVdBVkVTBApyZXNlcnZlQmlnCQC2AgEFCHJlc2VydmVXBAZzdXBwbHkFDm5ldXRyaW5vU3VwcGx5BAlzdXBwbHlCaWcJALYCAQUGc3VwcGx5AwkAZwIFAkJSBQVNVUxUNgkAAgEJAKwCAgkArAICAgVCUiA9IAkApAMBBQJCUgIRLCBjYW5ub3QgYnV5IFNVUkYEC21heFdhdmVzUGF5CQBlAgkAawMFBnN1cHBseQUFTVVMVDgFBXByaWNlBQhyZXNlcnZlVwQKbWF4VXNkblBheQkAZQIFBnN1cHBseQkAawMFCHJlc2VydmVXBQVwcmljZQUFTVVMVDgECXVzZUFtb3VudAMJAAACBQdhc3NldElkBQ9uZXV0cmlub0Fzc2V0SWQDCQBmAgUGYW1vdW50BQptYXhVc2RuUGF5BQptYXhVc2RuUGF5BQZhbW91bnQDCQAAAgUHYXNzZXRJZAUHV0FWRVNJRAMJAGYCBQZhbW91bnQFC21heFdhdmVzUGF5BQttYXhXYXZlc1BheQUGYW1vdW50AAAECWFtb3VudEJpZwkAtgIBBQl1c2VBbW91bnQDCQAAAgUHYXNzZXRJZAUPbmV1dHJpbm9Bc3NldElkCQCUCgIFA25pbAkAzAgCCQCgAwEJALwCAwkAvAIDBQlhbW91bnRCaWcFBk1VTFRYOAUIcHJpY2VCaWcJALgCAgUJc3VwcGx5QmlnCQC6AgIFCWFtb3VudEJpZwUEVFdPWAUKcmVzZXJ2ZUJpZwkAzAgCAAAJAMwIAgUJdXNlQW1vdW50CQDMCAIFCHJlc2VydmVXCQDMCAIFBnN1cHBseQkAzAgCBQJCUgkAzAgCBQhyZXNlcnZlVwkAzAgCCQBlAgUGc3VwcGx5BQl1c2VBbW91bnQJAMwIAgkAawMJARZjb252ZXJ0V2F2ZXNUb05ldXRyaW5vAgUIcmVzZXJ2ZVcFBXByaWNlBQVNVUxUNgkAZQIFBnN1cHBseQUJdXNlQW1vdW50CQDMCAIJAGUCBQZhbW91bnQFCXVzZUFtb3VudAkAzAgCBQVwcmljZQUDbmlsAwkAAAIFB2Fzc2V0SWQFB1dBVkVTSUQJAJQKAgUDbmlsCQDMCAIJAKADAQkAvAIDBQlzdXBwbHlCaWcJAHcGCQC8AgMJALcCAgUKcmVzZXJ2ZUJpZwUJYW1vdW50QmlnBQdNVUxUWDE2BQpyZXNlcnZlQmlnABAFCEVVTEVSWDE2ABAAEAUGSEFMRlVQBQdNVUxUWDE2CQDMCAIFCXVzZUFtb3VudAkAzAgCAAAJAMwIAgUIcmVzZXJ2ZVcJAMwIAgUGc3VwcGx5CQDMCAIFAkJSCQDMCAIJAGQCBQhyZXNlcnZlVwUJdXNlQW1vdW50CQDMCAIFBnN1cHBseQkAzAgCCQBrAwkBFmNvbnZlcnRXYXZlc1RvTmV1dHJpbm8CCQBkAgUIcmVzZXJ2ZVcFCXVzZUFtb3VudAUFcHJpY2UFBU1VTFQ2BQZzdXBwbHkJAMwIAgkAZQIFBmFtb3VudAUJdXNlQW1vdW50CQDMCAIFBXByaWNlBQNuaWwJAAIBAhFVbnN1cHBvcnRlZCBhc3NldAFpASBjYWxjQ29udHJhY3ROc2J0UHJpY2VTWVNSRUFET05MWQEPbnNidFN1cHBseURFTFRBBA9uZXV0cmlub01ldHJpY3MJAQlhc0FueUxpc3QBCQD8BwQFBHRoaXMCGmNhbGNOZXV0aW5vTWV0cmljc1JFQURPTkxZBQNuaWwFA25pbAQFcHJpY2UJAQVhc0ludAEJAJEDAgUPbmV1dHJpbm9NZXRyaWNzBQ9uTWV0cmljSWR4UHJpY2UEBHdSYXcJAQVhc0ludAEJAJEDAgUPbmV1dHJpbm9NZXRyaWNzBRFuTWV0cmljSWR4UmVzZXJ2ZQQEdVJhdwkAZQIJAQVhc0ludAEJAJEDAgUPbmV1dHJpbm9NZXRyaWNzBRRuTWV0cmljSWR4VXNkblN1cHBseQUPbnNidFN1cHBseURFTFRBBARzUmF3CQBkAgkBBWFzSW50AQkAkQMCBQ9uZXV0cmlub01ldHJpY3MFFG5NZXRyaWNJZHhOc2J0U3VwcGx5BQ9uc2J0U3VwcGx5REVMVEEEBG1SYXcJAQVhc0ludAEJAJEDAgUPbmV1dHJpbm9NZXRyaWNzBRduTWV0cmljSWR4TWF4TnNidFN1cHBseQQKa0NhbGNBcnJheQkBCWFzQW55TGlzdAEJAPwHBAUEdGhpcwISY2FsY3VsYXRlS1JFQURPTkxZCQDMCAIFBHdSYXcJAMwIAgUEdVJhdwkAzAgCBQVwcmljZQkAzAgCBQRtUmF3CQDMCAIFBHNSYXcFA25pbAUDbmlsBAhtdWx0S1gxNgkApwMBCQEIYXNTdHJpbmcBCQCRAwIFCmtDYWxjQXJyYXkFEmtSZXN1bHRJZHhNdWx0S1N0cgQMbXVsdFN0ZXAxWDE2CQC8AgMJALYCAQUEbVJhdwUHTVVMVFgxNgkAtgIBCQBlAgUEbVJhdwUEc1JhdwQMbXVsdFN0ZXAyWDE2CQC8AgMFDG11bHRTdGVwMVgxNgUMbXVsdFN0ZXAxWDE2BQdNVUxUWDE2BBVtdWx0TnNidDJ1c2RuUHJpY2VYMTYJALwCAwUIbXVsdEtYMTYFDG11bHRTdGVwMlgxNgUHTVVMVFgxNgQObnNidDJ1c2RuUHJpY2UJAKADAQkAvAIDBRVtdWx0TnNidDJ1c2RuUHJpY2VYMTYJALYCAQUFTVVMVDYFB01VTFRYMTYED25zYnQyd2F2ZXNQcmljZQkAawMFDm5zYnQydXNkblByaWNlBQVNVUxUNgUFcHJpY2UJAJQKAgUDbmlsCQDMCAIFDm5zYnQydXNkblByaWNlCQDMCAIFD25zYnQyd2F2ZXNQcmljZQUDbmlsAWkBGmNhbGNOZXV0aW5vTWV0cmljc1JFQURPTkxZAAQNbnNidFN1cHBseU1BWAgJAQV2YWx1ZQEJAOwHAQULbnNidEFzc2V0SWQIcXVhbnRpdHkECm5zYnRTdXBwbHkJAGUCBQ1uc2J0U3VwcGx5TUFYCQDwBwIFD2F1Y3Rpb25Db250cmFjdAULbnNidEFzc2V0SWQECnN1cmZTdXBwbHkICQEFdmFsdWUBCQDsBwEFC3N1cmZBc3NldElkCHF1YW50aXR5BApiYXNrZXRJbmZvCQENZ2V0QmFza2V0SW5mbwAJAJQKAgUDbmlsCQDMCAIFDGN1cnJlbnRQcmljZQkAzAgCBRVuZXV0cmlub0xvY2tlZEJhbGFuY2UJAMwIAgUSd2F2ZXNMb2NrZWRCYWxhbmNlCQDMCAIJAQdyZXNlcnZlAQIFV0FWRVMJAMwIAgkBDXJlc2VydmVzSW5Vc2QBAgVXQVZFUwkAzAgCBQ5uZXV0cmlub1N1cHBseQkAzAgCBRluZXV0cmlub091dE9mTWFya2V0U3VwcGx5CQDMCAIFE25ldXRyaW5vVG90YWxTdXBwbHkJAMwIAgUCQlIJAMwIAgUKbnNidFN1cHBseQkAzAgCBQ1uc2J0U3VwcGx5TUFYCQDMCAIFCnN1cmZTdXBwbHkJAMwIAgUNdXNkblVzZHRQZWdYNgkAzAgCBQ9jdXJyZW50UHJpY2VBZGoJAMwIAggFCmJhc2tldEluZm8CXzEJAMwIAggFCmJhc2tldEluZm8CXzIJAMwIAggFCmJhc2tldEluZm8CXzMFA25pbAFpASFnZXRVbnN0YWtlQ29taXNzaW9uQW1vdW50UkVBRE9OTFkDBmFtb3VudAtzdGFydEhlaWdodAhoYWxmTGlmZQkAlAoCBQNuaWwJAGsDBQZhbW91bnQJAGwGAAIAAAkAawMJAQEtAQkAZQIFBmhlaWdodAULc3RhcnRIZWlnaHQFBU1VTFQ4BQhoYWxmTGlmZQAIAAgFBkhBTEZVUAUFTVVMVDgBaQETbWVyZ2VTdGFrZXNSRUFET05MWQUHYW1vdW50MQdoZWlnaHQxB2Ftb3VudDIHaGVpZ2h0MghoYWxmTGlmZQQBdwkAawMFB2Ftb3VudDIJAGwGAAIAAAkAawMJAGUCBQdoZWlnaHQyBQdoZWlnaHQxBQVNVUxUOAUIaGFsZkxpZmUACAAIBQZIQUxGVVAFBU1VTFQ4BAF2CQBrAwkAZAIFB2Ftb3VudDEFB2Ftb3VudDIFBU1VTFQ4CQBkAgUHYW1vdW50MQUBdwkAlAoCBQNuaWwJAGQCBQdoZWlnaHQxCQBpAgkAZQIFBUhBTEY4CQBoAgUIaGFsZkxpZmUJAG0GBQF2AAgAAgAAAAgFBkhBTEZVUAUFTVVMVDgBAnR4AQZ2ZXJpZnkABBNwdWJLZXlBZG1pbnNMaXN0U3RyCQC5CQIJAMwIAgIsR0pkTFNhTGl2NUs3eHVlamFjOG1jUmNIb3lvM2RQckVTcnZrdEczYTZNQVIJAMwIAgIsRVl3Wm1VUmQ1S0thUVJCanNWYTZnOERQaXNGb1M2U292Ukp0RmlMNWdNSFUJAMwIAgIsRHRtQWZ1RGRDckhLOHNwZEFlQVl6cTZNc1plZ2VEOWduc3JwdVRSa0NiVkEJAMwIAgIsNVdSWEZTandjVGJOZktjSnM4WnFYbVNTV1lzU1ZKVXRNdk1xWmo1aEg0TmMFA25pbAUDU0VQBBBwdWJLZXlBZG1pbnNMaXN0CQC1CQIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUPY29udHJvbENvbnRyYWN0Agwlc19fbXVsdGlzaWcFE3B1YktleUFkbWluc0xpc3RTdHIFA1NFUAQFY291bnQJAGQCCQBkAgkAZAIDCQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwAACQDZBAEJAJEDAgUQcHViS2V5QWRtaW5zTGlzdAAAAAEAAAMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAEJANkEAQkAkQMCBRBwdWJLZXlBZG1pbnNMaXN0AAEAAQAAAwkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAgkA2QQBCQCRAwIFEHB1YktleUFkbWluc0xpc3QAAgABAAADCQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwADCQDZBAEJAJEDAgUQcHViS2V5QWRtaW5zTGlzdAADAAIAAAkAZwIFBWNvdW50AAPqi6ti", "height": 4142872, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 2TgCT7gX6dPAK8VsvJHxQT7maAxBGVccptnQg4dL89cc Next: none Diff:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let revisionNum = "84925bdd892fd3edaba91bacee32ee293f796de0"
4+let revisionNum = ""
55
66 let MULTSCALE = 8
77
101101
102102
103103 func keySurfAssetId () = "surf_asset_id"
104+
105+
106+func keyWindAssetId () = "wind_asset_id"
104107
105108
106109 func swapsTimeframeKEY () = "swaps_timeframe"
210213
211214 let IdxControlCfgPegProviderDapp = 14
212215
216+let IdxControlCfgWindProxyDapp = 16
217+
213218 func keyControlAddress () = "%s%s__config__controlAddress"
214219
215220
236241
237242 let pegProviderContract = getContractAddressOrFail(controlCfg, IdxControlCfgPegProviderDapp)
238243
244+let windProxyContract = getContractAddressOrFail(controlCfg, IdxControlCfgWindProxyDapp)
245+
239246 let neutrinoAssetIdStr = getStringOrFail(neutrinoContract, keyNeutrinoAssetId())
240247
241248 let neutrinoAssetId = fromBase58String(neutrinoAssetIdStr)
243250 let nsbtAssetId = fromBase58String(getStringValue(neutrinoContract, keyNsbtAssetId()))
244251
245252 let surfAssetId = fromBase58String(getStringValue(auctionContract, keySurfAssetId()))
253+
254+let windAssetIdStr = getStringOrFail(neutrinoContract, keyWindAssetId())
255+
256+let windAssetId = fromBase58String(windAssetIdStr)
246257
247258 func keyBalanceLocked () = "balance_lock_"
248259
311322 let tempAssetId = fromBase58String(assetId)
312323 if ((tempAssetId == WAVESID))
313324 then (wavesBalance(neutrinoContract).regular - wavesLockedBalance)
314- else (assetBalance(neutrinoContract, tempAssetId) - valueOrElse(getInteger(neutrinoContract, keyTokenLockedBalance(assetId)), 0))
325+ else if ((tempAssetId == windAssetId))
326+ then (assetBalance(neutrinoContract, tempAssetId) + asInt(invoke(windProxyContract, "balanceREADONLY", nil, nil)))
327+ else (assetBalance(neutrinoContract, tempAssetId) - valueOrElse(getInteger(neutrinoContract, keyTokenLockedBalance(assetId)), 0))
315328 }
316329
317330
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let revisionNum = "84925bdd892fd3edaba91bacee32ee293f796de0"
4+let revisionNum = ""
55
66 let MULTSCALE = 8
77
88 let SCALE16 = 16
99
1010 let SEP = "__"
1111
1212 let HALF8 = 50000000
1313
1414 let EULERX16 = toBigInt(27182818284590452)
1515
1616 let TWOX = toBigInt(2)
1717
1818 let MULT6 = 1000000
1919
2020 let MULTX6 = toBigInt(1000000)
2121
2222 let MULT8 = 100000000
2323
2424 let MULTX8 = toBigInt(100000000)
2525
2626 let MULTX10 = toBigInt(10000000000)
2727
2828 let MULTX16 = toBigInt(10000000000000000)
2929
3030 let WAVESID = fromBase58String("WAVES")
3131
3232 let kResultIdxA = 0
3333
3434 let kResultIdxPaulB = 1
3535
3636 let kResultIdxWReservesInUsdn = 2
3737
3838 let kResultIdxMultBR = 3
3939
4040 let kResultIdxMultPower = 4
4141
4242 let kResultIdxMultExpInPowerStr = 5
4343
4444 let kResultIdxMultKStr = 6
4545
4646 let nMetricIdxPrice = 0
4747
4848 let nMetricIdxUsdnLockedBalance = 1
4949
5050 let nMetricIdxWavesLockedBalance = 2
5151
5252 let nMetricIdxReserve = 3
5353
5454 let nMetricIdxReserveInUsdn = 4
5555
5656 let nMetricIdxUsdnSupply = 5
5757
5858 let nMetricIdxSurplus = 6
5959
6060 let nMetricIdxSurplusPercent = 7
6161
6262 let nMetricIdxBR = 8
6363
6464 let nMetricIdxNsbtSupply = 9
6565
6666 let nMetricIdxMaxNsbtSupply = 10
6767
6868 let nMetricIdxSurfSupply = 11
6969
7070 let nMetricUsdnUsdtPeg = 12
7171
7272 let nMetricCurrentPriceAdj = 13
7373
7474 let nMetricBasketInfo = 14
7575
7676 func keyNeutrinoAddress () = "%s%s__config__neutrinoAddress"
7777
7878
7979 func keySwapAmountAParam () = "%s%s__config__swapAParam"
8080
8181
8282 func keySwapAmountBParam () = "%s%s__config__swapBParam"
8383
8484
8585 func keyUsdnSwapAmountAParam () = "%s%s__config__usdnSwapAParam"
8686
8787
8888 func keyUsdnSwapAmountBParam () = "%s%s__config__usdnSwapBParam"
8989
9090
9191 func keyPriceAdjMinCoeff () = "%s%s__priceAdj__minCoefficient"
9292
9393
9494 func keyPriceAdjArbRegulator () = "%s%s__priceAdj__arbRegulator"
9595
9696
9797 func keyNeutrinoAssetId () = "neutrino_asset_id"
9898
9999
100100 func keyNsbtAssetId () = "bond_asset_id"
101101
102102
103103 func keySurfAssetId () = "surf_asset_id"
104+
105+
106+func keyWindAssetId () = "wind_asset_id"
104107
105108
106109 func swapsTimeframeKEY () = "swaps_timeframe"
107110
108111
109112 func keyUserLastQuickSwapHeight (userAddress) = makeString(["%s%s", "userLastQuickSwapHeight", userAddress], SEP)
110113
111114
112115 func keyQuickSwapUserSpentInPeriod (userAddress) = makeString(["%s%s", "quickSwapUserSpentInPeriod", userAddress], SEP)
113116
114117
115118 func basketAssetsKey () = "%s%s__common__basketAssets"
116119
117120
118121 func keyPrice () = "price"
119122
120123
121124 func keyPriceByAsset (assetId) = ("%s%s%s__common__priceByAsset__" + assetId)
122125
123126
124127 let RpdBalanceKey = "rpd_balance"
125128
126129 func rpdUserBalanceKey (owner,assetId) = makeString([RpdBalanceKey, assetId, owner], "_")
127130
128131
129132 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
130133
131134
132135 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
133136
134137
135138 func getNumberByKey (address,key) = valueOrElse(getInteger(address, key), 0)
136139
137140
138141 func getBoolOrFail (address,key) = valueOrErrorMessage(getBoolean(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
139142
140143
141144 func convertNeutrinoToWaves (amount,price) = fraction(amount, MULT8, price)
142145
143146
144147 func convertWavesToNeutrino (amount,price) = fraction(amount, price, MULT8)
145148
146149
147150 func toX16 (origVal,origScaleMult) = fraction(toBigInt(origVal), MULTX16, toBigInt(origScaleMult))
148151
149152
150153 func fromX16 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), MULTX16))
151154
152155
153156 func asAnyList (val) = match val {
154157 case valAnyLyst: List[Any] =>
155158 valAnyLyst
156159 case _ =>
157160 throw("fail to cast into List[Any]")
158161 }
159162
160163
161164 func asInt (val) = match val {
162165 case valInt: Int =>
163166 valInt
164167 case _ =>
165168 throw("fail to cast into Int")
166169 }
167170
168171
169172 func asString (val) = match val {
170173 case valStr: String =>
171174 valStr
172175 case _ =>
173176 throw("fail to cast into String")
174177 }
175178
176179
177180 func asPriceSTRUCT (v) = match v {
178181 case struct: (Int, Int, Int, Int) =>
179182 struct
180183 case _ =>
181184 throw("fail to cast into PriceSTRUCT")
182185 }
183186
184187
185188 let IdxControlCfgNeutrinoDapp = 1
186189
187190 let IdxControlCfgAuctionDapp = 2
188191
189192 let IdxControlCfgRpdDapp = 3
190193
191194 let IdxControlCfgMathDapp = 4
192195
193196 let IdxControlCfgLiquidationDapp = 5
194197
195198 let IdxControlCfgRestDapp = 6
196199
197200 let IdxControlCfgNodeRegistryDapp = 7
198201
199202 let IdxControlCfgNsbtStakingDapp = 8
200203
201204 let IdxControlCfgMediatorDapp = 9
202205
203206 let IdxControlCfgSurfStakingDapp = 10
204207
205208 let IdxControlCfgGnsbtControllerDapp = 11
206209
207210 let IdxControlCfgRestV2Dapp = 12
208211
209212 let IdxControlCfgGovernanceDapp = 13
210213
211214 let IdxControlCfgPegProviderDapp = 14
212215
216+let IdxControlCfgWindProxyDapp = 16
217+
213218 func keyControlAddress () = "%s%s__config__controlAddress"
214219
215220
216221 func keyControlCfg () = "%s__controlConfig"
217222
218223
219224 func readControlCfgOrFail (control) = split_4C(getStringOrFail(control, keyControlCfg()), SEP)
220225
221226
222227 func getContractAddressOrFail (controlCfg,idx) = valueOrErrorMessage(addressFromString(controlCfg[idx]), ("Control cfg doesn't contain address at index " + toString(idx)))
223228
224229
225230 let controlContract = addressFromStringValue(valueOrElse(getString(this, keyControlAddress()), "3P5Bfd58PPfNvBM2Hy8QfbcDqMeNtzg7KfP"))
226231
227232 let controlCfg = readControlCfgOrFail(controlContract)
228233
229234 let neutrinoContract = getContractAddressOrFail(controlCfg, IdxControlCfgNeutrinoDapp)
230235
231236 let auctionContract = getContractAddressOrFail(controlCfg, IdxControlCfgAuctionDapp)
232237
233238 let liquidationContract = getContractAddressOrFail(controlCfg, IdxControlCfgLiquidationDapp)
234239
235240 let usdnStakingContract = getContractAddressOrFail(controlCfg, IdxControlCfgRpdDapp)
236241
237242 let pegProviderContract = getContractAddressOrFail(controlCfg, IdxControlCfgPegProviderDapp)
238243
244+let windProxyContract = getContractAddressOrFail(controlCfg, IdxControlCfgWindProxyDapp)
245+
239246 let neutrinoAssetIdStr = getStringOrFail(neutrinoContract, keyNeutrinoAssetId())
240247
241248 let neutrinoAssetId = fromBase58String(neutrinoAssetIdStr)
242249
243250 let nsbtAssetId = fromBase58String(getStringValue(neutrinoContract, keyNsbtAssetId()))
244251
245252 let surfAssetId = fromBase58String(getStringValue(auctionContract, keySurfAssetId()))
253+
254+let windAssetIdStr = getStringOrFail(neutrinoContract, keyWindAssetId())
255+
256+let windAssetId = fromBase58String(windAssetIdStr)
246257
247258 func keyBalanceLocked () = "balance_lock_"
248259
249260
250261 func totalLockedKEY (swapType,assetId) = makeString(["%s%s%s", "balanceLock", swapType, assetId], SEP)
251262
252263
253264 func keyTokenLockedBalance (assetId) = totalLockedKEY("outNeutrino", assetId)
254265
255266
256267 func keyNeutrinoLockedBalance () = totalLockedKEY("outMulti", neutrinoAssetIdStr)
257268
258269
259270 func keyOldNeutrinoLockedBalance () = (keyBalanceLocked() + "neutrino")
260271
261272
262273 func keyOldWavesLockedBalance () = (keyBalanceLocked() + "waves")
263274
264275
265276 func calcUsdnOutOfMarketSupply () = {
266277 let outOfMarketAddressList = valueOrElse(getString(controlContract, "%s%s__control__outOfMarketAddressList"), "")
267278 if ((outOfMarketAddressList == ""))
268279 then 0
269280 else {
270281 func balancesSUM (outOfMarketSupply,nextAddress) = ((outOfMarketSupply + valueOrElse(getInteger(usdnStakingContract, rpdUserBalanceKey(nextAddress, neutrinoAssetIdStr)), 0)) + assetBalance(addressFromStringValue(nextAddress), neutrinoAssetId))
271282
272283 let $l = split(outOfMarketAddressList, SEP)
273284 let $s = size($l)
274285 let $acc0 = 0
275286 func $f0_1 ($a,$i) = if (($i >= $s))
276287 then $a
277288 else balancesSUM($a, $l[$i])
278289
279290 func $f0_2 ($a,$i) = if (($i >= $s))
280291 then $a
281292 else throw("List size exceeds 7")
282293
283294 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7)
284295 }
285296 }
286297
287298
288299 func readCurrentAvgPeg () = asPriceSTRUCT(invoke(pegProviderContract, "price", [4], nil))._2
289300
290301
291302 func adjustPrice (priceX6,usdnUsdtPegX6) = {
292303 let minCoeffX6 = valueOrElse(getInteger(this, keyPriceAdjMinCoeff()), 600000)
293304 let arbRegulatorX6 = valueOrElse(getInteger(this, keyPriceAdjArbRegulator()), 150000)
294305 let maxPriceCoeffX6 = max([minCoeffX6, fraction((MULT6 + arbRegulatorX6), usdnUsdtPegX6, MULT6)])
295306 let priceCoeffX6 = min([maxPriceCoeffX6, MULT6])
296307 fraction(priceX6, MULT6, priceCoeffX6)
297308 }
298309
299310
300311 let currentPrice = getIntegerValue(controlContract, keyPrice())
301312
302313 let usdnUsdtPegX6 = readCurrentAvgPeg()
303314
304315 let currentPriceAdj = adjustPrice(currentPrice, usdnUsdtPegX6)
305316
306317 let neutrinoLockedBalance = (valueOrElse(getInteger(neutrinoContract, keyOldNeutrinoLockedBalance()), 0) + valueOrElse(getInteger(neutrinoContract, keyNeutrinoLockedBalance()), 0))
307318
308319 let wavesLockedBalance = (valueOrElse(getInteger(neutrinoContract, keyOldWavesLockedBalance()), 0) + valueOrElse(getInteger(neutrinoContract, keyTokenLockedBalance("WAVES")), 0))
309320
310321 func reserve (assetId) = {
311322 let tempAssetId = fromBase58String(assetId)
312323 if ((tempAssetId == WAVESID))
313324 then (wavesBalance(neutrinoContract).regular - wavesLockedBalance)
314- else (assetBalance(neutrinoContract, tempAssetId) - valueOrElse(getInteger(neutrinoContract, keyTokenLockedBalance(assetId)), 0))
325+ else if ((tempAssetId == windAssetId))
326+ then (assetBalance(neutrinoContract, tempAssetId) + asInt(invoke(windProxyContract, "balanceREADONLY", nil, nil)))
327+ else (assetBalance(neutrinoContract, tempAssetId) - valueOrElse(getInteger(neutrinoContract, keyTokenLockedBalance(assetId)), 0))
315328 }
316329
317330
318331 func reservesInUsd (assetId) = {
319332 let vol = reserve(assetId)
320333 let pr = value(getInteger(controlContract, keyPriceByAsset(assetId)))
321334 fraction(vol, pr, MULT8)
322335 }
323336
324337
325338 let neutrinoOutOfMarketSupply = calcUsdnOutOfMarketSupply()
326339
327340 let neutrinoTotalSupply = (((neutrinoLockedBalance + value(assetInfo(neutrinoAssetId)).quantity) - assetBalance(neutrinoContract, neutrinoAssetId)) - assetBalance(liquidationContract, neutrinoAssetId))
328341
329342 let neutrinoSupply = (neutrinoTotalSupply - neutrinoOutOfMarketSupply)
330343
331344 func getBR () = {
332345 let basket = split(value(getString(neutrinoContract, basketAssetsKey())), SEP)
333346 func addBr (acc,assetId) = (acc + reservesInUsd(assetId))
334347
335348 let sumReserves = {
336349 let $l = basket
337350 let $s = size($l)
338351 let $acc0 = 0
339352 func $f0_1 ($a,$i) = if (($i >= $s))
340353 then $a
341354 else addBr($a, $l[$i])
342355
343356 func $f0_2 ($a,$i) = if (($i >= $s))
344357 then $a
345358 else throw("List size exceeds 10")
346359
347360 $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)
348361 }
349362 fraction(sumReserves, MULT6, neutrinoSupply)
350363 }
351364
352365
353366 let BR = if ((neutrinoSupply == 0))
354367 then 0
355368 else getBR()
356369
357370 func getBasketInfo () = {
358371 let basketAssets = value(getString(neutrinoContract, basketAssetsKey()))
359372 let basket = split(basketAssets, SEP)
360373 func weightCalc (acc,assetId) = {
361374 let vol = reserve(assetId)
362375 let pr = value(getInteger(controlContract, keyPriceByAsset(assetId)))
363376 let resU = fraction(vol, pr, MULT8)
364377 $Tuple2((acc._1 :+ $Tuple4(assetId, vol, resU, pr)), (acc._2 + resU))
365378 }
366379
367380 let t = {
368381 let $l = basket
369382 let $s = size($l)
370383 let $acc0 = $Tuple2(nil, 0)
371384 func $f0_1 ($a,$i) = if (($i >= $s))
372385 then $a
373386 else weightCalc($a, $l[$i])
374387
375388 func $f0_2 ($a,$i) = if (($i >= $s))
376389 then $a
377390 else throw("List size exceeds 10")
378391
379392 $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)
380393 }
381394 func combine (acc,item) = {
382395 let share = if ((t._2 == 0))
383396 then MULT6
384397 else fraction(item._3, MULT6, t._2)
385398 (acc :+ makeString([item._1, toString(share), toString(item._4), toString(item._2)], ":"))
386399 }
387400
388401 let weightedPrice = if ((neutrinoSupply == 0))
389402 then 0
390403 else fraction(t._2, MULT6, neutrinoSupply)
391404 $Tuple3(makeString({
392405 let $l = t._1
393406 let $s = size($l)
394407 let $acc0 = nil
395408 func $f1_1 ($a,$i) = if (($i >= $s))
396409 then $a
397410 else combine($a, $l[$i])
398411
399412 func $f1_2 ($a,$i) = if (($i >= $s))
400413 then $a
401414 else throw("List size exceeds 10")
402415
403416 $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)
404417 }, "_"), weightedPrice, t._2)
405418 }
406419
407420
408421 @Callable(i)
409422 func constructorV1 (neutrinoAddress,nsbtLockAddress,swapAmountAParam) = if ((i.caller != this))
410423 then throw("not authorized")
411424 else [StringEntry(keyNeutrinoAddress(), neutrinoAddress), IntegerEntry(keySwapAmountAParam(), swapAmountAParam)]
412425
413426
414427
415428 @Callable(i)
416429 func calcSwapLimitREADONLY (gNsbtAmount) = {
417430 let limitBasketTokenInUsd = if ((0 >= gNsbtAmount))
418431 then 0
419432 else {
420433 let aParamX8 = toBigInt(getIntOrFail(this, keySwapAmountAParam()))
421434 let bParamX16 = toBigInt(getIntOrFail(this, keySwapAmountBParam()))
422435 let powPartX8 = pow(toBigInt(gNsbtAmount), 6, bParamX16, 16, 8, CEILING)
423436 toInt(fraction(aParamX8, powPartX8, MULTX10))
424437 }
425438 let limitUsdn = if ((0 >= gNsbtAmount))
426439 then 0
427440 else {
428441 let aParamX8 = toBigInt(getIntOrFail(this, keyUsdnSwapAmountAParam()))
429442 let bParamX16 = toBigInt(getIntOrFail(this, keyUsdnSwapAmountBParam()))
430443 let powPartX8 = pow(toBigInt(gNsbtAmount), 6, bParamX16, 16, 8, CEILING)
431444 toInt(fraction(aParamX8, powPartX8, MULTX10))
432445 }
433446 $Tuple2(nil, [limitBasketTokenInUsd, 0, limitUsdn])
434447 }
435448
436449
437450
438451 @Callable(i)
439452 func calculateKREADONLY (wRaw,uRaw,price,mRaw,sRaw) = {
440453 let EXP = toBigInt(2718281)
441454 let EXPSCALE = 6
442455 let a = valueOrElse(getInteger(auctionContract, "nsbtCurveParam_a"), 3)
443456 let paulB = valueOrElse(getInteger(auctionContract, "nsbtCurveParam_b"), ((3 * MULT6) / 10))
444457 let wReservesInUsdn = convertWavesToNeutrino(wRaw, price)
445458 let multBR = fraction(wReservesInUsdn, MULT8, uRaw)
446459 if ((multBR > 10678564816))
447460 then throw((("BR=" + toString(multBR)) + " > 10678.564816% will overflow exponent"))
448461 else {
449462 let multPower = (a * (multBR - MULT8))
450463 let multExpInPower = pow(EXP, EXPSCALE, toBigInt(multPower), MULTSCALE, SCALE16, DOWN)
451464 let multK = fraction(toBigInt(paulB), multExpInPower, MULTX6)
452465 $Tuple2(nil, [a, paulB, wReservesInUsdn, multBR, multPower, toString(multExpInPower), toString(multK)])
453466 }
454467 }
455468
456469
457470
458471 @Callable(i)
459472 func curveFunctionREADONLY (wavesPayRaw) = {
460473 let neutrinoMetrics = asAnyList(invoke(this, "calcNeutinoMetricsREADONLY", nil, nil))
461474 let price = asInt(neutrinoMetrics[nMetricIdxPrice])
462475 let wRaw = asInt(neutrinoMetrics[nMetricIdxReserve])
463476 let uRaw = asInt(neutrinoMetrics[nMetricIdxUsdnSupply])
464477 let sRaw = asInt(neutrinoMetrics[nMetricIdxNsbtSupply])
465478 let mRaw = asInt(neutrinoMetrics[nMetricIdxMaxNsbtSupply])
466479 let kCalcArray = asAnyList(invoke(this, "calculateKREADONLY", [wRaw, uRaw, price, mRaw, sRaw], nil))
467480 let multK = parseBigIntValue(asString(kCalcArray[kResultIdxMultKStr]))
468481 let usdnPay = convertWavesToNeutrino(wavesPayRaw, price)
469482 let bigMaxNsbtSupply = toBigInt(mRaw)
470483 let bigNsbtSupply = toBigInt((mRaw - sRaw))
471484 let step1 = fraction(toBigInt(usdnPay), MULTX16, multK)
472485 let step2 = fraction(step1, bigNsbtSupply, bigMaxNsbtSupply)
473486 let step3 = toInt(fraction(bigNsbtSupply, bigMaxNsbtSupply, (step2 + bigMaxNsbtSupply)))
474487 let nsbtAmountRaw = ((mRaw - sRaw) - step3)
475488 $Tuple2(nil, [nsbtAmountRaw, usdnPay, wRaw, uRaw, mRaw, sRaw, asInt(kCalcArray[kResultIdxA]), asInt(kCalcArray[kResultIdxPaulB]), asInt(kCalcArray[kResultIdxWReservesInUsdn]), price, asInt(kCalcArray[kResultIdxMultBR]), asInt(kCalcArray[kResultIdxMultPower]), kCalcArray[kResultIdxMultExpInPowerStr], kCalcArray[kResultIdxMultKStr], toString(step1), toString(step2), step3])
476489 }
477490
478491
479492
480493 @Callable(i)
481494 func surfFunctionREADONLY (amount,assetId) = if ((0 > amount))
482495 then throw("amount should be positive")
483496 else {
484497 let price = currentPrice
485498 let priceBig = toBigInt(price)
486499 let reserveW = reserve("WAVES")
487500 let reserveBig = toBigInt(reserveW)
488501 let supply = neutrinoSupply
489502 let supplyBig = toBigInt(supply)
490503 if ((BR >= MULT6))
491504 then throw((("BR = " + toString(BR)) + ", cannot buy SURF"))
492505 else {
493506 let maxWavesPay = (fraction(supply, MULT8, price) - reserveW)
494507 let maxUsdnPay = (supply - fraction(reserveW, price, MULT8))
495508 let useAmount = if ((assetId == neutrinoAssetId))
496509 then if ((amount > maxUsdnPay))
497510 then maxUsdnPay
498511 else amount
499512 else if ((assetId == WAVESID))
500513 then if ((amount > maxWavesPay))
501514 then maxWavesPay
502515 else amount
503516 else 0
504517 let amountBig = toBigInt(useAmount)
505518 if ((assetId == neutrinoAssetId))
506519 then $Tuple2(nil, [toInt(fraction(fraction(amountBig, MULTX8, priceBig), (supplyBig - (amountBig / TWOX)), reserveBig)), 0, useAmount, reserveW, supply, BR, reserveW, (supply - useAmount), fraction(convertWavesToNeutrino(reserveW, price), MULT6, (supply - useAmount)), (amount - useAmount), price])
507520 else if ((assetId == WAVESID))
508521 then $Tuple2(nil, [toInt(fraction(supplyBig, log(fraction((reserveBig + amountBig), MULTX16, reserveBig), 16, EULERX16, 16, 16, HALFUP), MULTX16)), useAmount, 0, reserveW, supply, BR, (reserveW + useAmount), supply, fraction(convertWavesToNeutrino((reserveW + useAmount), price), MULT6, supply), (amount - useAmount), price])
509522 else throw("Unsupported asset")
510523 }
511524 }
512525
513526
514527
515528 @Callable(i)
516529 func calcContractNsbtPriceSYSREADONLY (nsbtSupplyDELTA) = {
517530 let neutrinoMetrics = asAnyList(invoke(this, "calcNeutinoMetricsREADONLY", nil, nil))
518531 let price = asInt(neutrinoMetrics[nMetricIdxPrice])
519532 let wRaw = asInt(neutrinoMetrics[nMetricIdxReserve])
520533 let uRaw = (asInt(neutrinoMetrics[nMetricIdxUsdnSupply]) - nsbtSupplyDELTA)
521534 let sRaw = (asInt(neutrinoMetrics[nMetricIdxNsbtSupply]) + nsbtSupplyDELTA)
522535 let mRaw = asInt(neutrinoMetrics[nMetricIdxMaxNsbtSupply])
523536 let kCalcArray = asAnyList(invoke(this, "calculateKREADONLY", [wRaw, uRaw, price, mRaw, sRaw], nil))
524537 let multKX16 = parseBigIntValue(asString(kCalcArray[kResultIdxMultKStr]))
525538 let multStep1X16 = fraction(toBigInt(mRaw), MULTX16, toBigInt((mRaw - sRaw)))
526539 let multStep2X16 = fraction(multStep1X16, multStep1X16, MULTX16)
527540 let multNsbt2usdnPriceX16 = fraction(multKX16, multStep2X16, MULTX16)
528541 let nsbt2usdnPrice = toInt(fraction(multNsbt2usdnPriceX16, toBigInt(MULT6), MULTX16))
529542 let nsbt2wavesPrice = fraction(nsbt2usdnPrice, MULT6, price)
530543 $Tuple2(nil, [nsbt2usdnPrice, nsbt2wavesPrice])
531544 }
532545
533546
534547
535548 @Callable(i)
536549 func calcNeutinoMetricsREADONLY () = {
537550 let nsbtSupplyMAX = value(assetInfo(nsbtAssetId)).quantity
538551 let nsbtSupply = (nsbtSupplyMAX - assetBalance(auctionContract, nsbtAssetId))
539552 let surfSupply = value(assetInfo(surfAssetId)).quantity
540553 let basketInfo = getBasketInfo()
541554 $Tuple2(nil, [currentPrice, neutrinoLockedBalance, wavesLockedBalance, reserve("WAVES"), reservesInUsd("WAVES"), neutrinoSupply, neutrinoOutOfMarketSupply, neutrinoTotalSupply, BR, nsbtSupply, nsbtSupplyMAX, surfSupply, usdnUsdtPegX6, currentPriceAdj, basketInfo._1, basketInfo._2, basketInfo._3])
542555 }
543556
544557
545558
546559 @Callable(i)
547560 func getUnstakeComissionAmountREADONLY (amount,startHeight,halfLife) = $Tuple2(nil, fraction(amount, pow(2, 0, fraction(-((height - startHeight)), MULT8, halfLife), 8, 8, HALFUP), MULT8))
548561
549562
550563
551564 @Callable(i)
552565 func mergeStakesREADONLY (amount1,height1,amount2,height2,halfLife) = {
553566 let w = fraction(amount2, pow(2, 0, fraction((height2 - height1), MULT8, halfLife), 8, 8, HALFUP), MULT8)
554567 let v = fraction((amount1 + amount2), MULT8, (amount1 + w))
555568 $Tuple2(nil, (height1 + ((HALF8 - (halfLife * log(v, 8, 2, 0, 8, HALFUP))) / MULT8)))
556569 }
557570
558571
559572 @Verifier(tx)
560573 func verify () = {
561574 let pubKeyAdminsListStr = makeString(["GJdLSaLiv5K7xuejac8mcRcHoyo3dPrESrvktG3a6MAR", "EYwZmURd5KKaQRBjsVa6g8DPisFoS6SovRJtFiL5gMHU", "DtmAfuDdCrHK8spdAeAYzq6MsZegeD9gnsrpuTRkCbVA", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"], SEP)
562575 let pubKeyAdminsList = split(valueOrElse(getString(controlContract, "%s__multisig"), pubKeyAdminsListStr), SEP)
563576 let count = ((((if (sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(pubKeyAdminsList[0])))
564577 then 1
565578 else 0) + (if (sigVerify(tx.bodyBytes, tx.proofs[1], fromBase58String(pubKeyAdminsList[1])))
566579 then 1
567580 else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[2], fromBase58String(pubKeyAdminsList[2])))
568581 then 1
569582 else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[3], fromBase58String(pubKeyAdminsList[3])))
570583 then 2
571584 else 0))
572585 (count >= 3)
573586 }
574587

github/deemru/w8io/786bc32 
61.72 ms