tx · 74rf9Vdqi9f8SHdP9ipAKhpd68m8VwbfeMKCcNExBi45 3NAg2HDvKz7gwrNc2wnUxdK74NydBFUXTYP: -0.03300000 Waves 2024.12.10 20:31 [3408805] smart account 3NAg2HDvKz7gwrNc2wnUxdK74NydBFUXTYP > SELF 0.00000000 Waves
{ "type": 13, "id": "74rf9Vdqi9f8SHdP9ipAKhpd68m8VwbfeMKCcNExBi45", "fee": 3300000, "feeAssetId": null, "timestamp": 1733851942662, "version": 2, "chainId": 84, "sender": "3NAg2HDvKz7gwrNc2wnUxdK74NydBFUXTYP", "senderPublicKey": "BEbZF8zo7WjaQFZFFuPs7hqSLEgGwjwQFGg4tSidf9C3", "proofs": [ "5UVYpaYXrSyaDbXDwpMnHxoT884NVqud31k9L9EkFt4PkVfVs9WxxEag4LYTnJek7chFyBf9Rk3ngMLhdkueQdHv" ], "script": "base64:BwJuCAISCAoGCAgICAgIEggKBggICAgICBIJCgcICAgICAgIEgUKAwgICBIDCgEIEgwKCggICAgICAgICAgSBgoECAgICBIFCgMBCAgSBQoDAQgIEgMKAQESAwoBCBIDCgEIEgASABIDCgEIEgMKAQhxAAlTRVBBUkFUT1ICAl9fAAxLRVlfTVVMVElTSUcCCE1VTFRJU0lHAApLRVlfU1RBVFVTAgZTVEFUVVMACEtFWV9JTklUAgRJTklUAApLRVlfUEFVU0VEAgZQQVVTRUQACktFWV9QQVVTRVICBlBBVVNFUgAMS0VZX0VYRUNVVE9SAghFWEVDVVRPUgATS0VZX0NBTExFUl9DT05UUkFDVAIPQ0FMTEVSX0NPTlRSQUNUAA9LRVlfV0FWRVNfVkFVTFQCC1dBVkVTX1ZBVUxUABNLRVlfQUNDT1VOVF9TVE9SQUdFAg9BQ0NPVU5UX1NUT1JBR0UACUtFWV9DSEFJTgIFQ0hBSU4AEktFWV9BU1NFVF9DVVJSRU5DWQIOQVNTRVRfQ1VSUkVOQ1kAEktFWV9BU1NFVF9SRVNFUlZFUwIOQVNTRVRfUkVTRVJWRVMAGUtFWV9BU1NFVF9SRVNFUlZFU19MT0NLRUQCFUFTU0VUX1JFU0VSVkVTX0xPQ0tFRAAYS0VZX1VTRVJfTE9DS0VEX0NVUlJFTkNZAhRVU0VSX0xPQ0tFRF9DVVJSRU5DWQAVS0VZX0NVUlJFTkNZX1JFU0VSVkVTAhFDVVJSRU5DWV9SRVNFUlZFUwAbS0VZX1JFUVVFU1RfV0lUSERSQVdBTF9TSVpFAhdSRVFVRVNUX1dJVEhEUkFXQUxfU0laRQAWS0VZX1JFUVVFU1RfV0lUSERSQVdBTAISUkVRVUVTVF9XSVRIRFJBV0FMACJLRVlfUkVRVUVTVF9XSVRIRFJBV0FMX0JMT0NLX0RFTEFZAh5SRVFVRVNUX1dJVEhEUkFXQUxfQkxPQ0tfREVMQVkADUtFWV9TRVFVRU5DRVICCVNFUVVFTkNFUgATS0VZX1dJVEhEUkFXQUxfSEFTSAIPV0lUSERSQVdBTF9IQVNIABFLRVlfVkFVTFRfQURBUFRFUgINVkFVTFRfQURBUFRFUgAWS0VZX1JFV0FSRF9ESVNUUklCVVRPUgISUkVXQVJEX0RJU1RSSUJVVE9SABlLRVlfUkVMQVlFUl9GRUVfUkVDSVBJRU5UAhVSRUxBWUVSX0ZFRV9SRUNJUElFTlQADEZVTkNfREVQT1NJVAIHZGVwb3NpdAAVRlVOQ19HRVRfVVNFUl9CQUxBTkNFAg5nZXRVc2VyQmFsYW5jZQAWRlVOQ19JTlRFUk5BTF9UUkFOU0ZFUgIQaW50ZXJuYWxUcmFuc2ZlcgANRlVOQ19XSVRIRFJBVwIId2l0aGRyYXcAG0ZVTkNfREVQT1NJVF9TVEFLSU5HX1JFV0FSRAIUZGVwb3NpdFN0YWtpbmdSZXdhcmQAFlJFUVVFU1RfU1RBVFVTX0NSRUFURUQAAAATUkVRVUVTVF9TVEFUVVNfRE9ORQABABdSRVFVRVNUX1NUQVRVU19SRUpFQ1RFRAACAAVXQVZFUwIFV0FWRVMAC1NQT1RfV0FMTEVUAgRTUE9UAAdNQVhfSU5UAP//////////fwALWkVST19CSUdJTlQJALYCAQAAAApPTkVfQklHSU5UCQC2AgEAAQAHT05FX0RBWQCAuJkpAA5BTEdfVFlQRV9XQVZFUwABAAxBTEdfVFlQRV9FVk0AAgAMV0FWRVNfUFJFRklYAQT///8BABRFVk1fU0lHTkFUVVJFX1BSRUZJWAEcGUV0aGVyZXVtIFNpZ25lZCBNZXNzYWdlOgozMgEQX3ZhbGlkYXRlQWRkcmVzcwIIYWRkcmVzc18EZXJyXwQHJG1hdGNoMAkApggBBQhhZGRyZXNzXwMJAAECBQckbWF0Y2gwAgdBZGRyZXNzBAFhBQckbWF0Y2gwBgkAAgEFBGVycl8BDF92YWxpZGF0ZUludAQEdmFsXw5sb3dlckJvdW5kYXJ5Xw51cHBlckJvdW5kYXJ5XwRlcnJfAwMJAGYCBQ5sb3dlckJvdW5kYXJ5XwUEdmFsXwYJAGYCBQR2YWxfBQ51cHBlckJvdW5kYXJ5XwkAAgEFBGVycl8GAQ9fdmFsaWRhdGVCaWdJbnQDBHZhbF8ObG93ZXJCb3VuZGFyeV8EZXJyXwMJAL8CAgUObG93ZXJCb3VuZGFyeV8FBHZhbF8JAAIBBQRlcnJfBgERX3ZhbGlkYXRlQmlnSW50XzIEBHZhbF8ObG93ZXJCb3VuZGFyeV8OdXBwZXJCb3VuZGFyeV8EZXJyXwMDCQC/AgIFDmxvd2VyQm91bmRhcnlfBQR2YWxfBgkAvwICBQR2YWxfBQ51cHBlckJvdW5kYXJ5XwkAAgEFBGVycl8GAQ9fdmFsaWRhdGVTdHJpbmcCBHZhbF8EZXJyXwMDCQBnAgAACQCxAgEFBHZhbF8GCQEIY29udGFpbnMCBQR2YWxfBQlTRVBBUkFUT1IJAAIBBQRlcnJfBgEUX3ZhbGlkYXRlU3RyaW5nRXF1YWwDBXZhbDFfBXZhbDJfBGVycl8DCQECIT0CBQV2YWwxXwUFdmFsMl8JAAIBBQRlcnJfBgEJX2xvYWRJbml0AAQHJG1hdGNoMAkAoAgBBQhLRVlfSU5JVAMJAAECBQckbWF0Y2gwAgdCb29sZWFuBAFhBQckbWF0Y2gwBQFhBwEJX3NhdmVJbml0AQdpc0luaXRfCQDMCAIJAQxCb29sZWFuRW50cnkCBQhLRVlfSU5JVAUHaXNJbml0XwUDbmlsAQpfbG9hZFBhdXNlAAQHJG1hdGNoMAkAoAgBBQpLRVlfUEFVU0VEAwkAAQIFByRtYXRjaDACB0Jvb2xlYW4EAWEFByRtYXRjaDAFAWEHAQpfc2F2ZVBhdXNlAQlpc1BhdXNlZF8JAMwIAgkBDEJvb2xlYW5FbnRyeQIFCktFWV9QQVVTRUQFCWlzUGF1c2VkXwUDbmlsAQtfbG9hZFBhdXNlcgAEByRtYXRjaDAJAKIIAQUKS0VZX1BBVVNFUgMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAWEFByRtYXRjaDAJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAWEJAQdBZGRyZXNzAQEAAQtfc2F2ZVBhdXNlcgEHcGF1c2VyXwkAzAgCCQELU3RyaW5nRW50cnkCBQpLRVlfUEFVU0VSCQClCAEFB3BhdXNlcl8FA25pbAENX2xvYWRNdWx0aXNpZwAEByRtYXRjaDAJAKIIAQUMS0VZX01VTFRJU0lHAwkAAQIFByRtYXRjaDACBlN0cmluZwQBYQUHJG1hdGNoMAkBEUBleHRyTmF0aXZlKDEwNjIpAQUBYQkBB0FkZHJlc3MBAQABDV9zYXZlTXVsdGlzaWcBCW11bHRpc2lnXwkAzAgCCQELU3RyaW5nRW50cnkCBQxLRVlfTVVMVElTSUcJAKUIAQUJbXVsdGlzaWdfBQNuaWwBE19sb2FkQ2FsbGVyQ29udHJhY3QBCGNoYWluSWRfBAckbWF0Y2gwCQCiCAEJALkJAgkAzAgCBRNLRVlfQ0FMTEVSX0NPTlRSQUNUCQDMCAIJAKQDAQUIY2hhaW5JZF8FA25pbAUJU0VQQVJBVE9SAwkAAQIFByRtYXRjaDACBlN0cmluZwQBYQUHJG1hdGNoMAUBYQIAARNfc2F2ZUNhbGxlckNvbnRyYWN0AghjaGFpbklkXw9jYWxsZXJDb250cmFjdF8JAMwIAgkBC1N0cmluZ0VudHJ5AgkAuQkCCQDMCAIFE0tFWV9DQUxMRVJfQ09OVFJBQ1QJAMwIAgkApAMBBQhjaGFpbklkXwUDbmlsBQlTRVBBUkFUT1IFD2NhbGxlckNvbnRyYWN0XwUDbmlsAQ1fbG9hZEV4ZWN1dG9yAAQHJG1hdGNoMAkAoggBBQxLRVlfRVhFQ1VUT1IDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFhBQckbWF0Y2gwCQERQGV4dHJOYXRpdmUoMTA2MikBBQFhCQEHQWRkcmVzcwEBAAENX3NhdmVFeGVjdXRvcgEJZXhlY3V0b3JfCQDMCAIJAQtTdHJpbmdFbnRyeQIFDEtFWV9FWEVDVVRPUgkApQgBBQlleGVjdXRvcl8FA25pbAETX2xvYWRBY2NvdW50U3RvcmFnZQAEByRtYXRjaDAJAKIIAQUTS0VZX0FDQ09VTlRfU1RPUkFHRQMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAWEFByRtYXRjaDAJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAWEJAQdBZGRyZXNzAQEAARNfc2F2ZUFjY291bnRTdG9yYWdlAQ9hY2NvdW50U3RvcmFnZV8JAMwIAgkBC1N0cmluZ0VudHJ5AgUTS0VZX0FDQ09VTlRfU1RPUkFHRQkApQgBBQ9hY2NvdW50U3RvcmFnZV8FA25pbAEPX2xvYWRXYXZlc1ZhdWx0AAQHJG1hdGNoMAkAoggBBQ9LRVlfV0FWRVNfVkFVTFQDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFhBQckbWF0Y2gwCQERQGV4dHJOYXRpdmUoMTA2MikBBQFhCQEHQWRkcmVzcwEBAAEPX3NhdmVXYXZlc1ZhdWx0AQt3YXZlc1ZhdWx0XwkAzAgCCQELU3RyaW5nRW50cnkCBQ9LRVlfV0FWRVNfVkFVTFQJAKUIAQULd2F2ZXNWYXVsdF8FA25pbAEKX2xvYWRDaGFpbgEIY2hhaW5JZF8EByRtYXRjaDAJAKIIAQkAuQkCCQDMCAIFCUtFWV9DSEFJTgkAzAgCCQCkAwEFCGNoYWluSWRfBQNuaWwFCVNFUEFSQVRPUgMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAWEFByRtYXRjaDAFAWECAAEKX3NhdmVDaGFpbgIIY2hhaW5JZF8FbmFtZV8JAMwIAgkBC1N0cmluZ0VudHJ5AgkAuQkCCQDMCAIFCUtFWV9DSEFJTgkAzAgCCQCkAwEFCGNoYWluSWRfBQNuaWwFCVNFUEFSQVRPUgUFbmFtZV8FA25pbAESX2xvYWRBc3NldEN1cnJlbmN5AghjaGFpbklkXwZhc3NldF8EByRtYXRjaDAJAKIIAQkAuQkCCQDMCAIFEktFWV9BU1NFVF9DVVJSRU5DWQkAzAgCCQCkAwEFCGNoYWluSWRfCQDMCAIFBmFzc2V0XwUDbmlsBQlTRVBBUkFUT1IDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFhBQckbWF0Y2gwBQFhAgABEl9zYXZlQXNzZXRDdXJyZW5jeQMIY2hhaW5JZF8GYXNzZXRfCWN1cnJlbmN5XwkAzAgCCQELU3RyaW5nRW50cnkCCQC5CQIJAMwIAgUSS0VZX0FTU0VUX0NVUlJFTkNZCQDMCAIJAKQDAQUIY2hhaW5JZF8JAMwIAgUGYXNzZXRfBQNuaWwFCVNFUEFSQVRPUgUJY3VycmVuY3lfBQNuaWwBEl9sb2FkQXNzZXRSZXNlcnZlcwIIY2hhaW5JZF8GYXNzZXRfBAckbWF0Y2gwCQCiCAEJALkJAgkAzAgCBRJLRVlfQVNTRVRfUkVTRVJWRVMJAMwIAgkApAMBBQhjaGFpbklkXwkAzAgCBQZhc3NldF8FA25pbAUJU0VQQVJBVE9SAwkAAQIFByRtYXRjaDACBlN0cmluZwQBYQUHJG1hdGNoMAkApwMBBQFhBQtaRVJPX0JJR0lOVAESX3NhdmVBc3NldFJlc2VydmVzAwhjaGFpbklkXwZhc3NldF8JcmVzZXJ2ZXNfCQDMCAIJAQtTdHJpbmdFbnRyeQIJALkJAgkAzAgCBRJLRVlfQVNTRVRfUkVTRVJWRVMJAMwIAgkApAMBBQhjaGFpbklkXwkAzAgCBQZhc3NldF8FA25pbAUJU0VQQVJBVE9SCQCmAwEFCXJlc2VydmVzXwUDbmlsARhfbG9hZEFzc2V0UmVzZXJ2ZXNMb2NrZWQCCGNoYWluSWRfBmFzc2V0XwQHJG1hdGNoMAkAoggBCQC5CQIJAMwIAgUZS0VZX0FTU0VUX1JFU0VSVkVTX0xPQ0tFRAkAzAgCCQCkAwEFCGNoYWluSWRfCQDMCAIFBmFzc2V0XwUDbmlsBQlTRVBBUkFUT1IDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFhBQckbWF0Y2gwCQCnAwEFAWEFC1pFUk9fQklHSU5UARhfc2F2ZUFzc2V0UmVzZXJ2ZXNMb2NrZWQDCGNoYWluSWRfBmFzc2V0XwlyZXNlcnZlc18JAMwIAgkBC1N0cmluZ0VudHJ5AgkAuQkCCQDMCAIFGUtFWV9BU1NFVF9SRVNFUlZFU19MT0NLRUQJAMwIAgkApAMBBQhjaGFpbklkXwkAzAgCBQZhc3NldF8FA25pbAUJU0VQQVJBVE9SCQCmAwEFCXJlc2VydmVzXwUDbmlsARdfbG9hZFVzZXJMb2NrZWRDdXJyZW5jeQIJY3VycmVuY3lfBXVzZXJfBAckbWF0Y2gwCQCiCAEJALkJAgkAzAgCBRhLRVlfVVNFUl9MT0NLRURfQ1VSUkVOQ1kJAMwIAgUJY3VycmVuY3lfCQDMCAIFBXVzZXJfBQNuaWwFCVNFUEFSQVRPUgMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAWEFByRtYXRjaDAJAKcDAQUBYQULWkVST19CSUdJTlQBF19zYXZlVXNlckxvY2tlZEN1cnJlbmN5AwljdXJyZW5jeV8FdXNlcl8HYW1vdW50XwkAzAgCCQELU3RyaW5nRW50cnkCCQC5CQIJAMwIAgUYS0VZX1VTRVJfTE9DS0VEX0NVUlJFTkNZCQDMCAIFCWN1cnJlbmN5XwkAzAgCBQV1c2VyXwUDbmlsBQlTRVBBUkFUT1IJAKYDAQUHYW1vdW50XwUDbmlsARVfbG9hZEN1cnJlbmN5UmVzZXJ2ZXMBCWN1cnJlbmN5XwQHJG1hdGNoMAkAoggBCQC5CQIJAMwIAgUVS0VZX0NVUlJFTkNZX1JFU0VSVkVTCQDMCAIFCWN1cnJlbmN5XwUDbmlsBQlTRVBBUkFUT1IDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFhBQckbWF0Y2gwCQCnAwEFAWEFC1pFUk9fQklHSU5UARVfc2F2ZUN1cnJlbmN5UmVzZXJ2ZXMCCWN1cnJlbmN5XwlyZXNlcnZlc18JAMwIAgkBC1N0cmluZ0VudHJ5AgkAuQkCCQDMCAIFFUtFWV9DVVJSRU5DWV9SRVNFUlZFUwkAzAgCBQljdXJyZW5jeV8FA25pbAUJU0VQQVJBVE9SCQCmAwEFCXJlc2VydmVzXwUDbmlsARpfbG9hZFJlcXVlc3RXaXRoZHJhd2FsU2l6ZQAEByRtYXRjaDAJAJ8IAQUbS0VZX1JFUVVFU1RfV0lUSERSQVdBTF9TSVpFAwkAAQIFByRtYXRjaDACA0ludAQBYQUHJG1hdGNoMAUBYQAAARpfc2F2ZVJlcXVlc3RXaXRoZHJhd2FsU2l6ZQEEdmFsXwkAzAgCCQEMSW50ZWdlckVudHJ5AgUbS0VZX1JFUVVFU1RfV0lUSERSQVdBTF9TSVpFBQR2YWxfBQNuaWwBFl9sb2FkUmVxdWVzdFdpdGhkcmF3YWwBBmluZGV4XwQHJG1hdGNoMAkAoggBCQC5CQIJAMwIAgUWS0VZX1JFUVVFU1RfV0lUSERSQVdBTAkAzAgCCQCkAwEFBmluZGV4XwUDbmlsBQlTRVBBUkFUT1IDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFhBQckbWF0Y2gwBAZzdHJ1Y3QJALUJAgUBYQUJU0VQQVJBVE9SCQCaCggJAJEDAgUGc3RydWN0AAAJAJEDAgUGc3RydWN0AAEJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZzdHJ1Y3QAAgkAkQMCBQZzdHJ1Y3QAAwkApwMBCQCRAwIFBnN0cnVjdAAECQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGc3RydWN0AAUJAJEDAgUGc3RydWN0AAYJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZzdHJ1Y3QABwkAmgoIAgACAAAAAgAFC1pFUk9fQklHSU5UAAACAAUWUkVRVUVTVF9TVEFUVVNfQ1JFQVRFRAEWX3NhdmVSZXF1ZXN0V2l0aGRyYXdhbAIGaW5kZXhfCHJlcXVlc3RfCQDMCAIJAQtTdHJpbmdFbnRyeQIJALkJAgkAzAgCBRZLRVlfUkVRVUVTVF9XSVRIRFJBV0FMCQDMCAIJAKQDAQUGaW5kZXhfBQNuaWwFCVNFUEFSQVRPUgkAuQkCCQDMCAIIBQhyZXF1ZXN0XwJfMQkAzAgCCAUIcmVxdWVzdF8CXzIJAMwIAgkApAMBCAUIcmVxdWVzdF8CXzMJAMwIAggFCHJlcXVlc3RfAl80CQDMCAIJAKYDAQgFCHJlcXVlc3RfAl81CQDMCAIJAKQDAQgFCHJlcXVlc3RfAl82CQDMCAIIBQhyZXF1ZXN0XwJfNwkAzAgCCQCkAwEIBQhyZXF1ZXN0XwJfOAUDbmlsBQlTRVBBUkFUT1IFA25pbAEgX2xvYWRSZXF1ZXN0V2l0aGRyYXdhbEJsb2NrRGVsYXkABAckbWF0Y2gwCQCfCAEFIktFWV9SRVFVRVNUX1dJVEhEUkFXQUxfQkxPQ0tfREVMQVkDCQABAgUHJG1hdGNoMAIDSW50BAFhBQckbWF0Y2gwBQFhAAABIF9zYXZlUmVxdWVzdFdpdGhkcmF3YWxCbG9ja0RlbGF5AQZkZWxheV8JAMwIAgkBDEludGVnZXJFbnRyeQIFIktFWV9SRVFVRVNUX1dJVEhEUkFXQUxfQkxPQ0tfREVMQVkFBmRlbGF5XwUDbmlsAQ5fbG9hZFNlcXVlbmNlcgAEByRtYXRjaDAJAKIIAQUNS0VZX1NFUVVFTkNFUgMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAWEFByRtYXRjaDAJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAWEJAQdBZGRyZXNzAQEAAQ5fc2F2ZVNlcXVlbmNlcgEKc2VxdWVuY2VyXwkAzAgCCQELU3RyaW5nRW50cnkCBQ1LRVlfU0VRVUVOQ0VSCQClCAEFCnNlcXVlbmNlcl8FA25pbAETX2xvYWRXaXRoZHJhd2FsSGFzaAEPd2l0aGRyYXdhbEhhc2hfBAckbWF0Y2gwCQCiCAEJALkJAgkAzAgCBRNLRVlfV0lUSERSQVdBTF9IQVNICQDMCAIJANgEAQUPd2l0aGRyYXdhbEhhc2hfBQNuaWwFCVNFUEFSQVRPUgMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAWEFByRtYXRjaDAFAWECAAETX3NhdmVXaXRoZHJhd2FsSGFzaAIPd2l0aGRyYXdhbEhhc2hfBXR4SWRfCQDMCAIJAQtTdHJpbmdFbnRyeQIJALkJAgkAzAgCBRNLRVlfV0lUSERSQVdBTF9IQVNICQDMCAIJANgEAQUPd2l0aGRyYXdhbEhhc2hfBQNuaWwFCVNFUEFSQVRPUgUFdHhJZF8FA25pbAERX2xvYWRWYXVsdEFkYXB0ZXIABAckbWF0Y2gwCQCiCAEFEUtFWV9WQVVMVF9BREFQVEVSAwkAAQIFByRtYXRjaDACBlN0cmluZwQBYQUHJG1hdGNoMAkBEUBleHRyTmF0aXZlKDEwNjIpAQUBYQkBB0FkZHJlc3MBAQABEV9zYXZlVmF1bHRBZGFwdGVyAQ12YXVsdEFkYXB0ZXJfCQDMCAIJAQtTdHJpbmdFbnRyeQIFEUtFWV9WQVVMVF9BREFQVEVSCQClCAEFDXZhdWx0QWRhcHRlcl8FA25pbAEWX2xvYWRSZXdhcmREaXN0cmlidXRvcgAEByRtYXRjaDAJAKIIAQUWS0VZX1JFV0FSRF9ESVNUUklCVVRPUgMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAWEFByRtYXRjaDAFAWECAAEWX3NhdmVSZXdhcmREaXN0cmlidXRvcgEMZGlzdHJpYnV0b3JfCQDMCAIJAQtTdHJpbmdFbnRyeQIFFktFWV9SRVdBUkRfRElTVFJJQlVUT1IFDGRpc3RyaWJ1dG9yXwUDbmlsARhfbG9hZFJlbGF5ZXJGZWVSZWNpcGllbnQABAckbWF0Y2gwCQCiCAEFGUtFWV9SRUxBWUVSX0ZFRV9SRUNJUElFTlQDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFhBQckbWF0Y2gwBQFhAgABGF9zYXZlUmVsYXllckZlZVJlY2lwaWVudAEUcmVsYXllckZlZVJlY2lwaWVudF8JAMwIAgkBC1N0cmluZ0VudHJ5AgUZS0VZX1JFTEFZRVJfRkVFX1JFQ0lQSUVOVAUUcmVsYXllckZlZVJlY2lwaWVudF8FA25pbAERX29ubHlUaGlzQ29udHJhY3QBB2NhbGxlcl8DCQECIT0CBQdjYWxsZXJfBQR0aGlzCQACAQIZX29ubHlUaGlzQ29udHJhY3Q6IHJldmVydAYBEF93aGVuTXVsdGlzaWdTZXQAAwkAAAIJAQ1fbG9hZE11bHRpc2lnAAkBB0FkZHJlc3MBAQAJAAIBAhhfd2hlbk11bHRpc2lnU2V0OiByZXZlcnQGARNfd2hlbk5vdEluaXRpYWxpemVkAAMJAQlfbG9hZEluaXQACQACAQIbX3doZW5Ob3RJbml0aWFsaXplZDogcmV2ZXJ0BgEQX3doZW5Jbml0aWFsaXplZAADCQEBIQEJAQlfbG9hZEluaXQACQACAQIYX3doZW5Jbml0aWFsaXplZDogcmV2ZXJ0BgEOX3doZW5Ob3RQYXVzZWQAAwkBCl9sb2FkUGF1c2UACQACAQIWX3doZW5Ob3RQYXVzZWQ6IHJldmVydAYBC193aGVuUGF1c2VkAAMJAQEhAQkBCl9sb2FkUGF1c2UACQACAQITX3doZW5QYXVzZWQ6IHJldmVydAYBC19vbmx5UGF1c2VyAQdjYWxsZXJfAwkBAiE9AgUHY2FsbGVyXwkBC19sb2FkUGF1c2VyAAkAAgECE19vbmx5UGF1c2VyOiByZXZlcnQGARFfdmFsaWRhdGVFeGVjdXRvcgIEdmFsXwRlcnJfAwkBAiE9AgUEdmFsXwkBDV9sb2FkRXhlY3V0b3IACQACAQUEZXJyXwYBF192YWxpZGF0ZUNhbGxlckNvbnRyYWN0AwhjaGFpbklkXw9jYWxsZXJDb250cmFjdF8EZXJyXwMJAQIhPQIJARNfbG9hZENhbGxlckNvbnRyYWN0AQUIY2hhaW5JZF8FD2NhbGxlckNvbnRyYWN0XwkAAgEFBGVycl8GAQxfY2hhaW5FeGlzdHMCCGNoYWluSWRfBGVycl8DCQBnAgAACQCxAgEJAQpfbG9hZENoYWluAQUIY2hhaW5JZF8JAAIBBQRlcnJfBgEOX2NoYWluTm90RXhpc3QCCGNoYWluSWRfBGVycl8DCQBmAgkAsQIBCQEKX2xvYWRDaGFpbgEFCGNoYWluSWRfAAAJAAIBBQRlcnJfBgEUX2Fzc2V0Q3VycmVuY3lFeGlzdHMDCGNoYWluSWRfBmFzc2V0XwRlcnJfAwkAZwIAAAkAsQIBCQESX2xvYWRBc3NldEN1cnJlbmN5AgUIY2hhaW5JZF8FBmFzc2V0XwkAAgEFBGVycl8GARZfYXNzZXRDdXJyZW5jeU5vdEV4aXN0AwhjaGFpbklkXwZhc3NldF8EZXJyXwMJAGYCCQCxAgEJARJfbG9hZEFzc2V0Q3VycmVuY3kCBQhjaGFpbklkXwUGYXNzZXRfAAAJAAIBBQRlcnJfBgETX3ZhbGlkYXRlV2F2ZXNWYXVsdAIGY2FsbGVyBGVycl8DCQECIT0CCQEPX2xvYWRXYXZlc1ZhdWx0AAUGY2FsbGVyCQACAQUEZXJyXwYBEV9yZXF1ZXN0SXNDcmVhdGVkAgdzdGF0dXNfBGVycl8DCQECIT0CBQdzdGF0dXNfBRZSRVFVRVNUX1NUQVRVU19DUkVBVEVECQACAQUEZXJyXwYBEl92YWxpZGF0ZVNlcXVlbmNlcgIGY2FsbGVyBGVycl8DCQECIT0CCQEOX2xvYWRTZXF1ZW5jZXIABQZjYWxsZXIJAAIBBQRlcnJfBgEcX2NoZWNrV2l0aGRyYXdhbEhhc2hOb3RFeGlzdAIPd2l0aGRyYXdhbEhhc2hfBGVycl8DCQBmAgkAsQIBCQETX2xvYWRXaXRoZHJhd2FsSGFzaAEFD3dpdGhkcmF3YWxIYXNoXwAACQACAQUEZXJyXwYBGF92YWxpZGF0ZVNpZ25hdHVyZUZvcm1hdAMKc2lnbmF0dXJlXwRhbGdfBGVycl8DCQAAAgUEYWxnXwUOQUxHX1RZUEVfV0FWRVMDCQECIT0CCQDIAQEFCnNpZ25hdHVyZV8AQAkAAgEFBGVycl8GAwkAAAIFBGFsZ18FDEFMR19UWVBFX0VWTQMJAQIhPQIJAMgBAQUKc2lnbmF0dXJlXwBBCQACAQUEZXJyXwYJAAIBCQCsAgIFBGVycl8CCTogaW52IGFsZwEPX3ZhbGlkYXRlV2ViM0lkAwd3ZWIzSWRfBGFsZ18EZXJyXwMJAAACBQRhbGdfBQ5BTEdfVFlQRV9XQVZFUwMJAQIhPQIJAMgBAQUHd2ViM0lkXwAgCQACAQUEZXJyXwYDCQAAAgUEYWxnXwUMQUxHX1RZUEVfRVZNAwkBAiE9AgkAyAEBBQd3ZWIzSWRfABQJAAIBBQRlcnJfBgkAAgEJAKwCAgUEZXJyXwIJOiBpbnYgYWxnARxfdmFsaWRhdGVXaXRoZHJhd2FsU2lnbmF0dXJlBQ93aXRoZHJhd2FsSGFzaF8Kc2lnbmF0dXJlXwd3ZWIzSWRfBGFsZ18EZXJyXwQGcmVzdWx0AwkAAAIFBGFsZ18FDkFMR19UWVBFX1dBVkVTBANtc2cJAMsBAgUMV0FWRVNfUFJFRklYCQCbAwEJANgEAQUPd2l0aGRyYXdhbEhhc2hfCQD0AwMFA21zZwUKc2lnbmF0dXJlXwUHd2ViM0lkXwMJAAACBQRhbGdfBQxBTEdfVFlQRV9FVk0EDmhhc2hXaXRoUHJlZml4CQCMFQEJAMsBAgUURVZNX1NJR05BVFVSRV9QUkVGSVgFD3dpdGhkcmF3YWxIYXNoXwkAAAIJAMwBAgkAjBUBCQCEBwIFDmhhc2hXaXRoUHJlZml4BQpzaWduYXR1cmVfABQFB3dlYjNJZF8JAAIBCQCsAgIFBGVycl8CCTogaW52IGFsZwMJAQEhAQUGcmVzdWx0CQACAQUEZXJyXwYBHV92YWxpZGF0ZVdlYjNJZE1hdGNoZXNBZGRyZXNzBAd3ZWIzSWRfBWZyb21fBGFsZ18EZXJyXwQHYWRkcmVzcwMJAAACBQRhbGdfBQ5BTEdfVFlQRV9XQVZFUwkApQgBCQCnCAEFB3dlYjNJZF8DCQAAAgUEYWxnXwUMQUxHX1RZUEVfRVZNCQCsAgICAjB4CQDcBAEFB3dlYjNJZF8JAAIBCQCsAgIFBGVycl8CCTogaW52IGFsZwMJAQIhPQIFB2FkZHJlc3MFBWZyb21fCQACAQUEZXJyXwYQAWkBBGluaXQGCWV4ZWN1dG9yXwdwYXVzZXJfD2FjY291bnRTdG9yYWdlXwt3YXZlc1ZhdWx0XwpzZXF1ZW5jZXJfDXZhdWx0QWRhcHRlcl8EA2VycgMDAwMDAwMDCQERX29ubHlUaGlzQ29udHJhY3QBCAUBaQZjYWxsZXIJARNfd2hlbk5vdEluaXRpYWxpemVkAAcJARBfd2hlbk11bHRpc2lnU2V0AAcJARBfdmFsaWRhdGVBZGRyZXNzAgUJZXhlY3V0b3JfAhZpbml0OiBpbnZhbGlkIGV4ZWN1dG9yBwkBEF92YWxpZGF0ZUFkZHJlc3MCBQdwYXVzZXJfAhRpbml0OiBpbnZhbGlkIHBhdXNlcgcJARBfdmFsaWRhdGVBZGRyZXNzAgUPYWNjb3VudFN0b3JhZ2VfAhxpbml0OiBpbnZhbGlkIGFjY291bnRTdG9yYWdlBwkBEF92YWxpZGF0ZUFkZHJlc3MCBQt3YXZlc1ZhdWx0XwIYaW5pdDogaW52YWxpZCB3YXZlc1ZhdWx0BwkBEF92YWxpZGF0ZUFkZHJlc3MCBQpzZXF1ZW5jZXJfAhdpbml0OiBpbnZhbGlkIHNlcXVlbmNlcgcJARBfdmFsaWRhdGVBZGRyZXNzAgUNdmF1bHRBZGFwdGVyXwIaaW5pdDogaW52YWxpZCB2YXVsdEFkYXB0ZXIHAwkAAAIFA2VycgUDZXJyCQCUCgIJAM4IAgkAzggCCQDOCAIJAM4IAgkAzggCCQDOCAIJAQlfc2F2ZUluaXQBBgkBDV9zYXZlRXhlY3V0b3IBCQERQGV4dHJOYXRpdmUoMTA2MikBBQlleGVjdXRvcl8JAQtfc2F2ZVBhdXNlcgEJARFAZXh0ck5hdGl2ZSgxMDYyKQEFB3BhdXNlcl8JARNfc2F2ZUFjY291bnRTdG9yYWdlAQkBEUBleHRyTmF0aXZlKDEwNjIpAQUPYWNjb3VudFN0b3JhZ2VfCQEPX3NhdmVXYXZlc1ZhdWx0AQkBEUBleHRyTmF0aXZlKDEwNjIpAQULd2F2ZXNWYXVsdF8JAQ5fc2F2ZVNlcXVlbmNlcgEJARFAZXh0ck5hdGl2ZSgxMDYyKQEFCnNlcXVlbmNlcl8JARFfc2F2ZVZhdWx0QWRhcHRlcgEJARFAZXh0ck5hdGl2ZSgxMDYyKQEFDXZhdWx0QWRhcHRlcl8FBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEHZGVwb3NpdAYPY2FsbGVyQ29udHJhY3RfBWZyb21fA3RvXwhjaGFpbklkXwZhc3NldF8HYW1vdW50XwQHY2hhaW5JZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQC2CQEFCGNoYWluSWRfAhhkZXBvc2l0OiBjaGFpbklkIG5vdCBpbnQEBmFtb3VudAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCoAwEFB2Ftb3VudF8CF2RlcG9zaXQ6IGFtb3VudCBub3QgaW50BANlcnIDAwMDAwMJARBfd2hlbkluaXRpYWxpemVkAAkBDl93aGVuTm90UGF1c2VkAAcJAQxfY2hhaW5FeGlzdHMCBQdjaGFpbklkAhhkZXBvc2l0OiBpbnZhbGlkIGNoYWluSWQHCQEPX3ZhbGlkYXRlU3RyaW5nAgUFZnJvbV8CFWRlcG9zaXQ6IGludmFsaWQgZnJvbQcJAQ9fdmFsaWRhdGVTdHJpbmcCBQN0b18CE2RlcG9zaXQ6IGludmFsaWQgdG8HCQEUX2Fzc2V0Q3VycmVuY3lFeGlzdHMDBQdjaGFpbklkBQZhc3NldF8CFmRlcG9zaXQ6IGludmFsaWQgYXNzZXQHCQEPX3ZhbGlkYXRlQmlnSW50AwUGYW1vdW50BQtaRVJPX0JJR0lOVAIXZGVwb3NpdDogaW52YWxpZCBhbW91bnQHAwkAAAIFA2VycgUDZXJyBARlcnIxAwkAAAIJAQpfbG9hZENoYWluAQUHY2hhaW5JZAUFV0FWRVMJARNfdmFsaWRhdGVXYXZlc1ZhdWx0AggFAWkGY2FsbGVyAhxkZXBvc2l0OiBpbnZhbGlkIHdhdmVzIHZhdWx0AwkBEV92YWxpZGF0ZUV4ZWN1dG9yAggFAWkGY2FsbGVyAhlkZXBvc2l0OiBpbnZhbGlkIGV4ZWN1dG9yCQEXX3ZhbGlkYXRlQ2FsbGVyQ29udHJhY3QDBQdjaGFpbklkBQ9jYWxsZXJDb250cmFjdF8CIGRlcG9zaXQ6IGludmFsaWQgY2FsbGVyIGNvbnRyYWN0BwMJAAACBQRlcnIxBQRlcnIxBBBuZXdBc3NldFJlc2VydmVzCQC3AgIJARJfbG9hZEFzc2V0UmVzZXJ2ZXMCBQdjaGFpbklkBQZhc3NldF8FBmFtb3VudAQIY3VycmVuY3kJARJfbG9hZEFzc2V0Q3VycmVuY3kCBQdjaGFpbklkBQZhc3NldF8EE25ld0N1cnJlbmN5UmVzZXJ2ZXMJALcCAgkBFV9sb2FkQ3VycmVuY3lSZXNlcnZlcwEFCGN1cnJlbmN5BQZhbW91bnQECmludm9jYXRpb24JAPwHBAkBE19sb2FkQWNjb3VudFN0b3JhZ2UABQxGVU5DX0RFUE9TSVQJAMwIAgUDdG9fCQDMCAIFCGN1cnJlbmN5CQDMCAIFB2Ftb3VudF8FA25pbAUDbmlsAwkAAAIFCmludm9jYXRpb24FCmludm9jYXRpb24JAJQKAgkAzggCCQESX3NhdmVBc3NldFJlc2VydmVzAwUHY2hhaW5JZAUGYXNzZXRfBRBuZXdBc3NldFJlc2VydmVzCQEVX3NhdmVDdXJyZW5jeVJlc2VydmVzAgUIY3VycmVuY3kFE25ld0N1cnJlbmN5UmVzZXJ2ZXMFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQERcmVxdWVzdFdpdGhkcmF3YWwHD2NhbGxlckNvbnRyYWN0XwVmcm9tXwN0b18MZnJvbUNoYWluSWRfCnRvQ2hhaW5JZF8GYXNzZXRfB2Ftb3VudF8EC2Zyb21DaGFpbklkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJALYJAQUMZnJvbUNoYWluSWRfAiZyZXF1ZXN0V2l0aGRyYXdhbDogZnJvbUNoYWluSWQgbm90IGludAQJdG9DaGFpbklkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJALYJAQUKdG9DaGFpbklkXwIkcmVxdWVzdFdpdGhkcmF3YWw6IHRvQ2hhaW5JZCBub3QgaW50BAZhbW91bnQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAqAMBBQdhbW91bnRfAiFyZXF1ZXN0V2l0aGRyYXdhbDogYW1vdW50IG5vdCBpbnQEA2VycgMDAwMDAwkBEF93aGVuSW5pdGlhbGl6ZWQACQEMX2NoYWluRXhpc3RzAgULZnJvbUNoYWluSWQCJnJlcXVlc3RXaXRoZHJhd2FsOiBpbnZhbGlkIGZyb21DaGFpbklkBwkBDF9jaGFpbkV4aXN0cwIFCXRvQ2hhaW5JZAIkcmVxdWVzdFdpdGhkcmF3YWw6IGludmFsaWQgdG9DaGFpbklkBwkBD192YWxpZGF0ZVN0cmluZwIFBWZyb21fAh9yZXF1ZXN0V2l0aGRyYXdhbDogaW52YWxpZCBmcm9tBwkBD192YWxpZGF0ZVN0cmluZwIFA3RvXwIdcmVxdWVzdFdpdGhkcmF3YWw6IGludmFsaWQgdG8HCQEUX2Fzc2V0Q3VycmVuY3lFeGlzdHMDBQl0b0NoYWluSWQFBmFzc2V0XwIgcmVxdWVzdFdpdGhkcmF3YWw6IGludmFsaWQgYXNzZXQHCQEPX3ZhbGlkYXRlQmlnSW50AwUGYW1vdW50BQtaRVJPX0JJR0lOVAIhcmVxdWVzdFdpdGhkcmF3YWw6IGludmFsaWQgYW1vdW50BwMJAAACBQNlcnIFA2VycgQEZXJyMQMJAAACCQEKX2xvYWRDaGFpbgEFC2Zyb21DaGFpbklkBQVXQVZFUwkBE192YWxpZGF0ZVdhdmVzVmF1bHQCCAUBaQZjYWxsZXICJnJlcXVlc3RXaXRoZHJhd2FsOiBpbnZhbGlkIHdhdmVzIHZhdWx0AwkBEV92YWxpZGF0ZUV4ZWN1dG9yAggFAWkGY2FsbGVyAiNyZXF1ZXN0V2l0aGRyYXdhbDogaW52YWxpZCBleGVjdXRvcgkBF192YWxpZGF0ZUNhbGxlckNvbnRyYWN0AwULZnJvbUNoYWluSWQFD2NhbGxlckNvbnRyYWN0XwIqcmVxdWVzdFdpdGhkcmF3YWw6IGludmFsaWQgY2FsbGVyIGNvbnRyYWN0BwMJAAACBQRlcnIxBQRlcnIxBAhjdXJyZW5jeQkBEl9sb2FkQXNzZXRDdXJyZW5jeQIFCXRvQ2hhaW5JZAUGYXNzZXRfBBBhdmFpbGFibGVCYWxhbmNlBAckbWF0Y2gwCQD8BwQJARNfbG9hZEFjY291bnRTdG9yYWdlAAUVRlVOQ19HRVRfVVNFUl9CQUxBTkNFCQDMCAIFBWZyb21fCQDMCAIFC1NQT1RfV0FMTEVUCQDMCAIFCGN1cnJlbmN5BQNuaWwFA25pbAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAWEFByRtYXRjaDAJAKcDAQUBYQkAAgECPHJlcXVlc3RXaXRoZHJhd2FsOiBjYW4ndCB0YWtlIGF2YWlsYWJsZSBiYWxhbmNlIGZyb20gc3RvcmFnZQMJAAACBRBhdmFpbGFibGVCYWxhbmNlBRBhdmFpbGFibGVCYWxhbmNlBA5sb2NrZWRSZXNlcnZlcwkBGF9sb2FkQXNzZXRSZXNlcnZlc0xvY2tlZAIFCXRvQ2hhaW5JZAUGYXNzZXRfBBJ1c2VyTG9ja2VkQ3VycmVuY3kJARdfbG9hZFVzZXJMb2NrZWRDdXJyZW5jeQIFCGN1cnJlbmN5BQVmcm9tXwQNJHQwMTkzOTkxOTg1NAMDCQDAAgIJALgCAgUQYXZhaWxhYmxlQmFsYW5jZQUSdXNlckxvY2tlZEN1cnJlbmN5BQZhbW91bnQJAMACAgkAuAICCQESX2xvYWRBc3NldFJlc2VydmVzAgUJdG9DaGFpbklkBQZhc3NldF8FDmxvY2tlZFJlc2VydmVzBQZhbW91bnQHCQCUCgIFFlJFUVVFU1RfU1RBVFVTX0NSRUFURUQJAM4IAgkBGF9zYXZlQXNzZXRSZXNlcnZlc0xvY2tlZAMFCXRvQ2hhaW5JZAUGYXNzZXRfCQC3AgIFDmxvY2tlZFJlc2VydmVzBQZhbW91bnQJARdfc2F2ZVVzZXJMb2NrZWRDdXJyZW5jeQMFCGN1cnJlbmN5BQVmcm9tXwkAtwICBQZhbW91bnQFEnVzZXJMb2NrZWRDdXJyZW5jeQkAlAoCBRdSRVFVRVNUX1NUQVRVU19SRUpFQ1RFRAUDbmlsBA1yZXF1ZXN0U3RhdHVzCAUNJHQwMTkzOTkxOTg1NAJfMQQPcmVzZXJ2ZXNBY3Rpb25zCAUNJHQwMTkzOTkxOTg1NAJfMgQVcmVxdWVzdFdpdGhkcmF3YWxTaXplCQEaX2xvYWRSZXF1ZXN0V2l0aGRyYXdhbFNpemUABBFyZXF1ZXN0V2l0aGRyYXdhbAkAmgoIBQVmcm9tXwUDdG9fBQl0b0NoYWluSWQFBmFzc2V0XwUGYW1vdW50BQZoZWlnaHQJANgEAQgFAWkNdHJhbnNhY3Rpb25JZAUNcmVxdWVzdFN0YXR1cwkAlAoCCQDOCAIJAM4IAgkBFl9zYXZlUmVxdWVzdFdpdGhkcmF3YWwCBRVyZXF1ZXN0V2l0aGRyYXdhbFNpemUFEXJlcXVlc3RXaXRoZHJhd2FsCQEaX3NhdmVSZXF1ZXN0V2l0aGRyYXdhbFNpemUBCQBkAgUVcmVxdWVzdFdpdGhkcmF3YWxTaXplAAEFD3Jlc2VydmVzQWN0aW9ucwUVcmVxdWVzdFdpdGhkcmF3YWxTaXplCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBEWV4ZWN1dGVXaXRoZHJhd2FsAw9jYWxsZXJDb250cmFjdF8IY2hhaW5JZF8UcmVxdWVzdFdpdGhkcmF3YWxJZF8EB2NoYWluSWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAtgkBBQhjaGFpbklkXwIiZXhlY3V0ZVdpdGhkcmF3YWw6IGNoYWluSWQgbm90IGludAQTcmVxdWVzdFdpdGhkcmF3YWxJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQC2CQEFFHJlcXVlc3RXaXRoZHJhd2FsSWRfAi5leGVjdXRlV2l0aGRyYXdhbDogcmVxdWVzdFdpdGhkcmF3YWxJZCBub3QgaW50BBVyZXF1ZXN0V2l0aGRyYXdhbFNpemUJARpfbG9hZFJlcXVlc3RXaXRoZHJhd2FsU2l6ZQAEA2VycgMDCQEQX3doZW5Jbml0aWFsaXplZAAJAQxfY2hhaW5FeGlzdHMCBQdjaGFpbklkAiJleGVjdXRlV2l0aGRyYXdhbDogaW52YWxpZCBjaGFpbklkBwkBDF92YWxpZGF0ZUludAQFE3JlcXVlc3RXaXRoZHJhd2FsSWQAAAkAZQIFFXJlcXVlc3RXaXRoZHJhd2FsU2l6ZQABAi5leGVjdXRlV2l0aGRyYXdhbDogaW52YWxpZCByZXF1ZXN0V2l0aGRyYXdhbElkBwMJAAACBQNlcnIFA2VycgQEZXJyMQMJAAACCQEKX2xvYWRDaGFpbgEFB2NoYWluSWQFBVdBVkVTCQETX3ZhbGlkYXRlV2F2ZXNWYXVsdAIIBQFpBmNhbGxlcgImZXhlY3V0ZVdpdGhkcmF3YWw6IGludmFsaWQgd2F2ZXMgdmF1bHQDCQERX3ZhbGlkYXRlRXhlY3V0b3ICCAUBaQZjYWxsZXICI2V4ZWN1dGVXaXRoZHJhd2FsOiBpbnZhbGlkIGV4ZWN1dG9yCQEXX3ZhbGlkYXRlQ2FsbGVyQ29udHJhY3QDBQdjaGFpbklkBQ9jYWxsZXJDb250cmFjdF8CKmV4ZWN1dGVXaXRoZHJhd2FsOiBpbnZhbGlkIGNhbGxlciBjb250cmFjdAcDCQAAAgUEZXJyMQUEZXJyMQQHcmVxdWVzdAkBFl9sb2FkUmVxdWVzdFdpdGhkcmF3YWwBBRNyZXF1ZXN0V2l0aGRyYXdhbElkBAtyZXF1ZXN0RnJvbQgFB3JlcXVlc3QCXzEECXJlcXVlc3RUbwgFB3JlcXVlc3QCXzIEEHJlcXVlc3RUb0NoYWluSWQIBQdyZXF1ZXN0Al8zBAxyZXF1ZXN0QXNzZXQIBQdyZXF1ZXN0Al80BA1yZXF1ZXN0QW1vdW50CAUHcmVxdWVzdAJfNQQNcmVxdWVzdEhlaWdodAgFB3JlcXVlc3QCXzYEDXJlcXVlc3RTdGF0dXMIBQdyZXF1ZXN0Al84BBBuZXdBc3NldFJlc2VydmVzCQC4AgIJARJfbG9hZEFzc2V0UmVzZXJ2ZXMCBRByZXF1ZXN0VG9DaGFpbklkBQxyZXF1ZXN0QXNzZXQFDXJlcXVlc3RBbW91bnQEFm5ld0Fzc2V0UmVzZXJ2ZXNMb2NrZWQJALgCAgkBGF9sb2FkQXNzZXRSZXNlcnZlc0xvY2tlZAIFEHJlcXVlc3RUb0NoYWluSWQFDHJlcXVlc3RBc3NldAUNcmVxdWVzdEFtb3VudAQIY3VycmVuY3kJARJfbG9hZEFzc2V0Q3VycmVuY3kCBRByZXF1ZXN0VG9DaGFpbklkBQxyZXF1ZXN0QXNzZXQEE25ld0N1cnJlbmN5UmVzZXJ2ZXMJALgCAgkBFV9sb2FkQ3VycmVuY3lSZXNlcnZlcwEFCGN1cnJlbmN5BQ1yZXF1ZXN0QW1vdW50BBVuZXdVc2VyTG9ja2VkQ3VycmVuY3kJALgCAgkBF19sb2FkVXNlckxvY2tlZEN1cnJlbmN5AgUIY3VycmVuY3kFC3JlcXVlc3RGcm9tBQ1yZXF1ZXN0QW1vdW50BARlcnIyAwMDAwMJAQ9fdmFsaWRhdGVCaWdJbnQDBRBuZXdBc3NldFJlc2VydmVzBQtaRVJPX0JJR0lOVAIsZXhlY3V0ZVdpdGhkcmF3YWw6IG5lZ2F0aXZlIG5ld0Fzc2V0UmVzZXJ2ZXMJAQ9fdmFsaWRhdGVCaWdJbnQDBRZuZXdBc3NldFJlc2VydmVzTG9ja2VkBQtaRVJPX0JJR0lOVAIyZXhlY3V0ZVdpdGhkcmF3YWw6IG5lZ2F0aXZlIG5ld0Fzc2V0UmVzZXJ2ZXNMb2NrZWQHCQEPX3ZhbGlkYXRlQmlnSW50AwUTbmV3Q3VycmVuY3lSZXNlcnZlcwULWkVST19CSUdJTlQCL2V4ZWN1dGVXaXRoZHJhd2FsOiBuZWdhdGl2ZSBuZXdDdXJyZW5jeVJlc2VydmVzBwkBD192YWxpZGF0ZUJpZ0ludAMFFW5ld1VzZXJMb2NrZWRDdXJyZW5jeQULWkVST19CSUdJTlQCMWV4ZWN1dGVXaXRoZHJhd2FsOiBuZWdhdGl2ZSBuZXdVc2VyTG9ja2VkQ3VycmVuY3kHCQEMX3ZhbGlkYXRlSW50BAkAZQIFBmhlaWdodAUNcmVxdWVzdEhlaWdodAkBIF9sb2FkUmVxdWVzdFdpdGhkcmF3YWxCbG9ja0RlbGF5AAUHTUFYX0lOVAInZXhlY3V0ZVdpdGhkcmF3YWw6IHRvbyBlYXJseSB0byBleGVjdXRlBwkBEV9yZXF1ZXN0SXNDcmVhdGVkAgUNcmVxdWVzdFN0YXR1cwImZXhlY3V0ZVdpdGhkcmF3YWw6IHJlcXVlc3QgaXMgcmVzb2x2ZWQHAwkAAAIFBGVycjIFBGVycjIEEXN0b3JhZ2VJbnZvY2F0aW9uCQD8BwQJARNfbG9hZEFjY291bnRTdG9yYWdlAAUNRlVOQ19XSVRIRFJBVwkAzAgCBQtyZXF1ZXN0RnJvbQkAzAgCBQhjdXJyZW5jeQkAzAgCCQCmAwEFDXJlcXVlc3RBbW91bnQFA25pbAUDbmlsAwkAAAIFEXN0b3JhZ2VJbnZvY2F0aW9uBRFzdG9yYWdlSW52b2NhdGlvbgQSd2l0aGRyYXdJbnZvY2F0aW9uAwkAAAIJAQpfbG9hZENoYWluAQUQcmVxdWVzdFRvQ2hhaW5JZAUFV0FWRVMJAPwHBAkBD19sb2FkV2F2ZXNWYXVsdAAFDUZVTkNfV0lUSERSQVcJAMwIAgUJcmVxdWVzdFRvCQDMCAIFDHJlcXVlc3RBc3NldAkAzAgCCQCmAwEFDXJlcXVlc3RBbW91bnQFA25pbAUDbmlsCQD8BwQJARFfbG9hZFZhdWx0QWRhcHRlcgAFDUZVTkNfV0lUSERSQVcJAMwIAgUQcmVxdWVzdFRvQ2hhaW5JZAkAzAgCBQxyZXF1ZXN0QXNzZXQJAMwIAgkApgMBBQ1yZXF1ZXN0QW1vdW50CQDMCAIFCXJlcXVlc3RUbwUDbmlsBQNuaWwDCQAAAgUSd2l0aGRyYXdJbnZvY2F0aW9uBRJ3aXRoZHJhd0ludm9jYXRpb24EDnJlcXVlc3RVcGRhdGVkCQCaCggIBQdyZXF1ZXN0Al8xCAUHcmVxdWVzdAJfMggFB3JlcXVlc3QCXzMIBQdyZXF1ZXN0Al80CAUHcmVxdWVzdAJfNQgFB3JlcXVlc3QCXzYIBQdyZXF1ZXN0Al83BRNSRVFVRVNUX1NUQVRVU19ET05FCQCUCgIJAM4IAgkAzggCCQDOCAIJAM4IAgkBEl9zYXZlQXNzZXRSZXNlcnZlcwMFEHJlcXVlc3RUb0NoYWluSWQFDHJlcXVlc3RBc3NldAUQbmV3QXNzZXRSZXNlcnZlcwkBGF9zYXZlQXNzZXRSZXNlcnZlc0xvY2tlZAMFEHJlcXVlc3RUb0NoYWluSWQFDHJlcXVlc3RBc3NldAUWbmV3QXNzZXRSZXNlcnZlc0xvY2tlZAkBFV9zYXZlQ3VycmVuY3lSZXNlcnZlcwIFCGN1cnJlbmN5BRNuZXdDdXJyZW5jeVJlc2VydmVzCQEXX3NhdmVVc2VyTG9ja2VkQ3VycmVuY3kDBQhjdXJyZW5jeQULcmVxdWVzdEZyb20FFW5ld1VzZXJMb2NrZWRDdXJyZW5jeQkBFl9zYXZlUmVxdWVzdFdpdGhkcmF3YWwCBRNyZXF1ZXN0V2l0aGRyYXdhbElkBQ5yZXF1ZXN0VXBkYXRlZAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARByZWplY3RXaXRoZHJhd2FsARRyZXF1ZXN0V2l0aGRyYXdhbElkXwQTcmVxdWVzdFdpdGhkcmF3YWxJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQC2CQEFFHJlcXVlc3RXaXRoZHJhd2FsSWRfAi1yZWplY3RXaXRoZHJhd2FsOiByZXF1ZXN0V2l0aGRyYXdhbElkIG5vdCBpbnQEFXJlcXVlc3RXaXRoZHJhd2FsU2l6ZQkBGl9sb2FkUmVxdWVzdFdpdGhkcmF3YWxTaXplAAQDZXJyAwMJARBfd2hlbkluaXRpYWxpemVkAAkBEl92YWxpZGF0ZVNlcXVlbmNlcgIIBQFpBmNhbGxlcgIjcmVqZWN0V2l0aGRyYXdhbDogaW52YWxpZCBzZXF1ZW5jZXIHCQEMX3ZhbGlkYXRlSW50BAUTcmVxdWVzdFdpdGhkcmF3YWxJZAAACQBlAgUVcmVxdWVzdFdpdGhkcmF3YWxTaXplAAECLXJlamVjdFdpdGhkcmF3YWw6IGludmFsaWQgcmVxdWVzdFdpdGhkcmF3YWxJZAcDCQAAAgUDZXJyBQNlcnIEB3JlcXVlc3QJARZfbG9hZFJlcXVlc3RXaXRoZHJhd2FsAQUTcmVxdWVzdFdpdGhkcmF3YWxJZAQLcmVxdWVzdEZyb20IBQdyZXF1ZXN0Al8xBAlyZXF1ZXN0VG8IBQdyZXF1ZXN0Al8yBBByZXF1ZXN0VG9DaGFpbklkCAUHcmVxdWVzdAJfMwQMcmVxdWVzdEFzc2V0CAUHcmVxdWVzdAJfNAQNcmVxdWVzdEFtb3VudAgFB3JlcXVlc3QCXzUEDXJlcXVlc3RIZWlnaHQIBQdyZXF1ZXN0Al82BA1yZXF1ZXN0U3RhdHVzCAUHcmVxdWVzdAJfOAQIY3VycmVuY3kJARJfbG9hZEFzc2V0Q3VycmVuY3kCBRByZXF1ZXN0VG9DaGFpbklkBQxyZXF1ZXN0QXNzZXQEFm5ld0Fzc2V0UmVzZXJ2ZXNMb2NrZWQJALgCAgkBGF9sb2FkQXNzZXRSZXNlcnZlc0xvY2tlZAIFEHJlcXVlc3RUb0NoYWluSWQFDHJlcXVlc3RBc3NldAUNcmVxdWVzdEFtb3VudAQVbmV3VXNlckxvY2tlZEN1cnJlbmN5CQC4AgIJARdfbG9hZFVzZXJMb2NrZWRDdXJyZW5jeQIFCGN1cnJlbmN5BQtyZXF1ZXN0RnJvbQUNcmVxdWVzdEFtb3VudAQEZXJyMQMDCQEPX3ZhbGlkYXRlQmlnSW50AwUWbmV3QXNzZXRSZXNlcnZlc0xvY2tlZAULWkVST19CSUdJTlQCMXJlamVjdFdpdGhkcmF3YWw6IG5lZ2F0aXZlIG5ld0Fzc2V0UmVzZXJ2ZXNMb2NrZWQJAQ9fdmFsaWRhdGVCaWdJbnQDBRVuZXdVc2VyTG9ja2VkQ3VycmVuY3kFC1pFUk9fQklHSU5UAjByZWplY3RXaXRoZHJhd2FsOiBuZWdhdGl2ZSBuZXdVc2VyTG9ja2VkQ3VycmVuY3kHCQERX3JlcXVlc3RJc0NyZWF0ZWQCBQ1yZXF1ZXN0U3RhdHVzAiVyZWplY3RXaXRoZHJhd2FsOiByZXF1ZXN0IGlzIHJlc29sdmVkBwMJAAACBQRlcnIxBQRlcnIxBBBhdmFpbGFibGVCYWxhbmNlBAckbWF0Y2gwCQD8BwQJARNfbG9hZEFjY291bnRTdG9yYWdlAAUVRlVOQ19HRVRfVVNFUl9CQUxBTkNFCQDMCAIFC3JlcXVlc3RGcm9tCQDMCAIFC1NQT1RfV0FMTEVUCQDMCAIFCGN1cnJlbmN5BQNuaWwFA25pbAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAWEFByRtYXRjaDAJAKcDAQUBYQkAAgECO3JlamVjdFdpdGhkcmF3YWw6IGNhbid0IHRha2UgYXZhaWxhYmxlIGJhbGFuY2UgZnJvbSBzdG9yYWdlAwkAAAIFEGF2YWlsYWJsZUJhbGFuY2UFEGF2YWlsYWJsZUJhbGFuY2UDCQC/AgIFDXJlcXVlc3RBbW91bnQFEGF2YWlsYWJsZUJhbGFuY2UEDnJlcXVlc3RVcGRhdGVkCQCaCggIBQdyZXF1ZXN0Al8xCAUHcmVxdWVzdAJfMggFB3JlcXVlc3QCXzMIBQdyZXF1ZXN0Al80CAUHcmVxdWVzdAJfNQgFB3JlcXVlc3QCXzYIBQdyZXF1ZXN0Al83BRdSRVFVRVNUX1NUQVRVU19SRUpFQ1RFRAkAlAoCCQDOCAIJAM4IAgkBGF9zYXZlQXNzZXRSZXNlcnZlc0xvY2tlZAMFEHJlcXVlc3RUb0NoYWluSWQFDHJlcXVlc3RBc3NldAUWbmV3QXNzZXRSZXNlcnZlc0xvY2tlZAkBF19zYXZlVXNlckxvY2tlZEN1cnJlbmN5AwUIY3VycmVuY3kFC3JlcXVlc3RGcm9tBRVuZXdVc2VyTG9ja2VkQ3VycmVuY3kJARZfc2F2ZVJlcXVlc3RXaXRoZHJhd2FsAgUTcmVxdWVzdFdpdGhkcmF3YWxJZAUOcmVxdWVzdFVwZGF0ZWQGCQCUCgIFA25pbAcJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEId2l0aGRyYXcKBWZyb21fA3RvXwp0b0NoYWluSWRfBmFzc2V0XwdhbW91bnRfC3JlbGF5ZXJGZWVfCnRpbWVzdGFtcF8Hd2ViM0lkXwRhbGdfCnNpZ25hdHVyZV8ECXRvQ2hhaW5JZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQC2CQEFCnRvQ2hhaW5JZF8CG3dpdGhkcmF3OiB0b0NoYWluSWQgbm90IGludAQGYW1vdW50CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKgDAQUHYW1vdW50XwIYd2l0aGRyYXc6IGFtb3VudCBub3QgaW50BApyZWxheWVyRmVlCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKgDAQULcmVsYXllckZlZV8CHHdpdGhkcmF3OiByZWxheWVyRmVlIG5vdCBpbnQECXRpbWVzdGFtcAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQC2CQEFCnRpbWVzdGFtcF8CG3dpdGhkcmF3OiB0aW1lc3RhbXAgbm90IGludAQDYWxnCQETdmFsdWVPckVycm9yTWVzc2FnZQIJALYJAQUEYWxnXwIVd2l0aGRyYXc6IGFsZyBub3QgaW50BAZ3ZWIzSWQJANkEAQUHd2ViM0lkXwQJc2lnbmF0dXJlCQDZBAEFCnNpZ25hdHVyZV8EA2VycgMDAwMDAwMDAwMDCQEQX3doZW5Jbml0aWFsaXplZAAJARJfdmFsaWRhdGVTZXF1ZW5jZXICCAUBaQZjYWxsZXICG3dpdGhkcmF3OiBpbnZhbGlkIHNlcXVlbmNlcgcJAQ9fdmFsaWRhdGVTdHJpbmcCBQVmcm9tXwIWd2l0aGRyYXc6IGludmFsaWQgZnJvbQcJAQ9fdmFsaWRhdGVTdHJpbmcCBQN0b18CFHdpdGhkcmF3OiBpbnZhbGlkIHRvBwkBDF9jaGFpbkV4aXN0cwIFCXRvQ2hhaW5JZAIbd2l0aGRyYXc6IGludmFsaWQgdG9DaGFpbklkBwkBFF9hc3NldEN1cnJlbmN5RXhpc3RzAwUJdG9DaGFpbklkBQZhc3NldF8CF3dpdGhkcmF3OiBpbnZhbGlkIGFzc2V0BwkBD192YWxpZGF0ZUJpZ0ludAMFBmFtb3VudAULWkVST19CSUdJTlQCGHdpdGhkcmF3OiBpbnZhbGlkIGFtb3VudAcJARFfdmFsaWRhdGVCaWdJbnRfMgQFCnJlbGF5ZXJGZWUFC1pFUk9fQklHSU5UBQZhbW91bnQCHHdpdGhkcmF3OiBpbnZhbGlkIHJlbGF5ZXJGZWUHCQEMX3ZhbGlkYXRlSW50BAkAZAIFCXRpbWVzdGFtcAUHT05FX0RBWQgFCWxhc3RCbG9jawl0aW1lc3RhbXAFB01BWF9JTlQCG3dpdGhkcmF3OiBpbnZhbGlkIHRpbWVzdGFtcAcJAQ9fdmFsaWRhdGVXZWIzSWQDBQZ3ZWIzSWQFA2FsZwIUd2l0aGRyYXc6IGludiB3ZWIzSWQHCQEYX3ZhbGlkYXRlU2lnbmF0dXJlRm9ybWF0AwUJc2lnbmF0dXJlBQNhbGcCGHdpdGhkcmF3OiBpbnYgc2lnIGZvcm1hdAcJAR1fdmFsaWRhdGVXZWIzSWRNYXRjaGVzQWRkcmVzcwQFBndlYjNJZAUFZnJvbV8FA2FsZwIZd2l0aGRyYXc6IHdlYjNJZCBtaXNtYXRjaAcDCQAAAgUDZXJyBQNlcnIED3dpdGhkcmF3YWxCeXRlcwkAywECCQDLAQIJAMsBAgkAywECCQDLAQIJAMsBAgkAywECCQDLAQIJAMsBAgkAywECCQDLAQIJAJoDAQkAsQIBBQVmcm9tXwkAmwMBBQVmcm9tXwkAmgMBCQCxAgEFA3RvXwkAmwMBBQN0b18JAJoDAQUJdG9DaGFpbklkCQCaAwEJALECAQUGYXNzZXRfCQCbAwEFBmFzc2V0XwkAnQMBBQZhbW91bnQJAJ0DAQUKcmVsYXllckZlZQkAmgMBBQl0aW1lc3RhbXAFBndlYjNJZAkAmgMBBQNhbGcEDndpdGhkcmF3YWxIYXNoCQCMFQEFD3dpdGhkcmF3YWxCeXRlcwQIY3VycmVuY3kJARJfbG9hZEFzc2V0Q3VycmVuY3kCBQl0b0NoYWluSWQFBmFzc2V0XwQQYXZhaWxhYmxlQmFsYW5jZQQHJG1hdGNoMAkA/AcECQETX2xvYWRBY2NvdW50U3RvcmFnZQAFFUZVTkNfR0VUX1VTRVJfQkFMQU5DRQkAzAgCBQVmcm9tXwkAzAgCBQtTUE9UX1dBTExFVAkAzAgCBQhjdXJyZW5jeQUDbmlsBQNuaWwDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFhBQckbWF0Y2gwCQCnAwEFAWEJAAIBAjN3aXRoZHJhdzogY2FuJ3QgdGFrZSBhdmFpbGFibGUgYmFsYW5jZSBmcm9tIHN0b3JhZ2UDCQAAAgUQYXZhaWxhYmxlQmFsYW5jZQUQYXZhaWxhYmxlQmFsYW5jZQQNYXNzZXRSZXNlcnZlcwkBEl9sb2FkQXNzZXRSZXNlcnZlcwIFCXRvQ2hhaW5JZAUGYXNzZXRfBA5sb2NrZWRSZXNlcnZlcwkBGF9sb2FkQXNzZXRSZXNlcnZlc0xvY2tlZAIFCXRvQ2hhaW5JZAUGYXNzZXRfBAxhbW91bnRUb1NlbmQJALgCAgUGYW1vdW50BQpyZWxheWVyRmVlBA9hbW91bnRUb1NlbmRTdHIJAKYDAQUMYW1vdW50VG9TZW5kBARlcnIxAwMDCQEcX3ZhbGlkYXRlV2l0aGRyYXdhbFNpZ25hdHVyZQUFDndpdGhkcmF3YWxIYXNoBQlzaWduYXR1cmUFBndlYjNJZAUDYWxnAhV3aXRoZHJhdzogaW52YWxpZCBzaWcJARxfY2hlY2tXaXRoZHJhd2FsSGFzaE5vdEV4aXN0AgUOd2l0aGRyYXdhbEhhc2gCGndpdGhkcmF3OiBhbHJlYWR5IGV4ZWN1dGVkBwkBD192YWxpZGF0ZUJpZ0ludAMFEGF2YWlsYWJsZUJhbGFuY2UFDGFtb3VudFRvU2VuZAIed2l0aGRyYXc6IGluc3VmZmljaWVudCBiYWxhbmNlBwkBD192YWxpZGF0ZUJpZ0ludAMJALgCAgUNYXNzZXRSZXNlcnZlcwUObG9ja2VkUmVzZXJ2ZXMFDGFtb3VudFRvU2VuZAIfd2l0aGRyYXc6IGluc3VmZmljaWVudCByZXNlcnZlcwcDCQAAAgUEZXJyMQUEZXJyMQQQbmV3QXNzZXRSZXNlcnZlcwkAuAICBQ1hc3NldFJlc2VydmVzBQxhbW91bnRUb1NlbmQEE25ld0N1cnJlbmN5UmVzZXJ2ZXMJALgCAgkBFV9sb2FkQ3VycmVuY3lSZXNlcnZlcwEFCGN1cnJlbmN5BQxhbW91bnRUb1NlbmQEBGVycjIDCQEPX3ZhbGlkYXRlQmlnSW50AwUQbmV3QXNzZXRSZXNlcnZlcwULWkVST19CSUdJTlQCI3dpdGhkcmF3OiBuZWdhdGl2ZSBuZXdBc3NldFJlc2VydmVzCQEPX3ZhbGlkYXRlQmlnSW50AwUTbmV3Q3VycmVuY3lSZXNlcnZlcwULWkVST19CSUdJTlQCJndpdGhkcmF3OiBuZWdhdGl2ZSBuZXdDdXJyZW5jeVJlc2VydmVzBwMJAAACBQRlcnIyBQRlcnIyBBJzdG9yYWdlSW52b2NhdGlvbjEJAPwHBAkBE19sb2FkQWNjb3VudFN0b3JhZ2UABQ1GVU5DX1dJVEhEUkFXCQDMCAIFBWZyb21fCQDMCAIFCGN1cnJlbmN5CQDMCAIFB2Ftb3VudF8FA25pbAUDbmlsAwkAAAIFEnN0b3JhZ2VJbnZvY2F0aW9uMQUSc3RvcmFnZUludm9jYXRpb24xBBJzdG9yYWdlSW52b2NhdGlvbjIJAPwHBAkBE19sb2FkQWNjb3VudFN0b3JhZ2UABQxGVU5DX0RFUE9TSVQJAMwIAgkBGF9sb2FkUmVsYXllckZlZVJlY2lwaWVudAAJAMwIAgUIY3VycmVuY3kJAMwIAgULcmVsYXllckZlZV8FA25pbAUDbmlsAwkAAAIFEnN0b3JhZ2VJbnZvY2F0aW9uMgUSc3RvcmFnZUludm9jYXRpb24yBBJ3aXRoZHJhd0ludm9jYXRpb24DCQAAAgkBCl9sb2FkQ2hhaW4BBQl0b0NoYWluSWQFBVdBVkVTCQD8BwQJAQ9fbG9hZFdhdmVzVmF1bHQABQ1GVU5DX1dJVEhEUkFXCQDMCAIFA3RvXwkAzAgCBQZhc3NldF8JAMwIAgUPYW1vdW50VG9TZW5kU3RyBQNuaWwFA25pbAkA/AcECQERX2xvYWRWYXVsdEFkYXB0ZXIABQ1GVU5DX1dJVEhEUkFXCQDMCAIFCXRvQ2hhaW5JZAkAzAgCBQZhc3NldF8JAMwIAgUPYW1vdW50VG9TZW5kU3RyCQDMCAIFA3RvXwkAzAgCBQtyZWxheWVyRmVlXwUDbmlsBQNuaWwDCQAAAgUSd2l0aGRyYXdJbnZvY2F0aW9uBRJ3aXRoZHJhd0ludm9jYXRpb24JAJQKAgkAzggCCQDOCAIJARJfc2F2ZUFzc2V0UmVzZXJ2ZXMDBQl0b0NoYWluSWQFBmFzc2V0XwUQbmV3QXNzZXRSZXNlcnZlcwkBFV9zYXZlQ3VycmVuY3lSZXNlcnZlcwIFCGN1cnJlbmN5BRNuZXdDdXJyZW5jeVJlc2VydmVzCQETX3NhdmVXaXRoZHJhd2FsSGFzaAIFDndpdGhkcmF3YWxIYXNoCQDYBAEIBQFpDXRyYW5zYWN0aW9uSWQFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEUZGVwb3NpdFN0YWtpbmdSZXdhcmQED2NhbGxlckNvbnRyYWN0XwhjaGFpbklkXwZhc3NldF8HYW1vdW50XwQHY2hhaW5JZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQC2CQEFCGNoYWluSWRfAiVkZXBvc2l0U3Rha2luZ1Jld2FyZDogY2hhaW5JZCBub3QgaW50BAZhbW91bnQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAqAMBBQdhbW91bnRfAiRkZXBvc2l0U3Rha2luZ1Jld2FyZDogYW1vdW50IG5vdCBpbnQEA2VycgMDAwMJARBfd2hlbkluaXRpYWxpemVkAAkBDl93aGVuTm90UGF1c2VkAAcJAQxfY2hhaW5FeGlzdHMCBQdjaGFpbklkAiVkZXBvc2l0U3Rha2luZ1Jld2FyZDogaW52YWxpZCBjaGFpbklkBwkBFF9hc3NldEN1cnJlbmN5RXhpc3RzAwUHY2hhaW5JZAUGYXNzZXRfAiNkZXBvc2l0U3Rha2luZ1Jld2FyZDogaW52YWxpZCBhc3NldAcJAQ9fdmFsaWRhdGVCaWdJbnQDBQZhbW91bnQFC1pFUk9fQklHSU5UAiRkZXBvc2l0U3Rha2luZ1Jld2FyZDogaW52YWxpZCBhbW91bnQHAwkAAAIFA2VycgUDZXJyBARlcnIxAwkAAAIJAQpfbG9hZENoYWluAQUHY2hhaW5JZAUFV0FWRVMJARNfdmFsaWRhdGVXYXZlc1ZhdWx0AggFAWkGY2FsbGVyAilkZXBvc2l0U3Rha2luZ1Jld2FyZDogaW52YWxpZCB3YXZlcyB2YXVsdAMJARFfdmFsaWRhdGVFeGVjdXRvcgIIBQFpBmNhbGxlcgImZGVwb3NpdFN0YWtpbmdSZXdhcmQ6IGludmFsaWQgZXhlY3V0b3IJARdfdmFsaWRhdGVDYWxsZXJDb250cmFjdAMFB2NoYWluSWQFD2NhbGxlckNvbnRyYWN0XwItZGVwb3NpdFN0YWtpbmdSZXdhcmQ6IGludmFsaWQgY2FsbGVyIGNvbnRyYWN0BwMJAAACBQRlcnIxBQRlcnIxBBBuZXdBc3NldFJlc2VydmVzCQC3AgIJARJfbG9hZEFzc2V0UmVzZXJ2ZXMCBQdjaGFpbklkBQZhc3NldF8FBmFtb3VudAQIY3VycmVuY3kJARJfbG9hZEFzc2V0Q3VycmVuY3kCBQdjaGFpbklkBQZhc3NldF8EE25ld0N1cnJlbmN5UmVzZXJ2ZXMJALcCAgkBFV9sb2FkQ3VycmVuY3lSZXNlcnZlcwEFCGN1cnJlbmN5BQZhbW91bnQECmludm9jYXRpb24JAPwHBAkBE19sb2FkQWNjb3VudFN0b3JhZ2UABRtGVU5DX0RFUE9TSVRfU1RBS0lOR19SRVdBUkQJAMwIAgkBFl9sb2FkUmV3YXJkRGlzdHJpYnV0b3IACQDMCAIFCGN1cnJlbmN5CQDMCAIFB2Ftb3VudF8FA25pbAUDbmlsAwkAAAIFCmludm9jYXRpb24FCmludm9jYXRpb24JAJQKAgkAzggCCQESX3NhdmVBc3NldFJlc2VydmVzAwUHY2hhaW5JZAUGYXNzZXRfBRBuZXdBc3NldFJlc2VydmVzCQEVX3NhdmVDdXJyZW5jeVJlc2VydmVzAgUIY3VycmVuY3kFE25ld0N1cnJlbmN5UmVzZXJ2ZXMFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEIYWRkQ2hhaW4DCGNoYWluSWRfBW5hbWVfD2NhbGxlckNvbnRyYWN0XwQDZXJyAwMDAwMJARFfb25seVRoaXNDb250cmFjdAEIBQFpBmNhbGxlcgkBEF93aGVuSW5pdGlhbGl6ZWQABwkBDF92YWxpZGF0ZUludAQFCGNoYWluSWRfAAAFB01BWF9JTlQCGWFkZENoYWluOiBpbnZhbGlkIGNoYWluSWQHCQEPX3ZhbGlkYXRlU3RyaW5nAgUFbmFtZV8CFmFkZENoYWluOiBpbnZhbGlkIG5hbWUHCQEPX3ZhbGlkYXRlU3RyaW5nAgUPY2FsbGVyQ29udHJhY3RfAiBhZGRDaGFpbjogaW52YWxpZCBjYWxsZXJDb250cmFjdAcJAQ5fY2hhaW5Ob3RFeGlzdAIFCGNoYWluSWRfAhhhZGRDaGFpbjogYWxyZWFkeSBleGlzdHMHAwkAAAIFA2VycgUDZXJyCQCUCgIJAM4IAgkBCl9zYXZlQ2hhaW4CBQhjaGFpbklkXwUFbmFtZV8JARNfc2F2ZUNhbGxlckNvbnRyYWN0AgUIY2hhaW5JZF8FD2NhbGxlckNvbnRyYWN0XwUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQhhZGRBc3NldAMIY2hhaW5JZF8GYXNzZXRfCWN1cnJlbmN5XwQDZXJyAwMDAwMJARFfb25seVRoaXNDb250cmFjdAEIBQFpBmNhbGxlcgkBEF93aGVuSW5pdGlhbGl6ZWQABwkBDF9jaGFpbkV4aXN0cwIFCGNoYWluSWRfAhlhZGRBc3NldDogaW52YWxpZCBjaGFpbklkBwkBD192YWxpZGF0ZVN0cmluZwIFBmFzc2V0XwIXYWRkQXNzZXQ6IGludmFsaWQgYXNzZXQHCQEPX3ZhbGlkYXRlU3RyaW5nAgUJY3VycmVuY3lfAhphZGRBc3NldDogaW52YWxpZCBjdXJyZW5jeQcJARZfYXNzZXRDdXJyZW5jeU5vdEV4aXN0AwUIY2hhaW5JZF8FBmFzc2V0XwIYYWRkQXNzZXQ6IGFscmVhZHkgZXhpc3RzBwMJAAACBQNlcnIFA2VycgkAlAoCCQESX3NhdmVBc3NldEN1cnJlbmN5AwUIY2hhaW5JZF8FBmFzc2V0XwUJY3VycmVuY3lfBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBHnNldFJlcXVlc3RXaXRoZHJhd2FsQmxvY2tEZWxheQEGZGVsYXlfBANlcnIDAwkBEV9vbmx5VGhpc0NvbnRyYWN0AQgFAWkGY2FsbGVyCQEQX3doZW5Jbml0aWFsaXplZAAHCQEMX3ZhbGlkYXRlSW50BAUGZGVsYXlfAAAFB01BWF9JTlQCLXNldFJlcXVlc3RXaXRoZHJhd2FsQmxvY2tEZWxheTogaW52YWxpZCBkZWxheQcDCQAAAgUDZXJyBQNlcnIJAJQKAgkBIF9zYXZlUmVxdWVzdFdpdGhkcmF3YWxCbG9ja0RlbGF5AQUGZGVsYXlfBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBF3VwZGF0ZVJld2FyZERpc3RyaWJ1dG9yARJyZXdhcmREaXN0cmlidXRvcl8EA2VycgMDCQERX29ubHlUaGlzQ29udHJhY3QBCAUBaQZjYWxsZXIJARBfd2hlbkluaXRpYWxpemVkAAcJAQ9fdmFsaWRhdGVTdHJpbmcCBRJyZXdhcmREaXN0cmlidXRvcl8CMnVwZGF0ZVJld2FyZERpc3RyaWJ1dG9yOiBpbnZhbGlkIHJld2FyZERpc3RyaWJ1dG9yBwMJAAACBQNlcnIFA2VycgkAlAoCCQEWX3NhdmVSZXdhcmREaXN0cmlidXRvcgEFEnJld2FyZERpc3RyaWJ1dG9yXwUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARl1cGRhdGVSZWxheWVyRmVlUmVjaXBpZW50ARRyZWxheWVyRmVlUmVjaXBpZW50XwQDZXJyAwMJARFfb25seVRoaXNDb250cmFjdAEIBQFpBmNhbGxlcgkBEF93aGVuSW5pdGlhbGl6ZWQABwkBD192YWxpZGF0ZVN0cmluZwIFFHJlbGF5ZXJGZWVSZWNpcGllbnRfAjZ1cGRhdGVSZWxheWVyRmVlUmVjaXBpZW50OiBpbnZhbGlkIHJlbGF5ZXJGZWVSZWNpcGllbnQHAwkAAAIFA2VycgUDZXJyCQCUCgIJARhfc2F2ZVJlbGF5ZXJGZWVSZWNpcGllbnQBBRRyZWxheWVyRmVlUmVjaXBpZW50XwUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQVwYXVzZQAEA2VycgMDCQELX29ubHlQYXVzZXIBCAUBaQZjYWxsZXIJARBfd2hlbkluaXRpYWxpemVkAAcJAQ5fd2hlbk5vdFBhdXNlZAAHAwkAAAIFA2VycgUDZXJyCQCUCgIJAQpfc2F2ZVBhdXNlAQYFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEHdW5wYXVzZQAEA2VycgMDCQELX29ubHlQYXVzZXIBCAUBaQZjYWxsZXIJARBfd2hlbkluaXRpYWxpemVkAAcJAQtfd2hlblBhdXNlZAAHAwkAAAIFA2VycgUDZXJyCQCUCgIJAQpfc2F2ZVBhdXNlAQcFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEMdXBkYXRlUGF1c2VyAQdwYXVzZXJfBANlcnIDAwkBEV9vbmx5VGhpc0NvbnRyYWN0AQgFAWkGY2FsbGVyCQEQX3doZW5Jbml0aWFsaXplZAAHCQEQX3ZhbGlkYXRlQWRkcmVzcwIFB3BhdXNlcl8CHHVwZGF0ZVBhdXNlcjogaW52YWxpZCBwYXVzZXIHAwkAAAIFA2VycgUDZXJyCQCUCgIJAQtfc2F2ZVBhdXNlcgEJARFAZXh0ck5hdGl2ZSgxMDYyKQEFB3BhdXNlcl8FBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQELc2V0TXVsdGlzaWcBCW11bHRpc2lnXwQDZXJyAwkBEV9vbmx5VGhpc0NvbnRyYWN0AQgFAWkGY2FsbGVyCQEQX3ZhbGlkYXRlQWRkcmVzcwIFCW11bHRpc2lnXwIdc2V0TXVsdGlzaWc6IGludmFsaWQgbXVsdGlzaWcHAwkAAAIFA2VycgUDZXJyCQCUCgIJAQ1fc2F2ZU11bHRpc2lnAQkBEUBleHRyTmF0aXZlKDEwNjIpAQUJbXVsdGlzaWdfBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJ0eAEGdmVyaWZ5AAQHJG1hdGNoMAkAoggBBQxLRVlfTVVMVElTSUcDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAhtdWx0aXNpZwUHJG1hdGNoMAkBC3ZhbHVlT3JFbHNlAgkAmwgCCQERQGV4dHJOYXRpdmUoMTA2MikBBQhtdWx0aXNpZwkAuQkCCQDMCAIFCktFWV9TVEFUVVMJAMwIAgkApQgBBQR0aGlzCQDMCAIJANgEAQgFAnR4AmlkBQNuaWwFCVNFUEFSQVRPUgcJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAIBQJ0eA9zZW5kZXJQdWJsaWNLZXmSCu1J", "height": 3408805, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: F4ZRZKEp5Tdpuwvtz9A7MmyUEwa7FJwExVLEHZD3TyBT Next: none Diff:
Old | New | Differences | |
---|---|---|---|
477 | 477 | func _validateWithdrawalSignature (withdrawalHash_,signature_,web3Id_,alg_,err_) = { | |
478 | 478 | let result = if ((alg_ == ALG_TYPE_WAVES)) | |
479 | 479 | then { | |
480 | - | let | |
481 | - | sigVerify( | |
480 | + | let msg = (WAVES_PREFIX + toBytes(toBase58String(withdrawalHash_))) | |
481 | + | sigVerify(msg, signature_, web3Id_) | |
482 | 482 | } | |
483 | 483 | else if ((alg_ == ALG_TYPE_EVM)) | |
484 | 484 | then { | |
609 | 609 | then { | |
610 | 610 | let lockedReserves = _loadAssetReservesLocked(toChainId, asset_) | |
611 | 611 | let userLockedCurrency = _loadUserLockedCurrency(currency, from_) | |
612 | - | let $ | |
612 | + | let $t01939919854 = if (if (((availableBalance - userLockedCurrency) >= amount)) | |
613 | 613 | then ((_loadAssetReserves(toChainId, asset_) - lockedReserves) >= amount) | |
614 | 614 | else false) | |
615 | 615 | then $Tuple2(REQUEST_STATUS_CREATED, (_saveAssetReservesLocked(toChainId, asset_, (lockedReserves + amount)) ++ _saveUserLockedCurrency(currency, from_, (amount + userLockedCurrency)))) | |
616 | 616 | else $Tuple2(REQUEST_STATUS_REJECTED, nil) | |
617 | - | let requestStatus = $ | |
618 | - | let reservesActions = $ | |
617 | + | let requestStatus = $t01939919854._1 | |
618 | + | let reservesActions = $t01939919854._2 | |
619 | 619 | let requestWithdrawalSize = _loadRequestWithdrawalSize() | |
620 | 620 | let requestWithdrawal = $Tuple8(from_, to_, toChainId, asset_, amount, height, toBase58String(i.transactionId), requestStatus) | |
621 | 621 | $Tuple2(((_saveRequestWithdrawal(requestWithdrawalSize, requestWithdrawal) ++ _saveRequestWithdrawalSize((requestWithdrawalSize + 1))) ++ reservesActions), requestWithdrawalSize) |
Old | New | Differences | |
---|---|---|---|
1 | 1 | {-# STDLIB_VERSION 7 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | 4 | let SEPARATOR = "__" | |
5 | 5 | ||
6 | 6 | let KEY_MULTISIG = "MULTISIG" | |
7 | 7 | ||
8 | 8 | let KEY_STATUS = "STATUS" | |
9 | 9 | ||
10 | 10 | let KEY_INIT = "INIT" | |
11 | 11 | ||
12 | 12 | let KEY_PAUSED = "PAUSED" | |
13 | 13 | ||
14 | 14 | let KEY_PAUSER = "PAUSER" | |
15 | 15 | ||
16 | 16 | let KEY_EXECUTOR = "EXECUTOR" | |
17 | 17 | ||
18 | 18 | let KEY_CALLER_CONTRACT = "CALLER_CONTRACT" | |
19 | 19 | ||
20 | 20 | let KEY_WAVES_VAULT = "WAVES_VAULT" | |
21 | 21 | ||
22 | 22 | let KEY_ACCOUNT_STORAGE = "ACCOUNT_STORAGE" | |
23 | 23 | ||
24 | 24 | let KEY_CHAIN = "CHAIN" | |
25 | 25 | ||
26 | 26 | let KEY_ASSET_CURRENCY = "ASSET_CURRENCY" | |
27 | 27 | ||
28 | 28 | let KEY_ASSET_RESERVES = "ASSET_RESERVES" | |
29 | 29 | ||
30 | 30 | let KEY_ASSET_RESERVES_LOCKED = "ASSET_RESERVES_LOCKED" | |
31 | 31 | ||
32 | 32 | let KEY_USER_LOCKED_CURRENCY = "USER_LOCKED_CURRENCY" | |
33 | 33 | ||
34 | 34 | let KEY_CURRENCY_RESERVES = "CURRENCY_RESERVES" | |
35 | 35 | ||
36 | 36 | let KEY_REQUEST_WITHDRAWAL_SIZE = "REQUEST_WITHDRAWAL_SIZE" | |
37 | 37 | ||
38 | 38 | let KEY_REQUEST_WITHDRAWAL = "REQUEST_WITHDRAWAL" | |
39 | 39 | ||
40 | 40 | let KEY_REQUEST_WITHDRAWAL_BLOCK_DELAY = "REQUEST_WITHDRAWAL_BLOCK_DELAY" | |
41 | 41 | ||
42 | 42 | let KEY_SEQUENCER = "SEQUENCER" | |
43 | 43 | ||
44 | 44 | let KEY_WITHDRAWAL_HASH = "WITHDRAWAL_HASH" | |
45 | 45 | ||
46 | 46 | let KEY_VAULT_ADAPTER = "VAULT_ADAPTER" | |
47 | 47 | ||
48 | 48 | let KEY_REWARD_DISTRIBUTOR = "REWARD_DISTRIBUTOR" | |
49 | 49 | ||
50 | 50 | let KEY_RELAYER_FEE_RECIPIENT = "RELAYER_FEE_RECIPIENT" | |
51 | 51 | ||
52 | 52 | let FUNC_DEPOSIT = "deposit" | |
53 | 53 | ||
54 | 54 | let FUNC_GET_USER_BALANCE = "getUserBalance" | |
55 | 55 | ||
56 | 56 | let FUNC_INTERNAL_TRANSFER = "internalTransfer" | |
57 | 57 | ||
58 | 58 | let FUNC_WITHDRAW = "withdraw" | |
59 | 59 | ||
60 | 60 | let FUNC_DEPOSIT_STAKING_REWARD = "depositStakingReward" | |
61 | 61 | ||
62 | 62 | let REQUEST_STATUS_CREATED = 0 | |
63 | 63 | ||
64 | 64 | let REQUEST_STATUS_DONE = 1 | |
65 | 65 | ||
66 | 66 | let REQUEST_STATUS_REJECTED = 2 | |
67 | 67 | ||
68 | 68 | let WAVES = "WAVES" | |
69 | 69 | ||
70 | 70 | let SPOT_WALLET = "SPOT" | |
71 | 71 | ||
72 | 72 | let MAX_INT = 9223372036854775807 | |
73 | 73 | ||
74 | 74 | let ZERO_BIGINT = toBigInt(0) | |
75 | 75 | ||
76 | 76 | let ONE_BIGINT = toBigInt(1) | |
77 | 77 | ||
78 | 78 | let ONE_DAY = 86400000 | |
79 | 79 | ||
80 | 80 | let ALG_TYPE_WAVES = 1 | |
81 | 81 | ||
82 | 82 | let ALG_TYPE_EVM = 2 | |
83 | 83 | ||
84 | 84 | let WAVES_PREFIX = base58'7YXq4t' | |
85 | 85 | ||
86 | 86 | let EVM_SIGNATURE_PREFIX = base58'G5Nu92G2p7moXW9qjjN3na7gtq4dWCeVdaSjry' | |
87 | 87 | ||
88 | 88 | func _validateAddress (address_,err_) = match addressFromString(address_) { | |
89 | 89 | case a: Address => | |
90 | 90 | true | |
91 | 91 | case _ => | |
92 | 92 | throw(err_) | |
93 | 93 | } | |
94 | 94 | ||
95 | 95 | ||
96 | 96 | func _validateInt (val_,lowerBoundary_,upperBoundary_,err_) = if (if ((lowerBoundary_ > val_)) | |
97 | 97 | then true | |
98 | 98 | else (val_ > upperBoundary_)) | |
99 | 99 | then throw(err_) | |
100 | 100 | else true | |
101 | 101 | ||
102 | 102 | ||
103 | 103 | func _validateBigInt (val_,lowerBoundary_,err_) = if ((lowerBoundary_ > val_)) | |
104 | 104 | then throw(err_) | |
105 | 105 | else true | |
106 | 106 | ||
107 | 107 | ||
108 | 108 | func _validateBigInt_2 (val_,lowerBoundary_,upperBoundary_,err_) = if (if ((lowerBoundary_ > val_)) | |
109 | 109 | then true | |
110 | 110 | else (val_ > upperBoundary_)) | |
111 | 111 | then throw(err_) | |
112 | 112 | else true | |
113 | 113 | ||
114 | 114 | ||
115 | 115 | func _validateString (val_,err_) = if (if ((0 >= size(val_))) | |
116 | 116 | then true | |
117 | 117 | else contains(val_, SEPARATOR)) | |
118 | 118 | then throw(err_) | |
119 | 119 | else true | |
120 | 120 | ||
121 | 121 | ||
122 | 122 | func _validateStringEqual (val1_,val2_,err_) = if ((val1_ != val2_)) | |
123 | 123 | then throw(err_) | |
124 | 124 | else true | |
125 | 125 | ||
126 | 126 | ||
127 | 127 | func _loadInit () = match getBoolean(KEY_INIT) { | |
128 | 128 | case a: Boolean => | |
129 | 129 | a | |
130 | 130 | case _ => | |
131 | 131 | false | |
132 | 132 | } | |
133 | 133 | ||
134 | 134 | ||
135 | 135 | func _saveInit (isInit_) = [BooleanEntry(KEY_INIT, isInit_)] | |
136 | 136 | ||
137 | 137 | ||
138 | 138 | func _loadPause () = match getBoolean(KEY_PAUSED) { | |
139 | 139 | case a: Boolean => | |
140 | 140 | a | |
141 | 141 | case _ => | |
142 | 142 | false | |
143 | 143 | } | |
144 | 144 | ||
145 | 145 | ||
146 | 146 | func _savePause (isPaused_) = [BooleanEntry(KEY_PAUSED, isPaused_)] | |
147 | 147 | ||
148 | 148 | ||
149 | 149 | func _loadPauser () = match getString(KEY_PAUSER) { | |
150 | 150 | case a: String => | |
151 | 151 | addressFromStringValue(a) | |
152 | 152 | case _ => | |
153 | 153 | Address(base58'') | |
154 | 154 | } | |
155 | 155 | ||
156 | 156 | ||
157 | 157 | func _savePauser (pauser_) = [StringEntry(KEY_PAUSER, toString(pauser_))] | |
158 | 158 | ||
159 | 159 | ||
160 | 160 | func _loadMultisig () = match getString(KEY_MULTISIG) { | |
161 | 161 | case a: String => | |
162 | 162 | addressFromStringValue(a) | |
163 | 163 | case _ => | |
164 | 164 | Address(base58'') | |
165 | 165 | } | |
166 | 166 | ||
167 | 167 | ||
168 | 168 | func _saveMultisig (multisig_) = [StringEntry(KEY_MULTISIG, toString(multisig_))] | |
169 | 169 | ||
170 | 170 | ||
171 | 171 | func _loadCallerContract (chainId_) = match getString(makeString([KEY_CALLER_CONTRACT, toString(chainId_)], SEPARATOR)) { | |
172 | 172 | case a: String => | |
173 | 173 | a | |
174 | 174 | case _ => | |
175 | 175 | "" | |
176 | 176 | } | |
177 | 177 | ||
178 | 178 | ||
179 | 179 | func _saveCallerContract (chainId_,callerContract_) = [StringEntry(makeString([KEY_CALLER_CONTRACT, toString(chainId_)], SEPARATOR), callerContract_)] | |
180 | 180 | ||
181 | 181 | ||
182 | 182 | func _loadExecutor () = match getString(KEY_EXECUTOR) { | |
183 | 183 | case a: String => | |
184 | 184 | addressFromStringValue(a) | |
185 | 185 | case _ => | |
186 | 186 | Address(base58'') | |
187 | 187 | } | |
188 | 188 | ||
189 | 189 | ||
190 | 190 | func _saveExecutor (executor_) = [StringEntry(KEY_EXECUTOR, toString(executor_))] | |
191 | 191 | ||
192 | 192 | ||
193 | 193 | func _loadAccountStorage () = match getString(KEY_ACCOUNT_STORAGE) { | |
194 | 194 | case a: String => | |
195 | 195 | addressFromStringValue(a) | |
196 | 196 | case _ => | |
197 | 197 | Address(base58'') | |
198 | 198 | } | |
199 | 199 | ||
200 | 200 | ||
201 | 201 | func _saveAccountStorage (accountStorage_) = [StringEntry(KEY_ACCOUNT_STORAGE, toString(accountStorage_))] | |
202 | 202 | ||
203 | 203 | ||
204 | 204 | func _loadWavesVault () = match getString(KEY_WAVES_VAULT) { | |
205 | 205 | case a: String => | |
206 | 206 | addressFromStringValue(a) | |
207 | 207 | case _ => | |
208 | 208 | Address(base58'') | |
209 | 209 | } | |
210 | 210 | ||
211 | 211 | ||
212 | 212 | func _saveWavesVault (wavesVault_) = [StringEntry(KEY_WAVES_VAULT, toString(wavesVault_))] | |
213 | 213 | ||
214 | 214 | ||
215 | 215 | func _loadChain (chainId_) = match getString(makeString([KEY_CHAIN, toString(chainId_)], SEPARATOR)) { | |
216 | 216 | case a: String => | |
217 | 217 | a | |
218 | 218 | case _ => | |
219 | 219 | "" | |
220 | 220 | } | |
221 | 221 | ||
222 | 222 | ||
223 | 223 | func _saveChain (chainId_,name_) = [StringEntry(makeString([KEY_CHAIN, toString(chainId_)], SEPARATOR), name_)] | |
224 | 224 | ||
225 | 225 | ||
226 | 226 | func _loadAssetCurrency (chainId_,asset_) = match getString(makeString([KEY_ASSET_CURRENCY, toString(chainId_), asset_], SEPARATOR)) { | |
227 | 227 | case a: String => | |
228 | 228 | a | |
229 | 229 | case _ => | |
230 | 230 | "" | |
231 | 231 | } | |
232 | 232 | ||
233 | 233 | ||
234 | 234 | func _saveAssetCurrency (chainId_,asset_,currency_) = [StringEntry(makeString([KEY_ASSET_CURRENCY, toString(chainId_), asset_], SEPARATOR), currency_)] | |
235 | 235 | ||
236 | 236 | ||
237 | 237 | func _loadAssetReserves (chainId_,asset_) = match getString(makeString([KEY_ASSET_RESERVES, toString(chainId_), asset_], SEPARATOR)) { | |
238 | 238 | case a: String => | |
239 | 239 | parseBigIntValue(a) | |
240 | 240 | case _ => | |
241 | 241 | ZERO_BIGINT | |
242 | 242 | } | |
243 | 243 | ||
244 | 244 | ||
245 | 245 | func _saveAssetReserves (chainId_,asset_,reserves_) = [StringEntry(makeString([KEY_ASSET_RESERVES, toString(chainId_), asset_], SEPARATOR), toString(reserves_))] | |
246 | 246 | ||
247 | 247 | ||
248 | 248 | func _loadAssetReservesLocked (chainId_,asset_) = match getString(makeString([KEY_ASSET_RESERVES_LOCKED, toString(chainId_), asset_], SEPARATOR)) { | |
249 | 249 | case a: String => | |
250 | 250 | parseBigIntValue(a) | |
251 | 251 | case _ => | |
252 | 252 | ZERO_BIGINT | |
253 | 253 | } | |
254 | 254 | ||
255 | 255 | ||
256 | 256 | func _saveAssetReservesLocked (chainId_,asset_,reserves_) = [StringEntry(makeString([KEY_ASSET_RESERVES_LOCKED, toString(chainId_), asset_], SEPARATOR), toString(reserves_))] | |
257 | 257 | ||
258 | 258 | ||
259 | 259 | func _loadUserLockedCurrency (currency_,user_) = match getString(makeString([KEY_USER_LOCKED_CURRENCY, currency_, user_], SEPARATOR)) { | |
260 | 260 | case a: String => | |
261 | 261 | parseBigIntValue(a) | |
262 | 262 | case _ => | |
263 | 263 | ZERO_BIGINT | |
264 | 264 | } | |
265 | 265 | ||
266 | 266 | ||
267 | 267 | func _saveUserLockedCurrency (currency_,user_,amount_) = [StringEntry(makeString([KEY_USER_LOCKED_CURRENCY, currency_, user_], SEPARATOR), toString(amount_))] | |
268 | 268 | ||
269 | 269 | ||
270 | 270 | func _loadCurrencyReserves (currency_) = match getString(makeString([KEY_CURRENCY_RESERVES, currency_], SEPARATOR)) { | |
271 | 271 | case a: String => | |
272 | 272 | parseBigIntValue(a) | |
273 | 273 | case _ => | |
274 | 274 | ZERO_BIGINT | |
275 | 275 | } | |
276 | 276 | ||
277 | 277 | ||
278 | 278 | func _saveCurrencyReserves (currency_,reserves_) = [StringEntry(makeString([KEY_CURRENCY_RESERVES, currency_], SEPARATOR), toString(reserves_))] | |
279 | 279 | ||
280 | 280 | ||
281 | 281 | func _loadRequestWithdrawalSize () = match getInteger(KEY_REQUEST_WITHDRAWAL_SIZE) { | |
282 | 282 | case a: Int => | |
283 | 283 | a | |
284 | 284 | case _ => | |
285 | 285 | 0 | |
286 | 286 | } | |
287 | 287 | ||
288 | 288 | ||
289 | 289 | func _saveRequestWithdrawalSize (val_) = [IntegerEntry(KEY_REQUEST_WITHDRAWAL_SIZE, val_)] | |
290 | 290 | ||
291 | 291 | ||
292 | 292 | func _loadRequestWithdrawal (index_) = match getString(makeString([KEY_REQUEST_WITHDRAWAL, toString(index_)], SEPARATOR)) { | |
293 | 293 | case a: String => | |
294 | 294 | let struct = split(a, SEPARATOR) | |
295 | 295 | $Tuple8(struct[0], struct[1], parseIntValue(struct[2]), struct[3], parseBigIntValue(struct[4]), parseIntValue(struct[5]), struct[6], parseIntValue(struct[7])) | |
296 | 296 | case _ => | |
297 | 297 | $Tuple8("", "", 0, "", ZERO_BIGINT, 0, "", REQUEST_STATUS_CREATED) | |
298 | 298 | } | |
299 | 299 | ||
300 | 300 | ||
301 | 301 | func _saveRequestWithdrawal (index_,request_) = [StringEntry(makeString([KEY_REQUEST_WITHDRAWAL, toString(index_)], SEPARATOR), makeString([request_._1, request_._2, toString(request_._3), request_._4, toString(request_._5), toString(request_._6), request_._7, toString(request_._8)], SEPARATOR))] | |
302 | 302 | ||
303 | 303 | ||
304 | 304 | func _loadRequestWithdrawalBlockDelay () = match getInteger(KEY_REQUEST_WITHDRAWAL_BLOCK_DELAY) { | |
305 | 305 | case a: Int => | |
306 | 306 | a | |
307 | 307 | case _ => | |
308 | 308 | 0 | |
309 | 309 | } | |
310 | 310 | ||
311 | 311 | ||
312 | 312 | func _saveRequestWithdrawalBlockDelay (delay_) = [IntegerEntry(KEY_REQUEST_WITHDRAWAL_BLOCK_DELAY, delay_)] | |
313 | 313 | ||
314 | 314 | ||
315 | 315 | func _loadSequencer () = match getString(KEY_SEQUENCER) { | |
316 | 316 | case a: String => | |
317 | 317 | addressFromStringValue(a) | |
318 | 318 | case _ => | |
319 | 319 | Address(base58'') | |
320 | 320 | } | |
321 | 321 | ||
322 | 322 | ||
323 | 323 | func _saveSequencer (sequencer_) = [StringEntry(KEY_SEQUENCER, toString(sequencer_))] | |
324 | 324 | ||
325 | 325 | ||
326 | 326 | func _loadWithdrawalHash (withdrawalHash_) = match getString(makeString([KEY_WITHDRAWAL_HASH, toBase58String(withdrawalHash_)], SEPARATOR)) { | |
327 | 327 | case a: String => | |
328 | 328 | a | |
329 | 329 | case _ => | |
330 | 330 | "" | |
331 | 331 | } | |
332 | 332 | ||
333 | 333 | ||
334 | 334 | func _saveWithdrawalHash (withdrawalHash_,txId_) = [StringEntry(makeString([KEY_WITHDRAWAL_HASH, toBase58String(withdrawalHash_)], SEPARATOR), txId_)] | |
335 | 335 | ||
336 | 336 | ||
337 | 337 | func _loadVaultAdapter () = match getString(KEY_VAULT_ADAPTER) { | |
338 | 338 | case a: String => | |
339 | 339 | addressFromStringValue(a) | |
340 | 340 | case _ => | |
341 | 341 | Address(base58'') | |
342 | 342 | } | |
343 | 343 | ||
344 | 344 | ||
345 | 345 | func _saveVaultAdapter (vaultAdapter_) = [StringEntry(KEY_VAULT_ADAPTER, toString(vaultAdapter_))] | |
346 | 346 | ||
347 | 347 | ||
348 | 348 | func _loadRewardDistributor () = match getString(KEY_REWARD_DISTRIBUTOR) { | |
349 | 349 | case a: String => | |
350 | 350 | a | |
351 | 351 | case _ => | |
352 | 352 | "" | |
353 | 353 | } | |
354 | 354 | ||
355 | 355 | ||
356 | 356 | func _saveRewardDistributor (distributor_) = [StringEntry(KEY_REWARD_DISTRIBUTOR, distributor_)] | |
357 | 357 | ||
358 | 358 | ||
359 | 359 | func _loadRelayerFeeRecipient () = match getString(KEY_RELAYER_FEE_RECIPIENT) { | |
360 | 360 | case a: String => | |
361 | 361 | a | |
362 | 362 | case _ => | |
363 | 363 | "" | |
364 | 364 | } | |
365 | 365 | ||
366 | 366 | ||
367 | 367 | func _saveRelayerFeeRecipient (relayerFeeRecipient_) = [StringEntry(KEY_RELAYER_FEE_RECIPIENT, relayerFeeRecipient_)] | |
368 | 368 | ||
369 | 369 | ||
370 | 370 | func _onlyThisContract (caller_) = if ((caller_ != this)) | |
371 | 371 | then throw("_onlyThisContract: revert") | |
372 | 372 | else true | |
373 | 373 | ||
374 | 374 | ||
375 | 375 | func _whenMultisigSet () = if ((_loadMultisig() == Address(base58''))) | |
376 | 376 | then throw("_whenMultisigSet: revert") | |
377 | 377 | else true | |
378 | 378 | ||
379 | 379 | ||
380 | 380 | func _whenNotInitialized () = if (_loadInit()) | |
381 | 381 | then throw("_whenNotInitialized: revert") | |
382 | 382 | else true | |
383 | 383 | ||
384 | 384 | ||
385 | 385 | func _whenInitialized () = if (!(_loadInit())) | |
386 | 386 | then throw("_whenInitialized: revert") | |
387 | 387 | else true | |
388 | 388 | ||
389 | 389 | ||
390 | 390 | func _whenNotPaused () = if (_loadPause()) | |
391 | 391 | then throw("_whenNotPaused: revert") | |
392 | 392 | else true | |
393 | 393 | ||
394 | 394 | ||
395 | 395 | func _whenPaused () = if (!(_loadPause())) | |
396 | 396 | then throw("_whenPaused: revert") | |
397 | 397 | else true | |
398 | 398 | ||
399 | 399 | ||
400 | 400 | func _onlyPauser (caller_) = if ((caller_ != _loadPauser())) | |
401 | 401 | then throw("_onlyPauser: revert") | |
402 | 402 | else true | |
403 | 403 | ||
404 | 404 | ||
405 | 405 | func _validateExecutor (val_,err_) = if ((val_ != _loadExecutor())) | |
406 | 406 | then throw(err_) | |
407 | 407 | else true | |
408 | 408 | ||
409 | 409 | ||
410 | 410 | func _validateCallerContract (chainId_,callerContract_,err_) = if ((_loadCallerContract(chainId_) != callerContract_)) | |
411 | 411 | then throw(err_) | |
412 | 412 | else true | |
413 | 413 | ||
414 | 414 | ||
415 | 415 | func _chainExists (chainId_,err_) = if ((0 >= size(_loadChain(chainId_)))) | |
416 | 416 | then throw(err_) | |
417 | 417 | else true | |
418 | 418 | ||
419 | 419 | ||
420 | 420 | func _chainNotExist (chainId_,err_) = if ((size(_loadChain(chainId_)) > 0)) | |
421 | 421 | then throw(err_) | |
422 | 422 | else true | |
423 | 423 | ||
424 | 424 | ||
425 | 425 | func _assetCurrencyExists (chainId_,asset_,err_) = if ((0 >= size(_loadAssetCurrency(chainId_, asset_)))) | |
426 | 426 | then throw(err_) | |
427 | 427 | else true | |
428 | 428 | ||
429 | 429 | ||
430 | 430 | func _assetCurrencyNotExist (chainId_,asset_,err_) = if ((size(_loadAssetCurrency(chainId_, asset_)) > 0)) | |
431 | 431 | then throw(err_) | |
432 | 432 | else true | |
433 | 433 | ||
434 | 434 | ||
435 | 435 | func _validateWavesVault (caller,err_) = if ((_loadWavesVault() != caller)) | |
436 | 436 | then throw(err_) | |
437 | 437 | else true | |
438 | 438 | ||
439 | 439 | ||
440 | 440 | func _requestIsCreated (status_,err_) = if ((status_ != REQUEST_STATUS_CREATED)) | |
441 | 441 | then throw(err_) | |
442 | 442 | else true | |
443 | 443 | ||
444 | 444 | ||
445 | 445 | func _validateSequencer (caller,err_) = if ((_loadSequencer() != caller)) | |
446 | 446 | then throw(err_) | |
447 | 447 | else true | |
448 | 448 | ||
449 | 449 | ||
450 | 450 | func _checkWithdrawalHashNotExist (withdrawalHash_,err_) = if ((size(_loadWithdrawalHash(withdrawalHash_)) > 0)) | |
451 | 451 | then throw(err_) | |
452 | 452 | else true | |
453 | 453 | ||
454 | 454 | ||
455 | 455 | func _validateSignatureFormat (signature_,alg_,err_) = if ((alg_ == ALG_TYPE_WAVES)) | |
456 | 456 | then if ((size(signature_) != 64)) | |
457 | 457 | then throw(err_) | |
458 | 458 | else true | |
459 | 459 | else if ((alg_ == ALG_TYPE_EVM)) | |
460 | 460 | then if ((size(signature_) != 65)) | |
461 | 461 | then throw(err_) | |
462 | 462 | else true | |
463 | 463 | else throw((err_ + ": inv alg")) | |
464 | 464 | ||
465 | 465 | ||
466 | 466 | func _validateWeb3Id (web3Id_,alg_,err_) = if ((alg_ == ALG_TYPE_WAVES)) | |
467 | 467 | then if ((size(web3Id_) != 32)) | |
468 | 468 | then throw(err_) | |
469 | 469 | else true | |
470 | 470 | else if ((alg_ == ALG_TYPE_EVM)) | |
471 | 471 | then if ((size(web3Id_) != 20)) | |
472 | 472 | then throw(err_) | |
473 | 473 | else true | |
474 | 474 | else throw((err_ + ": inv alg")) | |
475 | 475 | ||
476 | 476 | ||
477 | 477 | func _validateWithdrawalSignature (withdrawalHash_,signature_,web3Id_,alg_,err_) = { | |
478 | 478 | let result = if ((alg_ == ALG_TYPE_WAVES)) | |
479 | 479 | then { | |
480 | - | let | |
481 | - | sigVerify( | |
480 | + | let msg = (WAVES_PREFIX + toBytes(toBase58String(withdrawalHash_))) | |
481 | + | sigVerify(msg, signature_, web3Id_) | |
482 | 482 | } | |
483 | 483 | else if ((alg_ == ALG_TYPE_EVM)) | |
484 | 484 | then { | |
485 | 485 | let hashWithPrefix = keccak256_16Kb((EVM_SIGNATURE_PREFIX + withdrawalHash_)) | |
486 | 486 | (takeRight(keccak256_16Kb(ecrecover(hashWithPrefix, signature_)), 20) == web3Id_) | |
487 | 487 | } | |
488 | 488 | else throw((err_ + ": inv alg")) | |
489 | 489 | if (!(result)) | |
490 | 490 | then throw(err_) | |
491 | 491 | else true | |
492 | 492 | } | |
493 | 493 | ||
494 | 494 | ||
495 | 495 | func _validateWeb3IdMatchesAddress (web3Id_,from_,alg_,err_) = { | |
496 | 496 | let address = if ((alg_ == ALG_TYPE_WAVES)) | |
497 | 497 | then toString(addressFromPublicKey(web3Id_)) | |
498 | 498 | else if ((alg_ == ALG_TYPE_EVM)) | |
499 | 499 | then ("0x" + toBase16String(web3Id_)) | |
500 | 500 | else throw((err_ + ": inv alg")) | |
501 | 501 | if ((address != from_)) | |
502 | 502 | then throw(err_) | |
503 | 503 | else true | |
504 | 504 | } | |
505 | 505 | ||
506 | 506 | ||
507 | 507 | @Callable(i) | |
508 | 508 | func init (executor_,pauser_,accountStorage_,wavesVault_,sequencer_,vaultAdapter_) = { | |
509 | 509 | let err = if (if (if (if (if (if (if (if (_onlyThisContract(i.caller)) | |
510 | 510 | then _whenNotInitialized() | |
511 | 511 | else false) | |
512 | 512 | then _whenMultisigSet() | |
513 | 513 | else false) | |
514 | 514 | then _validateAddress(executor_, "init: invalid executor") | |
515 | 515 | else false) | |
516 | 516 | then _validateAddress(pauser_, "init: invalid pauser") | |
517 | 517 | else false) | |
518 | 518 | then _validateAddress(accountStorage_, "init: invalid accountStorage") | |
519 | 519 | else false) | |
520 | 520 | then _validateAddress(wavesVault_, "init: invalid wavesVault") | |
521 | 521 | else false) | |
522 | 522 | then _validateAddress(sequencer_, "init: invalid sequencer") | |
523 | 523 | else false) | |
524 | 524 | then _validateAddress(vaultAdapter_, "init: invalid vaultAdapter") | |
525 | 525 | else false | |
526 | 526 | if ((err == err)) | |
527 | 527 | then $Tuple2(((((((_saveInit(true) ++ _saveExecutor(addressFromStringValue(executor_))) ++ _savePauser(addressFromStringValue(pauser_))) ++ _saveAccountStorage(addressFromStringValue(accountStorage_))) ++ _saveWavesVault(addressFromStringValue(wavesVault_))) ++ _saveSequencer(addressFromStringValue(sequencer_))) ++ _saveVaultAdapter(addressFromStringValue(vaultAdapter_))), unit) | |
528 | 528 | else throw("Strict value is not equal to itself.") | |
529 | 529 | } | |
530 | 530 | ||
531 | 531 | ||
532 | 532 | ||
533 | 533 | @Callable(i) | |
534 | 534 | func deposit (callerContract_,from_,to_,chainId_,asset_,amount_) = { | |
535 | 535 | let chainId = valueOrErrorMessage(parseInt(chainId_), "deposit: chainId not int") | |
536 | 536 | let amount = valueOrErrorMessage(parseBigInt(amount_), "deposit: amount not int") | |
537 | 537 | let err = if (if (if (if (if (if (_whenInitialized()) | |
538 | 538 | then _whenNotPaused() | |
539 | 539 | else false) | |
540 | 540 | then _chainExists(chainId, "deposit: invalid chainId") | |
541 | 541 | else false) | |
542 | 542 | then _validateString(from_, "deposit: invalid from") | |
543 | 543 | else false) | |
544 | 544 | then _validateString(to_, "deposit: invalid to") | |
545 | 545 | else false) | |
546 | 546 | then _assetCurrencyExists(chainId, asset_, "deposit: invalid asset") | |
547 | 547 | else false) | |
548 | 548 | then _validateBigInt(amount, ZERO_BIGINT, "deposit: invalid amount") | |
549 | 549 | else false | |
550 | 550 | if ((err == err)) | |
551 | 551 | then { | |
552 | 552 | let err1 = if ((_loadChain(chainId) == WAVES)) | |
553 | 553 | then _validateWavesVault(i.caller, "deposit: invalid waves vault") | |
554 | 554 | else if (_validateExecutor(i.caller, "deposit: invalid executor")) | |
555 | 555 | then _validateCallerContract(chainId, callerContract_, "deposit: invalid caller contract") | |
556 | 556 | else false | |
557 | 557 | if ((err1 == err1)) | |
558 | 558 | then { | |
559 | 559 | let newAssetReserves = (_loadAssetReserves(chainId, asset_) + amount) | |
560 | 560 | let currency = _loadAssetCurrency(chainId, asset_) | |
561 | 561 | let newCurrencyReserves = (_loadCurrencyReserves(currency) + amount) | |
562 | 562 | let invocation = invoke(_loadAccountStorage(), FUNC_DEPOSIT, [to_, currency, amount_], nil) | |
563 | 563 | if ((invocation == invocation)) | |
564 | 564 | then $Tuple2((_saveAssetReserves(chainId, asset_, newAssetReserves) ++ _saveCurrencyReserves(currency, newCurrencyReserves)), unit) | |
565 | 565 | else throw("Strict value is not equal to itself.") | |
566 | 566 | } | |
567 | 567 | else throw("Strict value is not equal to itself.") | |
568 | 568 | } | |
569 | 569 | else throw("Strict value is not equal to itself.") | |
570 | 570 | } | |
571 | 571 | ||
572 | 572 | ||
573 | 573 | ||
574 | 574 | @Callable(i) | |
575 | 575 | func requestWithdrawal (callerContract_,from_,to_,fromChainId_,toChainId_,asset_,amount_) = { | |
576 | 576 | let fromChainId = valueOrErrorMessage(parseInt(fromChainId_), "requestWithdrawal: fromChainId not int") | |
577 | 577 | let toChainId = valueOrErrorMessage(parseInt(toChainId_), "requestWithdrawal: toChainId not int") | |
578 | 578 | let amount = valueOrErrorMessage(parseBigInt(amount_), "requestWithdrawal: amount not int") | |
579 | 579 | let err = if (if (if (if (if (if (_whenInitialized()) | |
580 | 580 | then _chainExists(fromChainId, "requestWithdrawal: invalid fromChainId") | |
581 | 581 | else false) | |
582 | 582 | then _chainExists(toChainId, "requestWithdrawal: invalid toChainId") | |
583 | 583 | else false) | |
584 | 584 | then _validateString(from_, "requestWithdrawal: invalid from") | |
585 | 585 | else false) | |
586 | 586 | then _validateString(to_, "requestWithdrawal: invalid to") | |
587 | 587 | else false) | |
588 | 588 | then _assetCurrencyExists(toChainId, asset_, "requestWithdrawal: invalid asset") | |
589 | 589 | else false) | |
590 | 590 | then _validateBigInt(amount, ZERO_BIGINT, "requestWithdrawal: invalid amount") | |
591 | 591 | else false | |
592 | 592 | if ((err == err)) | |
593 | 593 | then { | |
594 | 594 | let err1 = if ((_loadChain(fromChainId) == WAVES)) | |
595 | 595 | then _validateWavesVault(i.caller, "requestWithdrawal: invalid waves vault") | |
596 | 596 | else if (_validateExecutor(i.caller, "requestWithdrawal: invalid executor")) | |
597 | 597 | then _validateCallerContract(fromChainId, callerContract_, "requestWithdrawal: invalid caller contract") | |
598 | 598 | else false | |
599 | 599 | if ((err1 == err1)) | |
600 | 600 | then { | |
601 | 601 | let currency = _loadAssetCurrency(toChainId, asset_) | |
602 | 602 | let availableBalance = match invoke(_loadAccountStorage(), FUNC_GET_USER_BALANCE, [from_, SPOT_WALLET, currency], nil) { | |
603 | 603 | case a: String => | |
604 | 604 | parseBigIntValue(a) | |
605 | 605 | case _ => | |
606 | 606 | throw("requestWithdrawal: can't take available balance from storage") | |
607 | 607 | } | |
608 | 608 | if ((availableBalance == availableBalance)) | |
609 | 609 | then { | |
610 | 610 | let lockedReserves = _loadAssetReservesLocked(toChainId, asset_) | |
611 | 611 | let userLockedCurrency = _loadUserLockedCurrency(currency, from_) | |
612 | - | let $ | |
612 | + | let $t01939919854 = if (if (((availableBalance - userLockedCurrency) >= amount)) | |
613 | 613 | then ((_loadAssetReserves(toChainId, asset_) - lockedReserves) >= amount) | |
614 | 614 | else false) | |
615 | 615 | then $Tuple2(REQUEST_STATUS_CREATED, (_saveAssetReservesLocked(toChainId, asset_, (lockedReserves + amount)) ++ _saveUserLockedCurrency(currency, from_, (amount + userLockedCurrency)))) | |
616 | 616 | else $Tuple2(REQUEST_STATUS_REJECTED, nil) | |
617 | - | let requestStatus = $ | |
618 | - | let reservesActions = $ | |
617 | + | let requestStatus = $t01939919854._1 | |
618 | + | let reservesActions = $t01939919854._2 | |
619 | 619 | let requestWithdrawalSize = _loadRequestWithdrawalSize() | |
620 | 620 | let requestWithdrawal = $Tuple8(from_, to_, toChainId, asset_, amount, height, toBase58String(i.transactionId), requestStatus) | |
621 | 621 | $Tuple2(((_saveRequestWithdrawal(requestWithdrawalSize, requestWithdrawal) ++ _saveRequestWithdrawalSize((requestWithdrawalSize + 1))) ++ reservesActions), requestWithdrawalSize) | |
622 | 622 | } | |
623 | 623 | else throw("Strict value is not equal to itself.") | |
624 | 624 | } | |
625 | 625 | else throw("Strict value is not equal to itself.") | |
626 | 626 | } | |
627 | 627 | else throw("Strict value is not equal to itself.") | |
628 | 628 | } | |
629 | 629 | ||
630 | 630 | ||
631 | 631 | ||
632 | 632 | @Callable(i) | |
633 | 633 | func executeWithdrawal (callerContract_,chainId_,requestWithdrawalId_) = { | |
634 | 634 | let chainId = valueOrErrorMessage(parseInt(chainId_), "executeWithdrawal: chainId not int") | |
635 | 635 | let requestWithdrawalId = valueOrErrorMessage(parseInt(requestWithdrawalId_), "executeWithdrawal: requestWithdrawalId not int") | |
636 | 636 | let requestWithdrawalSize = _loadRequestWithdrawalSize() | |
637 | 637 | let err = if (if (_whenInitialized()) | |
638 | 638 | then _chainExists(chainId, "executeWithdrawal: invalid chainId") | |
639 | 639 | else false) | |
640 | 640 | then _validateInt(requestWithdrawalId, 0, (requestWithdrawalSize - 1), "executeWithdrawal: invalid requestWithdrawalId") | |
641 | 641 | else false | |
642 | 642 | if ((err == err)) | |
643 | 643 | then { | |
644 | 644 | let err1 = if ((_loadChain(chainId) == WAVES)) | |
645 | 645 | then _validateWavesVault(i.caller, "executeWithdrawal: invalid waves vault") | |
646 | 646 | else if (_validateExecutor(i.caller, "executeWithdrawal: invalid executor")) | |
647 | 647 | then _validateCallerContract(chainId, callerContract_, "executeWithdrawal: invalid caller contract") | |
648 | 648 | else false | |
649 | 649 | if ((err1 == err1)) | |
650 | 650 | then { | |
651 | 651 | let request = _loadRequestWithdrawal(requestWithdrawalId) | |
652 | 652 | let requestFrom = request._1 | |
653 | 653 | let requestTo = request._2 | |
654 | 654 | let requestToChainId = request._3 | |
655 | 655 | let requestAsset = request._4 | |
656 | 656 | let requestAmount = request._5 | |
657 | 657 | let requestHeight = request._6 | |
658 | 658 | let requestStatus = request._8 | |
659 | 659 | let newAssetReserves = (_loadAssetReserves(requestToChainId, requestAsset) - requestAmount) | |
660 | 660 | let newAssetReservesLocked = (_loadAssetReservesLocked(requestToChainId, requestAsset) - requestAmount) | |
661 | 661 | let currency = _loadAssetCurrency(requestToChainId, requestAsset) | |
662 | 662 | let newCurrencyReserves = (_loadCurrencyReserves(currency) - requestAmount) | |
663 | 663 | let newUserLockedCurrency = (_loadUserLockedCurrency(currency, requestFrom) - requestAmount) | |
664 | 664 | let err2 = if (if (if (if (if (_validateBigInt(newAssetReserves, ZERO_BIGINT, "executeWithdrawal: negative newAssetReserves")) | |
665 | 665 | then _validateBigInt(newAssetReservesLocked, ZERO_BIGINT, "executeWithdrawal: negative newAssetReservesLocked") | |
666 | 666 | else false) | |
667 | 667 | then _validateBigInt(newCurrencyReserves, ZERO_BIGINT, "executeWithdrawal: negative newCurrencyReserves") | |
668 | 668 | else false) | |
669 | 669 | then _validateBigInt(newUserLockedCurrency, ZERO_BIGINT, "executeWithdrawal: negative newUserLockedCurrency") | |
670 | 670 | else false) | |
671 | 671 | then _validateInt((height - requestHeight), _loadRequestWithdrawalBlockDelay(), MAX_INT, "executeWithdrawal: too early to execute") | |
672 | 672 | else false) | |
673 | 673 | then _requestIsCreated(requestStatus, "executeWithdrawal: request is resolved") | |
674 | 674 | else false | |
675 | 675 | if ((err2 == err2)) | |
676 | 676 | then { | |
677 | 677 | let storageInvocation = invoke(_loadAccountStorage(), FUNC_WITHDRAW, [requestFrom, currency, toString(requestAmount)], nil) | |
678 | 678 | if ((storageInvocation == storageInvocation)) | |
679 | 679 | then { | |
680 | 680 | let withdrawInvocation = if ((_loadChain(requestToChainId) == WAVES)) | |
681 | 681 | then invoke(_loadWavesVault(), FUNC_WITHDRAW, [requestTo, requestAsset, toString(requestAmount)], nil) | |
682 | 682 | else invoke(_loadVaultAdapter(), FUNC_WITHDRAW, [requestToChainId, requestAsset, toString(requestAmount), requestTo], nil) | |
683 | 683 | if ((withdrawInvocation == withdrawInvocation)) | |
684 | 684 | then { | |
685 | 685 | let requestUpdated = $Tuple8(request._1, request._2, request._3, request._4, request._5, request._6, request._7, REQUEST_STATUS_DONE) | |
686 | 686 | $Tuple2(((((_saveAssetReserves(requestToChainId, requestAsset, newAssetReserves) ++ _saveAssetReservesLocked(requestToChainId, requestAsset, newAssetReservesLocked)) ++ _saveCurrencyReserves(currency, newCurrencyReserves)) ++ _saveUserLockedCurrency(currency, requestFrom, newUserLockedCurrency)) ++ _saveRequestWithdrawal(requestWithdrawalId, requestUpdated)), unit) | |
687 | 687 | } | |
688 | 688 | else throw("Strict value is not equal to itself.") | |
689 | 689 | } | |
690 | 690 | else throw("Strict value is not equal to itself.") | |
691 | 691 | } | |
692 | 692 | else throw("Strict value is not equal to itself.") | |
693 | 693 | } | |
694 | 694 | else throw("Strict value is not equal to itself.") | |
695 | 695 | } | |
696 | 696 | else throw("Strict value is not equal to itself.") | |
697 | 697 | } | |
698 | 698 | ||
699 | 699 | ||
700 | 700 | ||
701 | 701 | @Callable(i) | |
702 | 702 | func rejectWithdrawal (requestWithdrawalId_) = { | |
703 | 703 | let requestWithdrawalId = valueOrErrorMessage(parseInt(requestWithdrawalId_), "rejectWithdrawal: requestWithdrawalId not int") | |
704 | 704 | let requestWithdrawalSize = _loadRequestWithdrawalSize() | |
705 | 705 | let err = if (if (_whenInitialized()) | |
706 | 706 | then _validateSequencer(i.caller, "rejectWithdrawal: invalid sequencer") | |
707 | 707 | else false) | |
708 | 708 | then _validateInt(requestWithdrawalId, 0, (requestWithdrawalSize - 1), "rejectWithdrawal: invalid requestWithdrawalId") | |
709 | 709 | else false | |
710 | 710 | if ((err == err)) | |
711 | 711 | then { | |
712 | 712 | let request = _loadRequestWithdrawal(requestWithdrawalId) | |
713 | 713 | let requestFrom = request._1 | |
714 | 714 | let requestTo = request._2 | |
715 | 715 | let requestToChainId = request._3 | |
716 | 716 | let requestAsset = request._4 | |
717 | 717 | let requestAmount = request._5 | |
718 | 718 | let requestHeight = request._6 | |
719 | 719 | let requestStatus = request._8 | |
720 | 720 | let currency = _loadAssetCurrency(requestToChainId, requestAsset) | |
721 | 721 | let newAssetReservesLocked = (_loadAssetReservesLocked(requestToChainId, requestAsset) - requestAmount) | |
722 | 722 | let newUserLockedCurrency = (_loadUserLockedCurrency(currency, requestFrom) - requestAmount) | |
723 | 723 | let err1 = if (if (_validateBigInt(newAssetReservesLocked, ZERO_BIGINT, "rejectWithdrawal: negative newAssetReservesLocked")) | |
724 | 724 | then _validateBigInt(newUserLockedCurrency, ZERO_BIGINT, "rejectWithdrawal: negative newUserLockedCurrency") | |
725 | 725 | else false) | |
726 | 726 | then _requestIsCreated(requestStatus, "rejectWithdrawal: request is resolved") | |
727 | 727 | else false | |
728 | 728 | if ((err1 == err1)) | |
729 | 729 | then { | |
730 | 730 | let availableBalance = match invoke(_loadAccountStorage(), FUNC_GET_USER_BALANCE, [requestFrom, SPOT_WALLET, currency], nil) { | |
731 | 731 | case a: String => | |
732 | 732 | parseBigIntValue(a) | |
733 | 733 | case _ => | |
734 | 734 | throw("rejectWithdrawal: can't take available balance from storage") | |
735 | 735 | } | |
736 | 736 | if ((availableBalance == availableBalance)) | |
737 | 737 | then if ((requestAmount > availableBalance)) | |
738 | 738 | then { | |
739 | 739 | let requestUpdated = $Tuple8(request._1, request._2, request._3, request._4, request._5, request._6, request._7, REQUEST_STATUS_REJECTED) | |
740 | 740 | $Tuple2(((_saveAssetReservesLocked(requestToChainId, requestAsset, newAssetReservesLocked) ++ _saveUserLockedCurrency(currency, requestFrom, newUserLockedCurrency)) ++ _saveRequestWithdrawal(requestWithdrawalId, requestUpdated)), true) | |
741 | 741 | } | |
742 | 742 | else $Tuple2(nil, false) | |
743 | 743 | else throw("Strict value is not equal to itself.") | |
744 | 744 | } | |
745 | 745 | else throw("Strict value is not equal to itself.") | |
746 | 746 | } | |
747 | 747 | else throw("Strict value is not equal to itself.") | |
748 | 748 | } | |
749 | 749 | ||
750 | 750 | ||
751 | 751 | ||
752 | 752 | @Callable(i) | |
753 | 753 | func withdraw (from_,to_,toChainId_,asset_,amount_,relayerFee_,timestamp_,web3Id_,alg_,signature_) = { | |
754 | 754 | let toChainId = valueOrErrorMessage(parseInt(toChainId_), "withdraw: toChainId not int") | |
755 | 755 | let amount = valueOrErrorMessage(parseBigInt(amount_), "withdraw: amount not int") | |
756 | 756 | let relayerFee = valueOrErrorMessage(parseBigInt(relayerFee_), "withdraw: relayerFee not int") | |
757 | 757 | let timestamp = valueOrErrorMessage(parseInt(timestamp_), "withdraw: timestamp not int") | |
758 | 758 | let alg = valueOrErrorMessage(parseInt(alg_), "withdraw: alg not int") | |
759 | 759 | let web3Id = fromBase58String(web3Id_) | |
760 | 760 | let signature = fromBase58String(signature_) | |
761 | 761 | let err = if (if (if (if (if (if (if (if (if (if (if (_whenInitialized()) | |
762 | 762 | then _validateSequencer(i.caller, "withdraw: invalid sequencer") | |
763 | 763 | else false) | |
764 | 764 | then _validateString(from_, "withdraw: invalid from") | |
765 | 765 | else false) | |
766 | 766 | then _validateString(to_, "withdraw: invalid to") | |
767 | 767 | else false) | |
768 | 768 | then _chainExists(toChainId, "withdraw: invalid toChainId") | |
769 | 769 | else false) | |
770 | 770 | then _assetCurrencyExists(toChainId, asset_, "withdraw: invalid asset") | |
771 | 771 | else false) | |
772 | 772 | then _validateBigInt(amount, ZERO_BIGINT, "withdraw: invalid amount") | |
773 | 773 | else false) | |
774 | 774 | then _validateBigInt_2(relayerFee, ZERO_BIGINT, amount, "withdraw: invalid relayerFee") | |
775 | 775 | else false) | |
776 | 776 | then _validateInt((timestamp + ONE_DAY), lastBlock.timestamp, MAX_INT, "withdraw: invalid timestamp") | |
777 | 777 | else false) | |
778 | 778 | then _validateWeb3Id(web3Id, alg, "withdraw: inv web3Id") | |
779 | 779 | else false) | |
780 | 780 | then _validateSignatureFormat(signature, alg, "withdraw: inv sig format") | |
781 | 781 | else false) | |
782 | 782 | then _validateWeb3IdMatchesAddress(web3Id, from_, alg, "withdraw: web3Id mismatch") | |
783 | 783 | else false | |
784 | 784 | if ((err == err)) | |
785 | 785 | then { | |
786 | 786 | let withdrawalBytes = (((((((((((toBytes(size(from_)) + toBytes(from_)) + toBytes(size(to_))) + toBytes(to_)) + toBytes(toChainId)) + toBytes(size(asset_))) + toBytes(asset_)) + toBytes(amount)) + toBytes(relayerFee)) + toBytes(timestamp)) + web3Id) + toBytes(alg)) | |
787 | 787 | let withdrawalHash = keccak256_16Kb(withdrawalBytes) | |
788 | 788 | let currency = _loadAssetCurrency(toChainId, asset_) | |
789 | 789 | let availableBalance = match invoke(_loadAccountStorage(), FUNC_GET_USER_BALANCE, [from_, SPOT_WALLET, currency], nil) { | |
790 | 790 | case a: String => | |
791 | 791 | parseBigIntValue(a) | |
792 | 792 | case _ => | |
793 | 793 | throw("withdraw: can't take available balance from storage") | |
794 | 794 | } | |
795 | 795 | if ((availableBalance == availableBalance)) | |
796 | 796 | then { | |
797 | 797 | let assetReserves = _loadAssetReserves(toChainId, asset_) | |
798 | 798 | let lockedReserves = _loadAssetReservesLocked(toChainId, asset_) | |
799 | 799 | let amountToSend = (amount - relayerFee) | |
800 | 800 | let amountToSendStr = toString(amountToSend) | |
801 | 801 | let err1 = if (if (if (_validateWithdrawalSignature(withdrawalHash, signature, web3Id, alg, "withdraw: invalid sig")) | |
802 | 802 | then _checkWithdrawalHashNotExist(withdrawalHash, "withdraw: already executed") | |
803 | 803 | else false) | |
804 | 804 | then _validateBigInt(availableBalance, amountToSend, "withdraw: insufficient balance") | |
805 | 805 | else false) | |
806 | 806 | then _validateBigInt((assetReserves - lockedReserves), amountToSend, "withdraw: insufficient reserves") | |
807 | 807 | else false | |
808 | 808 | if ((err1 == err1)) | |
809 | 809 | then { | |
810 | 810 | let newAssetReserves = (assetReserves - amountToSend) | |
811 | 811 | let newCurrencyReserves = (_loadCurrencyReserves(currency) - amountToSend) | |
812 | 812 | let err2 = if (_validateBigInt(newAssetReserves, ZERO_BIGINT, "withdraw: negative newAssetReserves")) | |
813 | 813 | then _validateBigInt(newCurrencyReserves, ZERO_BIGINT, "withdraw: negative newCurrencyReserves") | |
814 | 814 | else false | |
815 | 815 | if ((err2 == err2)) | |
816 | 816 | then { | |
817 | 817 | let storageInvocation1 = invoke(_loadAccountStorage(), FUNC_WITHDRAW, [from_, currency, amount_], nil) | |
818 | 818 | if ((storageInvocation1 == storageInvocation1)) | |
819 | 819 | then { | |
820 | 820 | let storageInvocation2 = invoke(_loadAccountStorage(), FUNC_DEPOSIT, [_loadRelayerFeeRecipient(), currency, relayerFee_], nil) | |
821 | 821 | if ((storageInvocation2 == storageInvocation2)) | |
822 | 822 | then { | |
823 | 823 | let withdrawInvocation = if ((_loadChain(toChainId) == WAVES)) | |
824 | 824 | then invoke(_loadWavesVault(), FUNC_WITHDRAW, [to_, asset_, amountToSendStr], nil) | |
825 | 825 | else invoke(_loadVaultAdapter(), FUNC_WITHDRAW, [toChainId, asset_, amountToSendStr, to_, relayerFee_], nil) | |
826 | 826 | if ((withdrawInvocation == withdrawInvocation)) | |
827 | 827 | then $Tuple2(((_saveAssetReserves(toChainId, asset_, newAssetReserves) ++ _saveCurrencyReserves(currency, newCurrencyReserves)) ++ _saveWithdrawalHash(withdrawalHash, toBase58String(i.transactionId))), unit) | |
828 | 828 | else throw("Strict value is not equal to itself.") | |
829 | 829 | } | |
830 | 830 | else throw("Strict value is not equal to itself.") | |
831 | 831 | } | |
832 | 832 | else throw("Strict value is not equal to itself.") | |
833 | 833 | } | |
834 | 834 | else throw("Strict value is not equal to itself.") | |
835 | 835 | } | |
836 | 836 | else throw("Strict value is not equal to itself.") | |
837 | 837 | } | |
838 | 838 | else throw("Strict value is not equal to itself.") | |
839 | 839 | } | |
840 | 840 | else throw("Strict value is not equal to itself.") | |
841 | 841 | } | |
842 | 842 | ||
843 | 843 | ||
844 | 844 | ||
845 | 845 | @Callable(i) | |
846 | 846 | func depositStakingReward (callerContract_,chainId_,asset_,amount_) = { | |
847 | 847 | let chainId = valueOrErrorMessage(parseInt(chainId_), "depositStakingReward: chainId not int") | |
848 | 848 | let amount = valueOrErrorMessage(parseBigInt(amount_), "depositStakingReward: amount not int") | |
849 | 849 | let err = if (if (if (if (_whenInitialized()) | |
850 | 850 | then _whenNotPaused() | |
851 | 851 | else false) | |
852 | 852 | then _chainExists(chainId, "depositStakingReward: invalid chainId") | |
853 | 853 | else false) | |
854 | 854 | then _assetCurrencyExists(chainId, asset_, "depositStakingReward: invalid asset") | |
855 | 855 | else false) | |
856 | 856 | then _validateBigInt(amount, ZERO_BIGINT, "depositStakingReward: invalid amount") | |
857 | 857 | else false | |
858 | 858 | if ((err == err)) | |
859 | 859 | then { | |
860 | 860 | let err1 = if ((_loadChain(chainId) == WAVES)) | |
861 | 861 | then _validateWavesVault(i.caller, "depositStakingReward: invalid waves vault") | |
862 | 862 | else if (_validateExecutor(i.caller, "depositStakingReward: invalid executor")) | |
863 | 863 | then _validateCallerContract(chainId, callerContract_, "depositStakingReward: invalid caller contract") | |
864 | 864 | else false | |
865 | 865 | if ((err1 == err1)) | |
866 | 866 | then { | |
867 | 867 | let newAssetReserves = (_loadAssetReserves(chainId, asset_) + amount) | |
868 | 868 | let currency = _loadAssetCurrency(chainId, asset_) | |
869 | 869 | let newCurrencyReserves = (_loadCurrencyReserves(currency) + amount) | |
870 | 870 | let invocation = invoke(_loadAccountStorage(), FUNC_DEPOSIT_STAKING_REWARD, [_loadRewardDistributor(), currency, amount_], nil) | |
871 | 871 | if ((invocation == invocation)) | |
872 | 872 | then $Tuple2((_saveAssetReserves(chainId, asset_, newAssetReserves) ++ _saveCurrencyReserves(currency, newCurrencyReserves)), unit) | |
873 | 873 | else throw("Strict value is not equal to itself.") | |
874 | 874 | } | |
875 | 875 | else throw("Strict value is not equal to itself.") | |
876 | 876 | } | |
877 | 877 | else throw("Strict value is not equal to itself.") | |
878 | 878 | } | |
879 | 879 | ||
880 | 880 | ||
881 | 881 | ||
882 | 882 | @Callable(i) | |
883 | 883 | func addChain (chainId_,name_,callerContract_) = { | |
884 | 884 | let err = if (if (if (if (if (_onlyThisContract(i.caller)) | |
885 | 885 | then _whenInitialized() | |
886 | 886 | else false) | |
887 | 887 | then _validateInt(chainId_, 0, MAX_INT, "addChain: invalid chainId") | |
888 | 888 | else false) | |
889 | 889 | then _validateString(name_, "addChain: invalid name") | |
890 | 890 | else false) | |
891 | 891 | then _validateString(callerContract_, "addChain: invalid callerContract") | |
892 | 892 | else false) | |
893 | 893 | then _chainNotExist(chainId_, "addChain: already exists") | |
894 | 894 | else false | |
895 | 895 | if ((err == err)) | |
896 | 896 | then $Tuple2((_saveChain(chainId_, name_) ++ _saveCallerContract(chainId_, callerContract_)), unit) | |
897 | 897 | else throw("Strict value is not equal to itself.") | |
898 | 898 | } | |
899 | 899 | ||
900 | 900 | ||
901 | 901 | ||
902 | 902 | @Callable(i) | |
903 | 903 | func addAsset (chainId_,asset_,currency_) = { | |
904 | 904 | let err = if (if (if (if (if (_onlyThisContract(i.caller)) | |
905 | 905 | then _whenInitialized() | |
906 | 906 | else false) | |
907 | 907 | then _chainExists(chainId_, "addAsset: invalid chainId") | |
908 | 908 | else false) | |
909 | 909 | then _validateString(asset_, "addAsset: invalid asset") | |
910 | 910 | else false) | |
911 | 911 | then _validateString(currency_, "addAsset: invalid currency") | |
912 | 912 | else false) | |
913 | 913 | then _assetCurrencyNotExist(chainId_, asset_, "addAsset: already exists") | |
914 | 914 | else false | |
915 | 915 | if ((err == err)) | |
916 | 916 | then $Tuple2(_saveAssetCurrency(chainId_, asset_, currency_), unit) | |
917 | 917 | else throw("Strict value is not equal to itself.") | |
918 | 918 | } | |
919 | 919 | ||
920 | 920 | ||
921 | 921 | ||
922 | 922 | @Callable(i) | |
923 | 923 | func setRequestWithdrawalBlockDelay (delay_) = { | |
924 | 924 | let err = if (if (_onlyThisContract(i.caller)) | |
925 | 925 | then _whenInitialized() | |
926 | 926 | else false) | |
927 | 927 | then _validateInt(delay_, 0, MAX_INT, "setRequestWithdrawalBlockDelay: invalid delay") | |
928 | 928 | else false | |
929 | 929 | if ((err == err)) | |
930 | 930 | then $Tuple2(_saveRequestWithdrawalBlockDelay(delay_), unit) | |
931 | 931 | else throw("Strict value is not equal to itself.") | |
932 | 932 | } | |
933 | 933 | ||
934 | 934 | ||
935 | 935 | ||
936 | 936 | @Callable(i) | |
937 | 937 | func updateRewardDistributor (rewardDistributor_) = { | |
938 | 938 | let err = if (if (_onlyThisContract(i.caller)) | |
939 | 939 | then _whenInitialized() | |
940 | 940 | else false) | |
941 | 941 | then _validateString(rewardDistributor_, "updateRewardDistributor: invalid rewardDistributor") | |
942 | 942 | else false | |
943 | 943 | if ((err == err)) | |
944 | 944 | then $Tuple2(_saveRewardDistributor(rewardDistributor_), unit) | |
945 | 945 | else throw("Strict value is not equal to itself.") | |
946 | 946 | } | |
947 | 947 | ||
948 | 948 | ||
949 | 949 | ||
950 | 950 | @Callable(i) | |
951 | 951 | func updateRelayerFeeRecipient (relayerFeeRecipient_) = { | |
952 | 952 | let err = if (if (_onlyThisContract(i.caller)) | |
953 | 953 | then _whenInitialized() | |
954 | 954 | else false) | |
955 | 955 | then _validateString(relayerFeeRecipient_, "updateRelayerFeeRecipient: invalid relayerFeeRecipient") | |
956 | 956 | else false | |
957 | 957 | if ((err == err)) | |
958 | 958 | then $Tuple2(_saveRelayerFeeRecipient(relayerFeeRecipient_), unit) | |
959 | 959 | else throw("Strict value is not equal to itself.") | |
960 | 960 | } | |
961 | 961 | ||
962 | 962 | ||
963 | 963 | ||
964 | 964 | @Callable(i) | |
965 | 965 | func pause () = { | |
966 | 966 | let err = if (if (_onlyPauser(i.caller)) | |
967 | 967 | then _whenInitialized() | |
968 | 968 | else false) | |
969 | 969 | then _whenNotPaused() | |
970 | 970 | else false | |
971 | 971 | if ((err == err)) | |
972 | 972 | then $Tuple2(_savePause(true), unit) | |
973 | 973 | else throw("Strict value is not equal to itself.") | |
974 | 974 | } | |
975 | 975 | ||
976 | 976 | ||
977 | 977 | ||
978 | 978 | @Callable(i) | |
979 | 979 | func unpause () = { | |
980 | 980 | let err = if (if (_onlyPauser(i.caller)) | |
981 | 981 | then _whenInitialized() | |
982 | 982 | else false) | |
983 | 983 | then _whenPaused() | |
984 | 984 | else false | |
985 | 985 | if ((err == err)) | |
986 | 986 | then $Tuple2(_savePause(false), unit) | |
987 | 987 | else throw("Strict value is not equal to itself.") | |
988 | 988 | } | |
989 | 989 | ||
990 | 990 | ||
991 | 991 | ||
992 | 992 | @Callable(i) | |
993 | 993 | func updatePauser (pauser_) = { | |
994 | 994 | let err = if (if (_onlyThisContract(i.caller)) | |
995 | 995 | then _whenInitialized() | |
996 | 996 | else false) | |
997 | 997 | then _validateAddress(pauser_, "updatePauser: invalid pauser") | |
998 | 998 | else false | |
999 | 999 | if ((err == err)) | |
1000 | 1000 | then $Tuple2(_savePauser(addressFromStringValue(pauser_)), unit) | |
1001 | 1001 | else throw("Strict value is not equal to itself.") | |
1002 | 1002 | } | |
1003 | 1003 | ||
1004 | 1004 | ||
1005 | 1005 | ||
1006 | 1006 | @Callable(i) | |
1007 | 1007 | func setMultisig (multisig_) = { | |
1008 | 1008 | let err = if (_onlyThisContract(i.caller)) | |
1009 | 1009 | then _validateAddress(multisig_, "setMultisig: invalid multisig") | |
1010 | 1010 | else false | |
1011 | 1011 | if ((err == err)) | |
1012 | 1012 | then $Tuple2(_saveMultisig(addressFromStringValue(multisig_)), unit) | |
1013 | 1013 | else throw("Strict value is not equal to itself.") | |
1014 | 1014 | } | |
1015 | 1015 | ||
1016 | 1016 | ||
1017 | 1017 | @Verifier(tx) | |
1018 | 1018 | func verify () = match getString(KEY_MULTISIG) { | |
1019 | 1019 | case multisig: String => | |
1020 | 1020 | valueOrElse(getBoolean(addressFromStringValue(multisig), makeString([KEY_STATUS, toString(this), toBase58String(tx.id)], SEPARATOR)), false) | |
1021 | 1021 | case _ => | |
1022 | 1022 | sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey) | |
1023 | 1023 | } | |
1024 | 1024 |
github/deemru/w8io/026f985 107.03 ms ◑