tx · Bz9P6rJGoJT1hMCKddpY611edWW1zwMgyhJKKsaQjUjB

3N2yNznNNBCevaJdCMr8XhM87sKKuBjMdEq:  -0.03600000 Waves

2022.06.30 10:42 [2118881] smart account 3N2yNznNNBCevaJdCMr8XhM87sKKuBjMdEq > SELF 0.00000000 Waves

{ "type": 13, "id": "Bz9P6rJGoJT1hMCKddpY611edWW1zwMgyhJKKsaQjUjB", "fee": 3600000, "feeAssetId": null, "timestamp": 1656574940008, "version": 2, "chainId": 84, "sender": "3N2yNznNNBCevaJdCMr8XhM87sKKuBjMdEq", "senderPublicKey": "644NyMVpLnyzhSJG4FPftw1Gn3yQfD6hbZJQvvoavceg", "proofs": [ "hZjaJPs8nn5NoJnLjvz4KTjLwkaaMq2uwN6KBzHc1Vp7o2D9quMpi7yc2eXmBwiWUmG3fUv7EjJXhEah1s6yzha", "2WSrGwQN4FnoqunMYKMdDMJUX1yw7M7yzVxzCfuJejb9b1RDGm21znTrpbYxZJqyBicuxATMz6VsyewuoSbhp4hy" ], "script": "base64:BgJKCAISBgoEAhgREhIGCgQCGBESEgYKBAIYERISBgoEAhgREhIGCgQCGBESEgYKBAIYERISBgoEAhgREhIGCgQCGBESEgYKBAIYERJLAAd2ZXJzaW9uAgUxLjAuMAAIa1ZlcnNpb24CB3ZlcnNpb24AB2tBY3RpdmUCBmFjdGl2ZQAJa0Fzc2V0SWRBAgpBX2Fzc2V0X2lkAAlrQXNzZXRJZEICCkJfYXNzZXRfaWQACWtCYWxhbmNlQQIPQV9hc3NldF9iYWxhbmNlAAlrQmFsYW5jZUICD0JfYXNzZXRfYmFsYW5jZQANa0JhbGFuY2VJbml0QQIMQV9hc3NldF9pbml0AA1rQmFsYW5jZUluaXRCAgxCX2Fzc2V0X2luaXQADWtTaGFyZUFzc2V0SWQCDnNoYXJlX2Fzc2V0X2lkABFrU2hhcmVBc3NldFN1cHBseQISc2hhcmVfYXNzZXRfc3VwcGx5AARrRmVlAgpjb21taXNzaW9uAAZrQ2F1c2UCDnNodXRkb3duX2NhdXNlAA1rRmlyc3RIYXJ2ZXN0Ag1maXJzdF9oYXJ2ZXN0ABNrRmlyc3RIYXJ2ZXN0SGVpZ2h0AhRmaXJzdF9oYXJ2ZXN0X2hlaWdodAALa1NoYXJlTGltaXQCHHNoYXJlX2xpbWl0X29uX2ZpcnN0X2hhcnZlc3QAC2tCYXNlUGVyaW9kAgtiYXNlX3BlcmlvZAANa1BlcmlvZExlbmd0aAINcGVyaW9kX2xlbmd0aAAMa1N0YXJ0SGVpZ2h0AgxzdGFydF9oZWlnaHQADGtVU0ROQWRkcmVzcwIYc3Rha2luZ191c2RubnNidF9hZGRyZXNzAAxrRVVSTkFkZHJlc3MCFHN0YWtpbmdfZXVybl9hZGRyZXNzAA5rTGVhc2luZ0Ftb3VudAIObGVhc2luZ19hbW91bnQADGtVU0ROQXNzZXRJZAINdXNkbl9hc3NldF9pZAAMa0VVUk5Bc3NldElkAg1ldXJuX2Fzc2V0X2lkAA5rU3Rha2luZ0Fzc2V0cwIOc3Rha2luZ19hc3NldHMADWtPcmFjbGVBY3RpdmUCFGFjdGl2ZV9hbGxfY29udHJhY3RzABdrT3JhY2xlQWN0aXZlRXhjaGFuZ2VycwIYYWN0aXZlX2dsb2JhbF9leGNoYW5nZXJzAAprRGlzY291bnRzAglkaXNjb3VudHMAD2tEaXNjb3VudFZhbHVlcwIPZGlzY291bnRfdmFsdWVzAA5rVXNlclN3b3BJbkdvdgIMX1NXT1BfYW1vdW50AAtrT3JhY2xlUG9vbAIFcG9vbF8ADWtBZG1pblB1YktleTECC2FkbWluX3B1Yl8xAA1rQWRtaW5QdWJLZXkyAgthZG1pbl9wdWJfMgANa0FkbWluUHViS2V5MwILYWRtaW5fcHViXzMAEmtBZG1pbkludm9rZVB1YktleQIQYWRtaW5faW52b2tlX3B1YgAQa01vbmV5Qm94QWRkcmVzcwIRbW9uZXlfYm94X2FkZHJlc3MADmtWb3RpbmdBZGRyZXNzAg52b3RpbmdfYWRkcmVzcwALa0dvdkFkZHJlc3MCEmdvdmVybmFuY2VfYWRkcmVzcwAPa0Zhcm1pbmdBZGRyZXNzAg9mYXJtaW5nX2FkZHJlc3MABm9yYWNsZQkBB0FkZHJlc3MBARoBVOlFqh6QLzqu8boO5i6akl8amITh82KzCAETZ2V0QmFzZTU4RnJvbU9yYWNsZQEDa2V5BAckbWF0Y2gwCQCdCAIFBm9yYWNsZQUDa2V5AwkAAQIFByRtYXRjaDACBlN0cmluZwQGc3RyaW5nBQckbWF0Y2gwCQDZBAEFBnN0cmluZwQHbm90aGluZwUHJG1hdGNoMAkAAgEJAKwCAgUDa2V5AghpcyBlbXB0eQAMYWRtaW5QdWJLZXkxCQETZ2V0QmFzZTU4RnJvbU9yYWNsZQEFDWtBZG1pblB1YktleTEADGFkbWluUHViS2V5MgkBE2dldEJhc2U1OEZyb21PcmFjbGUBBQ1rQWRtaW5QdWJLZXkyAAxhZG1pblB1YktleTMJARNnZXRCYXNlNThGcm9tT3JhY2xlAQUNa0FkbWluUHViS2V5MwARYWRtaW5JbnZva2VQdWJLZXkJARNnZXRCYXNlNThGcm9tT3JhY2xlAQUSa0FkbWluSW52b2tlUHViS2V5AA9tb25leUJveEFkZHJlc3MJAQdBZGRyZXNzAQkBE2dldEJhc2U1OEZyb21PcmFjbGUBBRBrTW9uZXlCb3hBZGRyZXNzAA12b3RpbmdBZGRyZXNzCQEHQWRkcmVzcwEJARNnZXRCYXNlNThGcm9tT3JhY2xlAQUOa1ZvdGluZ0FkZHJlc3MACmdvdkFkZHJlc3MJAQdBZGRyZXNzAQkBE2dldEJhc2U1OEZyb21PcmFjbGUBBQtrR292QWRkcmVzcwAOZmFybWluZ0FkZHJlc3MJAQdBZGRyZXNzAQkBE2dldEJhc2U1OEZyb21PcmFjbGUBBQ9rRmFybWluZ0FkZHJlc3MABFVTRE4JARNnZXRCYXNlNThGcm9tT3JhY2xlAQUMa1VTRE5Bc3NldElkAARFVVJOCQETZ2V0QmFzZTU4RnJvbU9yYWNsZQEFDGtFVVJOQXNzZXRJZAANc3Rha2luZ0Fzc2V0cwkBEUBleHRyTmF0aXZlKDEwNTMpAgUGb3JhY2xlBQ5rU3Rha2luZ0Fzc2V0cwASc3Rha2luZ1VTRE5BZGRyZXNzCQEHQWRkcmVzcwEJARNnZXRCYXNlNThGcm9tT3JhY2xlAQUMa1VTRE5BZGRyZXNzABJzdGFraW5nRVVSTkFkZHJlc3MJAQdBZGRyZXNzAQkBE2dldEJhc2U1OEZyb21PcmFjbGUBBQxrRVVSTkFkZHJlc3MACmJhc2VQZXJpb2QJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQ12b3RpbmdBZGRyZXNzBQtrQmFzZVBlcmlvZAIRRW1wdHkga0Jhc2VQZXJpb2QAC3N0YXJ0SGVpZ2h0CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUNdm90aW5nQWRkcmVzcwUMa1N0YXJ0SGVpZ2h0AhJFbXB0eSBrU3RhcnRIZWlnaHQADHBlcmlvZExlbmd0aAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFDXZvdGluZ0FkZHJlc3MFDWtQZXJpb2RMZW5ndGgCE0VtcHR5IGtQZXJpb2RMZW5ndGgAFWZpcnN0SGFydmVzdEVuZFBlcmlvZAkAZAIJAGQCBQpiYXNlUGVyaW9kCQBpAgkAZQIFBmhlaWdodAULc3RhcnRIZWlnaHQFDHBlcmlvZExlbmd0aAADAAZhY3RpdmUDCQERQGV4dHJOYXRpdmUoMTA1MSkCBQZvcmFjbGUFDWtPcmFjbGVBY3RpdmUJARFAZXh0ck5hdGl2ZSgxMDUxKQIFBm9yYWNsZQUXa09yYWNsZUFjdGl2ZUV4Y2hhbmdlcnMHAAlmZWVTY2FsZTYAwIQ9AAZzY2FsZTgAgMLXLwEOYWNjb3VudEJhbGFuY2UCB2Fzc2V0SWQEcG9vbAQHJG1hdGNoMAUHYXNzZXRJZAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAJpZAUHJG1hdGNoMAkA8AcCBQRwb29sBQJpZAMJAAECBQckbWF0Y2gwAgRVbml0BAV3YXZlcwUHJG1hdGNoMAgJAO8HAQUEcG9vbAlhdmFpbGFibGUJAAIBAgtNYXRjaCBlcnJvcgEMc3Rha2VkQW1vdW50Agdhc3NldElkBHBvb2wEFnN0YWtlZEFtb3VudENhbGN1bGF0ZWQEByRtYXRjaDAFB2Fzc2V0SWQDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQDYUlkBQckbWF0Y2gwAwkAAAIFA2FJZAUEVVNETgkAmggCBRJzdGFraW5nVVNETkFkZHJlc3MJAKwCAgkArAICCQCsAgICDHJwZF9iYWxhbmNlXwkA2AQBBQNhSWQCAV8JAKUIAQUEcG9vbAMJAAACBQNhSWQFBEVVUk4JAJoIAgUSc3Rha2luZ0VVUk5BZGRyZXNzCQCsAgIJAKwCAgkArAICAhglcyVzJXNfX3N0YWtpbmdCYWxhbmNlX18JANgEAQUDYUlkAgJfXwkApQgBBQRwb29sAAADCQABAgUHJG1hdGNoMAIEVW5pdAkBC3ZhbHVlT3JFbHNlAgkAmggCBQRwb29sBQ5rTGVhc2luZ0Ftb3VudAAACQACAQILTWF0Y2ggZXJyb3IEByRtYXRjaDAFFnN0YWtlZEFtb3VudENhbGN1bGF0ZWQDCQABAgUHJG1hdGNoMAIDSW50BAFpBQckbWF0Y2gwBQFpAAABDGdldEFzc2V0SW5mbwEHYXNzZXRJZAQHJG1hdGNoMAUHYXNzZXRJZAMDCQABAgUHJG1hdGNoMAIGU3RyaW5nBgkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAmlkBQckbWF0Y2gwBAskdDAzOTY3NDEzOQQHJG1hdGNoMQUCaWQDCQABAgUHJG1hdGNoMQIKQnl0ZVZlY3RvcgQDYUlkBQckbWF0Y2gxCQCUCgIJANgEAQUDYUlkBQNhSWQDCQABAgUHJG1hdGNoMQIGU3RyaW5nBANhSWQFByRtYXRjaDEJAJQKAgUDYUlkCQDZBAEFA2FJZAkAAgECC01hdGNoIGVycm9yBAhzdHJpbmdJZAgFCyR0MDM5Njc0MTM5Al8xBAdieXRlc0lkCAULJHQwMzk2NzQxMzkCXzIEBGluZm8JARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQdieXRlc0lkCQCsAgIJAKwCAgIGQXNzZXQgBQhzdHJpbmdJZAIOIGRvZXNuJ3QgZXhpc3QJAJUKAwUIc3RyaW5nSWQIBQRpbmZvBG5hbWUIBQRpbmZvCGRlY2ltYWxzAwkAAQIFByRtYXRjaDACBFVuaXQEBXdhdmVzBQckbWF0Y2gwCQCVCgMCBVdBVkVTAgVXQVZFUwAICQACAQILTWF0Y2ggZXJyb3IBB3N1c3BlbmQBBWNhdXNlCQDMCAIJAQxCb29sZWFuRW50cnkCBQdrQWN0aXZlBwkAzAgCCQELU3RyaW5nRW50cnkCBQZrQ2F1c2UFBWNhdXNlBQNuaWwBFGNhbGN1bGF0ZUZlZURpc2NvdW50AQh1c2VyQWRkcgQKc3dvcEFtb3VudAkBC3ZhbHVlT3JFbHNlAgkAmggCBQpnb3ZBZGRyZXNzCQCsAgIJAKUIAQUIdXNlckFkZHIFDmtVc2VyU3dvcEluR292AAAEDmRpc2NvdW50VmFsdWVzCQC1CQIJARFAZXh0ck5hdGl2ZSgxMDUzKQIFBm9yYWNsZQUPa0Rpc2NvdW50VmFsdWVzAgEsBAlkaXNjb3VudHMJALUJAgkBEUBleHRyTmF0aXZlKDEwNTMpAgUGb3JhY2xlBQprRGlzY291bnRzAgEsAwMJAGcCBQpzd29wQW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUOZGlzY291bnRWYWx1ZXMAAAkAZgIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5kaXNjb3VudFZhbHVlcwABBQpzd29wQW1vdW50BwkAZQIFCWZlZVNjYWxlNgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWRpc2NvdW50cwAAAwMJAGcCBQpzd29wQW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUOZGlzY291bnRWYWx1ZXMAAQkAZgIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5kaXNjb3VudFZhbHVlcwACBQpzd29wQW1vdW50BwkAZQIFCWZlZVNjYWxlNgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWRpc2NvdW50cwABAwMJAGcCBQpzd29wQW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUOZGlzY291bnRWYWx1ZXMAAgkAZgIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5kaXNjb3VudFZhbHVlcwADBQpzd29wQW1vdW50BwkAZQIFCWZlZVNjYWxlNgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWRpc2NvdW50cwACAwMJAGcCBQpzd29wQW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUOZGlzY291bnRWYWx1ZXMAAwkAZgIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5kaXNjb3VudFZhbHVlcwAEBQpzd29wQW1vdW50BwkAZQIFCWZlZVNjYWxlNgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWRpc2NvdW50cwADAwkAZwIFCnN3b3BBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5kaXNjb3VudFZhbHVlcwAECQBlAgUJZmVlU2NhbGU2CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUJZGlzY291bnRzAAQFCWZlZVNjYWxlNgENY2FsY3VsYXRlRmVlcwYJcG10QW1vdW50Em1pbkFtb3VudFRvUmVjZWl2ZQl0b2tlbkZyb20HdG9rZW5UbwNmZWUNZmVlR292ZXJuYW5jZQQQYW1vdW50V2l0aG91dEZlZQkAawMFB3Rva2VuVG8FCXBtdEFtb3VudAkAZAIFCXBtdEFtb3VudAUJdG9rZW5Gcm9tBA1hbW91bnRXaXRoRmVlCQBrAwUQYW1vdW50V2l0aG91dEZlZQkAZQIFCWZlZVNjYWxlNgUDZmVlBQlmZWVTY2FsZTYEEGdvdmVybmFuY2VSZXdhcmQJAGsDBRBhbW91bnRXaXRob3V0RmVlBQ1mZWVHb3Zlcm5hbmNlBQlmZWVTY2FsZTYDCQBmAgUSbWluQW1vdW50VG9SZWNlaXZlBQ1hbW91bnRXaXRoRmVlCQACAQkArAICCQCsAgIJAKwCAgIdQ2FsY3VsYXRlZCBhbW91bnQgdG8gcmVjZWl2ZSAJAKQDAQUNYW1vdW50V2l0aEZlZQIgIGlzIGxlc3MgdGhhbiBzcGVjaWZpZWQgbWluaW11bSAJAKQDAQUSbWluQW1vdW50VG9SZWNlaXZlCQCVCgMFEGFtb3VudFdpdGhvdXRGZWUFDWFtb3VudFdpdGhGZWUFEGdvdmVybmFuY2VSZXdhcmQBEGNhbGN1bGF0ZVZpcnRHZXQDCXBtdEFtb3VudAdiYWxhbmNlA2ZlZQQBYQABBAFiCQBlAgkAZAIJAGQCBQdiYWxhbmNlCQBrAwUHYmFsYW5jZQkAZQIFCWZlZVNjYWxlNgUDZmVlBQlmZWVTY2FsZTYJAGsDBQlwbXRBbW91bnQJAGUCBQlmZWVTY2FsZTYFA2ZlZQUJZmVlU2NhbGU2BQlwbXRBbW91bnQEAWMJALkCAgkAvgIBCQC2AgEFB2JhbGFuY2UJALYCAQUJcG10QW1vdW50BAFECQC4AgIJALkCAgkAtgIBBQFiCQC2AgEFAWIJALkCAgkAuQICCQC2AgEABAkAtgIBBQFhBQFjCQBoAgkAoAMBCQC6AgIJALcCAgkAvgIBCQC2AgEFAWIJAHYGBQFEAAAJALYCAQAFAAEAAAUERE9XTgkAtgIBAAIFAWEBEXBhcnNlUGF5bWVudEFzc2V0AQdhc3NldElkAwkAAAIFB2Fzc2V0SWQBAAUEdW5pdAUHYXNzZXRJZAERc3VzcGVuZFN1c3BpY2lvdXMGD2FjY291bnRCYWxhbmNlQQ9hY2NvdW50QmFsYW5jZUIIYmFsYW5jZUEIYmFsYW5jZUIIYXNzZXRJZEEIYXNzZXRJZEIJAQdzdXNwZW5kAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIjU3VzcGljaW91cyBzdGF0ZS4gQWN0dWFsIGJhbGFuY2VzOiAJAKQDAQUPYWNjb3VudEJhbGFuY2VBAgEgBQhhc3NldElkQQICLCAJAKQDAQUPYWNjb3VudEJhbGFuY2VCAgEgBQhhc3NldElkQgIJLiBTdGF0ZTogCQCkAwEFCGJhbGFuY2VBAgEgBQhhc3NldElkQQICLCAJAKQDAQUIYmFsYW5jZUICASAFCGFzc2V0SWRCAQhpc0FjdGl2ZQADBQZhY3RpdmUFBHVuaXQJAAIBAh9EQXBwIGlzIGluYWN0aXZlIGF0IHRoaXMgbW9tZW50AQxpc09yYWNsZVBvb2wBC3Bvb2xBZGRyZXNzAwkBCWlzRGVmaW5lZAEJAJ0IAgUGb3JhY2xlCQCsAgIFC2tPcmFjbGVQb29sBQtwb29sQWRkcmVzcwUEdW5pdAkAAgECG0RBcHAgaXMgbm90IHJlZ2lzdGVyZWQgcG9vbAEPZ2V0UG9vbEJhbGFuY2VzAwRwb29sCGFzc2V0SWRBCGFzc2V0SWRCBAhiYWxhbmNlQQkBEUBleHRyTmF0aXZlKDEwNTApAgUEcG9vbAUJa0JhbGFuY2VBBAhiYWxhbmNlQgkBEUBleHRyTmF0aXZlKDEwNTApAgUEcG9vbAUJa0JhbGFuY2VCBA1zdGFrZWRBbW91bnRBCQEMc3Rha2VkQW1vdW50AgUIYXNzZXRJZEEFBHBvb2wEDXN0YWtlZEFtb3VudEIJAQxzdGFrZWRBbW91bnQCBQhhc3NldElkQgUEcG9vbAQPYWNjb3VudEJhbGFuY2VBCQBkAgkBDmFjY291bnRCYWxhbmNlAgUIYXNzZXRJZEEFBHBvb2wFDXN0YWtlZEFtb3VudEEED2FjY291bnRCYWxhbmNlQgkAZAIJAQ5hY2NvdW50QmFsYW5jZQIFCGFzc2V0SWRCBQRwb29sBQ1zdGFrZWRBbW91bnRCBAtzaGFyZVN1cHBseQkBEUBleHRyTmF0aXZlKDEwNTApAgUEcG9vbAURa1NoYXJlQXNzZXRTdXBwbHkJAJcKBQUIYmFsYW5jZUEFCGJhbGFuY2VCBQ9hY2NvdW50QmFsYW5jZUEFD2FjY291bnRCYWxhbmNlQgULc2hhcmVTdXBwbHkBDWdldFBvb2xBc3NldHMBBHBvb2wEC3N0ckFzc2V0SWRBCQERQGV4dHJOYXRpdmUoMTA1MykCBQRwb29sBQlrQXNzZXRJZEEEC3N0ckFzc2V0SWRCCQERQGV4dHJOYXRpdmUoMTA1MykCBQRwb29sBQlrQXNzZXRJZEIECGFzc2V0SWRBAwkAAAIFC3N0ckFzc2V0SWRBAgVXQVZFUwUEdW5pdAkA2QQBBQtzdHJBc3NldElkQQQIYXNzZXRJZEIDCQAAAgULc3RyQXNzZXRJZEICBVdBVkVTBQR1bml0CQDZBAEFC3N0ckFzc2V0SWRCBAxzaGFyZUFzc2V0SWQJANkEAQkBEUBleHRyTmF0aXZlKDEwNTMpAgUEcG9vbAUNa1NoYXJlQXNzZXRJZAkAlwoFBQtzdHJBc3NldElkQQULc3RyQXNzZXRJZEIFCGFzc2V0SWRBBQhhc3NldElkQgUMc2hhcmVBc3NldElkAQxnZXRGZWVQYXJhbXMCBHBvb2wGY2FsbGVyBAtmZWVEaXNjb3VudAkBFGNhbGN1bGF0ZUZlZURpc2NvdW50AQUGY2FsbGVyBANmZWUJAG4ECQERQGV4dHJOYXRpdmUoMTA1MCkCBQRwb29sBQRrRmVlBQtmZWVEaXNjb3VudAUJZmVlU2NhbGU2BQdDRUlMSU5HBAZnb3ZGZWUJAG4ECQBrAwUDZmVlACgAZAULZmVlRGlzY291bnQFCWZlZVNjYWxlNgUHQ0VJTElORwkAlAoCBQNmZWUFBmdvdkZlZQkBaQEEaW5pdAQLY2FsbGVyQnl0ZXMEYXJncwhwQW1vdW50cwlwQXNzZXRJZHMEBmNhbGxlcgkBB0FkZHJlc3MBBQtjYWxsZXJCeXRlcwQLJHQwODg1MTg5MjkJAJQKAgkAkQMCBQhwQW1vdW50cwAACQERcGFyc2VQYXltZW50QXNzZXQBCQCRAwIFCXBBc3NldElkcwAABApwbXRBbW91bnRBCAULJHQwODg1MTg5MjkCXzEEC3BtdEFzc2V0SWRBCAULJHQwODg1MTg5MjkCXzIECyR0MDg5MzQ5MDEyCQCUCgIJAJEDAgUIcEFtb3VudHMAAQkBEXBhcnNlUGF5bWVudEFzc2V0AQkAkQMCBQlwQXNzZXRJZHMAAQQKcG10QW1vdW50QggFCyR0MDg5MzQ5MDEyAl8xBAtwbXRBc3NldElkQggFCyR0MDg5MzQ5MDEyAl8yAwkBASEBCQEPY29udGFpbnNFbGVtZW50AgkAzAgCBQxhZG1pblB1YktleTEJAMwIAgUMYWRtaW5QdWJLZXkyCQDMCAIFDGFkbWluUHViS2V5MwkAzAgCBRFhZG1pbkludm9rZVB1YktleQUDbmlsCAUBaRVvcmlnaW5DYWxsZXJQdWJsaWNLZXkJAAIBAiFPbmx5IGFkbWluIGNhbiBjYWxsIHRoaXMgZnVuY3Rpb24DCQEJaXNEZWZpbmVkAQkAmwgCBQZjYWxsZXIFB2tBY3RpdmUJAAIBAhZEQXBwIGlzIGFscmVhZHkgYWN0aXZlAwkAAAIFC3BtdEFzc2V0SWRBBQtwbXRBc3NldElkQgkAAgECGEFzc2V0cyBtdXN0IGJlIGRpZmZlcmVudAQLJHQwOTM4Mjk0NTkJAQxnZXRBc3NldEluZm8BBQtwbXRBc3NldElkQQQOcG10U3RyQXNzZXRJZEEIBQskdDA5MzgyOTQ1OQJfMQQNcG10QXNzZXROYW1lQQgFCyR0MDkzODI5NDU5Al8yBAxwbXREZWNpbWFsc0EIBQskdDA5MzgyOTQ1OQJfMwQLJHQwOTQ2ODk1NDUJAQxnZXRBc3NldEluZm8BBQtwbXRBc3NldElkQgQOcG10U3RyQXNzZXRJZEIIBQskdDA5NDY4OTU0NQJfMQQNcG10QXNzZXROYW1lQggFCyR0MDk0Njg5NTQ1Al8yBAxwbXREZWNpbWFsc0IIBQskdDA5NDY4OTU0NQJfMwQMZmlyc3RIYXJ2ZXN0CQAAAgkAkQMCBQRhcmdzAAACBHRydWUECXNoYXJlTmFtZQkArAICCQCsAgIJAKwCAgIBcwkArwICBQ1wbXRBc3NldE5hbWVBAAcCAV8JAK8CAgUNcG10QXNzZXROYW1lQgAHBBBzaGFyZURlc2NyaXB0aW9uCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIiU2hhcmVUb2tlbiBvZiBTd29wRmkgcHJvdG9jb2wgZm9yIAUNcG10QXNzZXROYW1lQQIFIGFuZCAFDXBtdEFzc2V0TmFtZUICDCBhdCBhZGRyZXNzIAkApQgBBQR0aGlzBA1zaGFyZURlY2ltYWxzCQBpAgkAZAIFDHBtdERlY2ltYWxzQQUMcG10RGVjaW1hbHNCAAIEBGFyZzEJAGwGBQpwbXRBbW91bnRBBQxwbXREZWNpbWFsc0EABQABBQxwbXREZWNpbWFsc0EFBERPV04EBGFyZzIJAGwGBQpwbXRBbW91bnRCBQxwbXREZWNpbWFsc0IABQABBQxwbXREZWNpbWFsc0IFBERPV04EBGFyZzMJAGwGAAoAAAUNc2hhcmVEZWNpbWFscwAAAAAFBERPV04EEnNoYXJlSW5pdGlhbFN1cHBseQkAawMFBGFyZzEFBGFyZzIFBGFyZzMECnNoYXJlSXNzdWUJAMIIBQUJc2hhcmVOYW1lBRBzaGFyZURlc2NyaXB0aW9uBRJzaGFyZUluaXRpYWxTdXBwbHkFDXNoYXJlRGVjaW1hbHMGBAxzaGFyZUlzc3VlSWQJALgIAQUKc2hhcmVJc3N1ZQQGc3Rha2UxAwkBCGNvbnRhaW5zAgUNc3Rha2luZ0Fzc2V0cwUOcG10U3RyQXNzZXRJZEEJAPwHBAgFAWkGY2FsbGVyAgxzdGFrZVVuc3Rha2UJAMwIAgYJAMwIAgUKcG10QW1vdW50QQkAzAgCBQ5wbXRTdHJBc3NldElkQQUDbmlsBQNuaWwAAAMJAAACBQZzdGFrZTEFBnN0YWtlMQQGc3Rha2UyAwkBCGNvbnRhaW5zAgUNc3Rha2luZ0Fzc2V0cwUOcG10U3RyQXNzZXRJZEIJAPwHBAgFAWkGY2FsbGVyAgxzdGFrZVVuc3Rha2UJAMwIAgYJAMwIAgUKcG10QW1vdW50QgkAzAgCBQ5wbXRTdHJBc3NldElkQgUDbmlsBQNuaWwAAAMJAAACBQZzdGFrZTIFBnN0YWtlMgQJYmFzZUVudHJ5CQDMCAIJAQtTdHJpbmdFbnRyeQIFCGtWZXJzaW9uBQd2ZXJzaW9uCQDMCAIJAQxCb29sZWFuRW50cnkCBQdrQWN0aXZlBgkAzAgCCQELU3RyaW5nRW50cnkCBQlrQXNzZXRJZEEFDnBtdFN0ckFzc2V0SWRBCQDMCAIJAQtTdHJpbmdFbnRyeQIFCWtBc3NldElkQgUOcG10U3RyQXNzZXRJZEIJAMwIAgkBDEludGVnZXJFbnRyeQIFCWtCYWxhbmNlQQUKcG10QW1vdW50QQkAzAgCCQEMSW50ZWdlckVudHJ5AgUJa0JhbGFuY2VCBQpwbXRBbW91bnRCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQRrRmVlCQERQGV4dHJOYXRpdmUoMTA1MCkCBQZvcmFjbGUCDWJhc2VfZmVlX2NwbW0JAMwIAgUKc2hhcmVJc3N1ZQkAzAgCCQELU3RyaW5nRW50cnkCBQ1rU2hhcmVBc3NldElkCQDYBAEFDHNoYXJlSXNzdWVJZAkAzAgCCQEMSW50ZWdlckVudHJ5AgURa1NoYXJlQXNzZXRTdXBwbHkFEnNoYXJlSW5pdGlhbFN1cHBseQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQZjYWxsZXIFEnNoYXJlSW5pdGlhbFN1cHBseQUMc2hhcmVJc3N1ZUlkBQNuaWwDBQxmaXJzdEhhcnZlc3QJAJQKAgUDbmlsCQCUCgIJAM4IAgUJYmFzZUVudHJ5CQDMCAIJAQxCb29sZWFuRW50cnkCBQ1rRmlyc3RIYXJ2ZXN0BQxmaXJzdEhhcnZlc3QJAMwIAgkBDEludGVnZXJFbnRyeQIFE2tGaXJzdEhhcnZlc3RIZWlnaHQJAGQCBQtzdGFydEhlaWdodAkAaAIFFWZpcnN0SGFydmVzdEVuZFBlcmlvZAUMcGVyaW9kTGVuZ3RoBQNuaWwFA25pbAkAlAoCBQNuaWwJAJQKAgUJYmFzZUVudHJ5BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQERaW5pdFdpdGhJbml0UmF0aW8EC2NhbGxlckJ5dGVzBGFyZ3MIcEFtb3VudHMJcEFzc2V0SWRzBAZjYWxsZXIJAQdBZGRyZXNzAQULY2FsbGVyQnl0ZXMEDSR0MDExNzkwMTE5OTAJAJcKBQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGFyZ3MAAAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGFyZ3MAAQkAkQMCBQRhcmdzAAIJAJEDAgUEYXJncwADCQAAAgkAkQMCBQRhcmdzAAQCBHRydWUECWFtdEFzc2V0QQgFDSR0MDExNzkwMTE5OTACXzEECWFtdEFzc2V0QggFDSR0MDExNzkwMTE5OTACXzIEC2Fzc2V0SWRBU3RyCAUNJHQwMTE3OTAxMTk5MAJfMwQLYXNzZXRJZEJTdHIIBQ0kdDAxMTc5MDExOTkwAl80BAxmaXJzdEhhcnZlc3QIBQ0kdDAxMTc5MDExOTkwAl81AwkBASEBCQEPY29udGFpbnNFbGVtZW50AgkAzAgCBQxhZG1pblB1YktleTEJAMwIAgUMYWRtaW5QdWJLZXkyCQDMCAIFDGFkbWluUHViS2V5MwkAzAgCBRFhZG1pbkludm9rZVB1YktleQUDbmlsCAUBaRVvcmlnaW5DYWxsZXJQdWJsaWNLZXkJAAIBAiFPbmx5IGFkbWluIGNhbiBjYWxsIHRoaXMgZnVuY3Rpb24DCQEJaXNEZWZpbmVkAQkAmwgCBQZjYWxsZXIFB2tBY3RpdmUJAAIBAhZEQXBwIGlzIGFscmVhZHkgYWN0aXZlAwkAAAIFC2Fzc2V0SWRBU3RyBQthc3NldElkQlN0cgkAAgECGEFzc2V0cyBtdXN0IGJlIGRpZmZlcmVudAQNJHQwMTIzNjAxMjQzNwkBDGdldEFzc2V0SW5mbwEFC2Fzc2V0SWRBU3RyBA5wbXRTdHJBc3NldElkQQgFDSR0MDEyMzYwMTI0MzcCXzEEDXBtdEFzc2V0TmFtZUEIBQ0kdDAxMjM2MDEyNDM3Al8yBAxwbXREZWNpbWFsc0EIBQ0kdDAxMjM2MDEyNDM3Al8zBA0kdDAxMjQ0NjEyNTIzCQEMZ2V0QXNzZXRJbmZvAQULYXNzZXRJZEJTdHIEDnBtdFN0ckFzc2V0SWRCCAUNJHQwMTI0NDYxMjUyMwJfMQQNcG10QXNzZXROYW1lQggFDSR0MDEyNDQ2MTI1MjMCXzIEDHBtdERlY2ltYWxzQggFDSR0MDEyNDQ2MTI1MjMCXzMECXNoYXJlTmFtZQkArAICCQCsAgIJAKwCAgIBcwkArwICBQ1wbXRBc3NldE5hbWVBAAcCAV8JAK8CAgUNcG10QXNzZXROYW1lQgAHBBBzaGFyZURlc2NyaXB0aW9uCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIiU2hhcmVUb2tlbiBvZiBTd29wRmkgcHJvdG9jb2wgZm9yIAUNcG10QXNzZXROYW1lQQIFIGFuZCAFDXBtdEFzc2V0TmFtZUICDCBhdCBhZGRyZXNzIAkApQgBBQR0aGlzBA1zaGFyZURlY2ltYWxzCQBpAgkAZAIFDHBtdERlY2ltYWxzQQUMcG10RGVjaW1hbHNCAAIEEnNoYXJlSW5pdGlhbFN1cHBseQAABApzaGFyZUlzc3VlCQDCCAUFCXNoYXJlTmFtZQUQc2hhcmVEZXNjcmlwdGlvbgUSc2hhcmVJbml0aWFsU3VwcGx5BQ1zaGFyZURlY2ltYWxzBgQMc2hhcmVJc3N1ZUlkCQC4CAEFCnNoYXJlSXNzdWUECWJhc2VFbnRyeQkAzAgCCQELU3RyaW5nRW50cnkCBQhrVmVyc2lvbgUHdmVyc2lvbgkAzAgCCQEMQm9vbGVhbkVudHJ5AgUHa0FjdGl2ZQYJAMwIAgkBC1N0cmluZ0VudHJ5AgUJa0Fzc2V0SWRBBQ5wbXRTdHJBc3NldElkQQkAzAgCCQELU3RyaW5nRW50cnkCBQlrQXNzZXRJZEIFDnBtdFN0ckFzc2V0SWRCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ1rQmFsYW5jZUluaXRBBQlhbXRBc3NldEEJAMwIAgkBDEludGVnZXJFbnRyeQIFDWtCYWxhbmNlSW5pdEIFCWFtdEFzc2V0QgkAzAgCCQEMSW50ZWdlckVudHJ5AgUJa0JhbGFuY2VBAAAJAMwIAgkBDEludGVnZXJFbnRyeQIFCWtCYWxhbmNlQgAACQDMCAIJAQxJbnRlZ2VyRW50cnkCBQRrRmVlCQERQGV4dHJOYXRpdmUoMTA1MCkCBQZvcmFjbGUCDWJhc2VfZmVlX2NwbW0JAMwIAgUKc2hhcmVJc3N1ZQkAzAgCCQELU3RyaW5nRW50cnkCBQ1rU2hhcmVBc3NldElkCQDYBAEFDHNoYXJlSXNzdWVJZAkAzAgCCQEMSW50ZWdlckVudHJ5AgURa1NoYXJlQXNzZXRTdXBwbHkFEnNoYXJlSW5pdGlhbFN1cHBseQUDbmlsAwUMZmlyc3RIYXJ2ZXN0CQCUCgIFA25pbAkAlAoCCQDOCAIFCWJhc2VFbnRyeQkAzAgCCQEMQm9vbGVhbkVudHJ5AgUNa0ZpcnN0SGFydmVzdAUMZmlyc3RIYXJ2ZXN0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBRNrRmlyc3RIYXJ2ZXN0SGVpZ2h0CQBkAgULc3RhcnRIZWlnaHQJAGgCBRVmaXJzdEhhcnZlc3RFbmRQZXJpb2QFDHBlcmlvZExlbmd0aAUDbmlsBQNuaWwJAJQKAgUDbmlsCQCUCgIFCWJhc2VFbnRyeQUDbmlsAWkBGGtlZXBMaW1pdEZvckZpcnN0SGFydmVzdAQLY2FsbGVyQnl0ZXMEYXJncwhwQW1vdW50cwlwQXNzZXRJZHMJAQt2YWx1ZU9yRWxzZQIJAQxpc09yYWNsZVBvb2wBCQClCAEIBQFpBmNhbGxlcgkBC3ZhbHVlT3JFbHNlAgkBCGlzQWN0aXZlAAMJAQEhAQkBD2NvbnRhaW5zRWxlbWVudAIJAMwIAgUMYWRtaW5QdWJLZXkxCQDMCAIFDGFkbWluUHViS2V5MgkAzAgCBQxhZG1pblB1YktleTMJAMwIAgURYWRtaW5JbnZva2VQdWJLZXkFA25pbAgFAWkVb3JpZ2luQ2FsbGVyUHVibGljS2V5CQACAQIhT25seSBhZG1pbiBjYW4gY2FsbCB0aGlzIGZ1bmN0aW9uBApzaGFyZUxpbWl0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEYXJncwAACQCUCgIFA25pbAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQtrU2hhcmVMaW1pdAUKc2hhcmVMaW1pdAUDbmlsBQNuaWwBaQEIZXhjaGFuZ2UEC2NhbGxlckJ5dGVzBGFyZ3MIcEFtb3VudHMJcEFzc2V0SWRzCQELdmFsdWVPckVsc2UCCQEMaXNPcmFjbGVQb29sAQkApQgBCAUBaQZjYWxsZXIJAQt2YWx1ZU9yRWxzZQIJAQhpc0FjdGl2ZQAEBmNhbGxlcgkBB0FkZHJlc3MBBQtjYWxsZXJCeXRlcwQNJHQwMTQ4NDgxNDkyNAkAlAoCCQCRAwIFCHBBbW91bnRzAAAJARFwYXJzZVBheW1lbnRBc3NldAEJAJEDAgUJcEFzc2V0SWRzAAAECXBtdEFtb3VudAgFDSR0MDE0ODQ4MTQ5MjQCXzEECnBtdEFzc2V0SWQIBQ0kdDAxNDg0ODE0OTI0Al8yBBJtaW5BbW91bnRUb1JlY2VpdmUJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRhcmdzAAAEDSR0MDE0OTk3MTUwNzMJAQ1nZXRQb29sQXNzZXRzAQgFAWkGY2FsbGVyBAtzdHJBc3NldElkQQgFDSR0MDE0OTk3MTUwNzMCXzEEC3N0ckFzc2V0SWRCCAUNJHQwMTQ5OTcxNTA3MwJfMgQIYXNzZXRJZEEIBQ0kdDAxNDk5NzE1MDczAl8zBAhhc3NldElkQggFDSR0MDE0OTk3MTUwNzMCXzQEDSR0MDE1MDg2MTUxOTIJAQ9nZXRQb29sQmFsYW5jZXMDCAUBaQZjYWxsZXIFCGFzc2V0SWRBBQhhc3NldElkQgQIYmFsYW5jZUEIBQ0kdDAxNTA4NjE1MTkyAl8xBAhiYWxhbmNlQggFDSR0MDE1MDg2MTUxOTICXzIED2FjY291bnRCYWxhbmNlQQgFDSR0MDE1MDg2MTUxOTICXzMED2FjY291bnRCYWxhbmNlQggFDSR0MDE1MDg2MTUxOTICXzQDAwkAAAIFCGJhbGFuY2VBAAAGCQAAAgUIYmFsYW5jZUIAAAkAAgECIENhbid0IGV4Y2hhbmdlIHdpdGggemVybyBiYWxhbmNlAwkAZwIAAAUSbWluQW1vdW50VG9SZWNlaXZlCQACAQkArAICAjRNaW5pbWFsIGFtb3VudCB0byByZWNlaXZlIG11c3QgYmUgcG9zaXRpdmUuIEFjdHVhbDogCQCkAwEFEm1pbkFtb3VudFRvUmVjZWl2ZQMJAQIhPQIJAJADAQUIcEFtb3VudHMAAQkAAgECHU9uZSBhdHRhY2hlZCBwYXltZW50IGV4cGVjdGVkAwkBASEBCQEPY29udGFpbnNFbGVtZW50AgkAzAgCBQhhc3NldElkQQkAzAgCBQhhc3NldElkQgUDbmlsBQpwbXRBc3NldElkCQACAQkArAICCQCsAgIJAKwCAgIkSW5jb3JyZWN0IGFzc2V0IGF0dGFjaGVkLiBFeHBlY3RlZDogBQtzdHJBc3NldElkQQIEIG9yIAULc3RyQXNzZXRJZEIDAwkAZgIFCGJhbGFuY2VBBQ9hY2NvdW50QmFsYW5jZUEGCQBmAgUIYmFsYW5jZUIFD2FjY291bnRCYWxhbmNlQgkAlAoCBQNuaWwJAM4IAgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQZjYWxsZXIFCXBtdEFtb3VudAUKcG10QXNzZXRJZAUDbmlsCQERc3VzcGVuZFN1c3BpY2lvdXMGBQ9hY2NvdW50QmFsYW5jZUEFD2FjY291bnRCYWxhbmNlQgUIYmFsYW5jZUEFCGJhbGFuY2VCBQtzdHJBc3NldElkQQULc3RyQXNzZXRJZEIEDSR0MDE2MDc3MTYxMzUJAQxnZXRGZWVQYXJhbXMCCAUBaQZjYWxsZXIIBQFpDG9yaWdpbkNhbGxlcgQDZmVlCAUNJHQwMTYwNzcxNjEzNQJfMQQGZ292RmVlCAUNJHQwMTYwNzcxNjEzNQJfMgQNJHQwMTYxNTIxNjQ4OQMJAAACBQpwbXRBc3NldElkBQhhc3NldElkQQkBDWNhbGN1bGF0ZUZlZXMGBQlwbXRBbW91bnQFEm1pbkFtb3VudFRvUmVjZWl2ZQUIYmFsYW5jZUEFCGJhbGFuY2VCBQNmZWUFBmdvdkZlZQkBDWNhbGN1bGF0ZUZlZXMGBQlwbXRBbW91bnQFEm1pbkFtb3VudFRvUmVjZWl2ZQUIYmFsYW5jZUIFCGJhbGFuY2VBBQNmZWUFBmdvdkZlZQQQYW1vdW50V2l0aG91dEZlZQgFDSR0MDE2MTUyMTY0ODkCXzEEDWFtb3VudFdpdGhGZWUIBQ0kdDAxNjE1MjE2NDg5Al8yBBBnb3Zlcm5hbmNlUmV3YXJkCAUNJHQwMTYxNTIxNjQ4OQJfMwQNJHQwMTY1MDcxNjgzMgMJAAACBQpwbXRBc3NldElkBQhhc3NldElkQQkAlQoDCQBkAgUIYmFsYW5jZUEFCXBtdEFtb3VudAkAZQIJAGUCBQhiYWxhbmNlQgUNYW1vdW50V2l0aEZlZQUQZ292ZXJuYW5jZVJld2FyZAUIYXNzZXRJZEIJAJUKAwkAZQIJAGUCBQhiYWxhbmNlQQUNYW1vdW50V2l0aEZlZQUQZ292ZXJuYW5jZVJld2FyZAkAZAIFCGJhbGFuY2VCBQlwbXRBbW91bnQFCGFzc2V0SWRBBAtuZXdCYWxhbmNlQQgFDSR0MDE2NTA3MTY4MzICXzEEC25ld0JhbGFuY2VCCAUNJHQwMTY1MDcxNjgzMgJfMgQLYXNzZXRJZFNlbmQIBQ0kdDAxNjUwNzE2ODMyAl8zBA0kdDAxNjg1MDE3MTAwAwkAAAIFCnBtdEFzc2V0SWQFCGFzc2V0SWRBCQCUCgIFCXBtdEFtb3VudAkAZAIFDWFtb3VudFdpdGhGZWUFEGdvdmVybmFuY2VSZXdhcmQJAJQKAgkAZAIFDWFtb3VudFdpdGhGZWUFEGdvdmVybmFuY2VSZXdhcmQFCXBtdEFtb3VudAQMc3Rha2VBbW91bnRBCAUNJHQwMTY4NTAxNzEwMAJfMQQMc3Rha2VBbW91bnRCCAUNJHQwMTY4NTAxNzEwMAJfMgQGc3Rha2UxAwkBCGNvbnRhaW5zAgUNc3Rha2luZ0Fzc2V0cwULc3RyQXNzZXRJZEEJAPwHBAgFAWkGY2FsbGVyAgxzdGFrZVVuc3Rha2UJAMwIAgkAAAIFCnBtdEFzc2V0SWQFCGFzc2V0SWRBCQDMCAIFDHN0YWtlQW1vdW50QQkAzAgCBQtzdHJBc3NldElkQQUDbmlsBQNuaWwAAAMJAAACBQZzdGFrZTEFBnN0YWtlMQQGc3Rha2UyAwkBCGNvbnRhaW5zAgUNc3Rha2luZ0Fzc2V0cwULc3RyQXNzZXRJZEIJAPwHBAgFAWkGY2FsbGVyAgxzdGFrZVVuc3Rha2UJAMwIAgkAAAIFCnBtdEFzc2V0SWQFCGFzc2V0SWRCCQDMCAIFDHN0YWtlQW1vdW50QgkAzAgCBQtzdHJBc3NldElkQgUDbmlsBQNuaWwAAAMJAAACBQZzdGFrZTIFBnN0YWtlMgkAlAoCBQNuaWwJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUJa0JhbGFuY2VBBQtuZXdCYWxhbmNlQQkAzAgCCQEMSW50ZWdlckVudHJ5AgUJa0JhbGFuY2VCBQtuZXdCYWxhbmNlQgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQZjYWxsZXIFDWFtb3VudFdpdGhGZWUFC2Fzc2V0SWRTZW5kCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFD21vbmV5Qm94QWRkcmVzcwUQZ292ZXJuYW5jZVJld2FyZAULYXNzZXRJZFNlbmQFA25pbAkAzAgCBQ1hbW91bnRXaXRoRmVlCQDMCAIFC2Fzc2V0SWRTZW5kBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEWcmVwbGVuaXNoV2l0aFR3b1Rva2VucwQLY2FsbGVyQnl0ZXMEYXJncwhwQW1vdW50cwlwQXNzZXRJZHMJAQt2YWx1ZU9yRWxzZQIJAQxpc09yYWNsZVBvb2wBCQClCAEIBQFpBmNhbGxlcgkBC3ZhbHVlT3JFbHNlAgkBCGlzQWN0aXZlAAQGY2FsbGVyCQEHQWRkcmVzcwEFC2NhbGxlckJ5dGVzBAtwbXRBc3NldElkQQkBEXBhcnNlUGF5bWVudEFzc2V0AQkAkQMCBQlwQXNzZXRJZHMAAAQLcG10QXNzZXRJZEIJARFwYXJzZVBheW1lbnRBc3NldAEJAJEDAgUJcEFzc2V0SWRzAAEEDHN0YWtlRmFybWluZwkAAAIJAJEDAgUEYXJncwAAAgR0cnVlBA0kdDAxODMxMjE4NDAyCQENZ2V0UG9vbEFzc2V0cwEIBQFpBmNhbGxlcgQLc3RyQXNzZXRJZEEIBQ0kdDAxODMxMjE4NDAyAl8xBAtzdHJBc3NldElkQggFDSR0MDE4MzEyMTg0MDICXzIECGFzc2V0SWRBCAUNJHQwMTgzMTIxODQwMgJfMwQIYXNzZXRJZEIIBQ0kdDAxODMxMjE4NDAyAl80BAxzaGFyZUFzc2V0SWQIBQ0kdDAxODMxMjE4NDAyAl81BA0kdDAxODQxNTE4NTM5CQEPZ2V0UG9vbEJhbGFuY2VzAwgFAWkGY2FsbGVyBQhhc3NldElkQQUIYXNzZXRJZEIECGJhbGFuY2VBCAUNJHQwMTg0MTUxODUzOQJfMQQIYmFsYW5jZUIIBQ0kdDAxODQxNTE4NTM5Al8yBA9hY2NvdW50QmFsYW5jZUEIBQ0kdDAxODQxNTE4NTM5Al8zBA9hY2NvdW50QmFsYW5jZUIIBQ0kdDAxODQxNTE4NTM5Al80BBBzaGFyZUFzc2V0U3VwcGx5CAUNJHQwMTg0MTUxODUzOQJfNQMJAQIhPQIJAJADAQUIcEFtb3VudHMAAgkAAgECHFR3byBhdHRhY2hlZCBhc3NldHMgZXhwZWN0ZWQDAwkBAiE9AgULcG10QXNzZXRJZEEFCGFzc2V0SWRBBgkBAiE9AgULcG10QXNzZXRJZEIFCGFzc2V0SWRCCQACAQkArAICCQCsAgIJAKwCAgIlSW5jb3JyZWN0IGFzc2V0cyBhdHRhY2hlZC4gRXhwZWN0ZWQ6IAULc3RyQXNzZXRJZEECBSBhbmQgBQtzdHJBc3NldElkQgMDCQBmAgUIYmFsYW5jZUEFD2FjY291bnRCYWxhbmNlQQYJAGYCBQhiYWxhbmNlQgUPYWNjb3VudEJhbGFuY2VCCQCUCgIFA25pbAkAzggCCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFBmNhbGxlcgkAkQMCBQhwQW1vdW50cwAABQtwbXRBc3NldElkQQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQZjYWxsZXIJAJEDAgUIcEFtb3VudHMAAQULcG10QXNzZXRJZEIFA25pbAkBEXN1c3BlbmRTdXNwaWNpb3VzBgUPYWNjb3VudEJhbGFuY2VBBQ9hY2NvdW50QmFsYW5jZUIFCGJhbGFuY2VBBQhiYWxhbmNlQgULc3RyQXNzZXRJZEEFC3N0ckFzc2V0SWRCBA0kdDAxOTIxMTE5Mjg4CQEMZ2V0QXNzZXRJbmZvAQULcG10QXNzZXRJZEEEDnBtdFN0ckFzc2V0SWRBCAUNJHQwMTkyMTExOTI4OAJfMQQNcG10QXNzZXROYW1lQQgFDSR0MDE5MjExMTkyODgCXzIEDHBtdERlY2ltYWxzQQgFDSR0MDE5MjExMTkyODgCXzMEDSR0MDE5MzA1MTkzODIJAQxnZXRBc3NldEluZm8BBQtwbXRBc3NldElkQgQOcG10U3RyQXNzZXRJZEIIBQ0kdDAxOTMwNTE5MzgyAl8xBA1wbXRBc3NldE5hbWVCCAUNJHQwMTkzMDUxOTM4MgJfMgQMcG10RGVjaW1hbHNCCAUNJHQwMTkzMDUxOTM4MgJfMwQHaW5pdGlhbAkAAAIJAGQCBQhiYWxhbmNlQQUIYmFsYW5jZUIAAAQNJHQwMTk0NTcyMDMwMAMFB2luaXRpYWwJAJcKBQkAkQMCBQhwQW1vdW50cwAACQCRAwIFCHBBbW91bnRzAAEAAAULcG10QXNzZXRJZEEAAQQTcmF0aW9TaGFyZVRva2Vuc0luQQkAawMFBnNjYWxlOAkAkQMCBQhwQW1vdW50cwAABQhiYWxhbmNlQQQTcmF0aW9TaGFyZVRva2Vuc0luQgkAawMFBnNjYWxlOAkAkQMCBQhwQW1vdW50cwABBQhiYWxhbmNlQgMJAGYCBRNyYXRpb1NoYXJlVG9rZW5zSW5CBRNyYXRpb1NoYXJlVG9rZW5zSW5BBANwbXQJAGsDCQCRAwIFCHBBbW91bnRzAAAFCGJhbGFuY2VCBQhiYWxhbmNlQQkAlwoFCQCRAwIFCHBBbW91bnRzAAAFA3BtdAkAZQIJAJEDAgUIcEFtb3VudHMAAQUDcG10BQtwbXRBc3NldElkQgUTcmF0aW9TaGFyZVRva2Vuc0luQQQDcG10CQBrAwkAkQMCBQhwQW1vdW50cwABBQhiYWxhbmNlQQUIYmFsYW5jZUIJAJcKBQUDcG10CQCRAwIFCHBBbW91bnRzAAEJAGUCCQCRAwIFCHBBbW91bnRzAAAFA3BtdAULcG10QXNzZXRJZEEFE3JhdGlvU2hhcmVUb2tlbnNJbkIECnBtdEFtb3VudEEIBQ0kdDAxOTQ1NzIwMzAwAl8xBApwbXRBbW91bnRCCAUNJHQwMTk0NTcyMDMwMAJfMgQGY2hhbmdlCAUNJHQwMTk0NTcyMDMwMAJfMwQNY2hhbmdlQXNzZXRJZAgFDSR0MDE5NDU3MjAzMDACXzQED3NoYXJlVG9rZW5SYXRpbwgFDSR0MDE5NDU3MjAzMDACXzUEFXNoYXJlVG9rZW5Ub1BheUFtb3VudAMFB2luaXRpYWwEDXNoYXJlRGVjaW1hbHMJAGkCCQBkAgUMcG10RGVjaW1hbHNBBQxwbXREZWNpbWFsc0IAAgkAawMJAGwGBQpwbXRBbW91bnRBBQxwbXREZWNpbWFsc0EABQABBQxwbXREZWNpbWFsc0EFBERPV04JAGwGBQpwbXRBbW91bnRCBQxwbXREZWNpbWFsc0IABQABBQxwbXREZWNpbWFsc0IFBERPV04JAGwGAAoAAAUNc2hhcmVEZWNpbWFscwAAAAAFBERPV04JAGsDBQ9zaGFyZVRva2VuUmF0aW8FEHNoYXJlQXNzZXRTdXBwbHkFBnNjYWxlOAMJAAACBRVzaGFyZVRva2VuVG9QYXlBbW91bnQAAAkAAgECHVRvbyBzbWFsbCBhbW91bnQgdG8gcmVwbGVuaXNoAwkAZgIAAAUGY2hhbmdlCQACAQIKQ2hhbmdlIDwgMAQGc3Rha2UxAwkBCGNvbnRhaW5zAgUNc3Rha2luZ0Fzc2V0cwUOcG10U3RyQXNzZXRJZEEJAPwHBAgFAWkGY2FsbGVyAgxzdGFrZVVuc3Rha2UJAMwIAgYJAMwIAgUKcG10QW1vdW50QQkAzAgCBQ5wbXRTdHJBc3NldElkQQUDbmlsBQNuaWwAAAMJAAACBQZzdGFrZTEFBnN0YWtlMQQGc3Rha2UyAwkBCGNvbnRhaW5zAgUNc3Rha2luZ0Fzc2V0cwUOcG10U3RyQXNzZXRJZEIJAPwHBAgFAWkGY2FsbGVyAgxzdGFrZVVuc3Rha2UJAMwIAgYJAMwIAgUKcG10QW1vdW50QgkAzAgCBQ5wbXRTdHJBc3NldElkQgUDbmlsBQNuaWwAAAMJAAACBQZzdGFrZTIFBnN0YWtlMgQMc2hhcmVUb2tlblNUAwUMc3Rha2VGYXJtaW5nBAdyZWlzc3VlCQD8BwQIBQFpBmNhbGxlcgIRcmVpc3N1ZVNoYXJlVG9rZW4JAMwIAgUVc2hhcmVUb2tlblRvUGF5QW1vdW50BQNuaWwFA25pbAMJAAACBQdyZWlzc3VlBQdyZWlzc3VlBAZzdGFrZTMJAPwHBAUOZmFybWluZ0FkZHJlc3MCD2xvY2tTaGFyZVRva2VucwkAzAgCCQClCAEIBQFpBmNhbGxlcgUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQxzaGFyZUFzc2V0SWQFFXNoYXJlVG9rZW5Ub1BheUFtb3VudAUDbmlsAwkAAAIFBnN0YWtlMwUGc3Rha2UzBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAMwIAgkBB1JlaXNzdWUDBQxzaGFyZUFzc2V0SWQFFXNoYXJlVG9rZW5Ub1BheUFtb3VudAYJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUGY2FsbGVyBRVzaGFyZVRva2VuVG9QYXlBbW91bnQFDHNoYXJlQXNzZXRJZAUDbmlsCQCUCgIFA25pbAkAlAoCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIFCWtCYWxhbmNlQQkAZAIFCGJhbGFuY2VBBQpwbXRBbW91bnRBCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQlrQmFsYW5jZUIJAGQCBQhiYWxhbmNlQgUKcG10QW1vdW50QgkAzAgCCQEMSW50ZWdlckVudHJ5AgURa1NoYXJlQXNzZXRTdXBwbHkJAGQCBRBzaGFyZUFzc2V0U3VwcGx5BRVzaGFyZVRva2VuVG9QYXlBbW91bnQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUGY2FsbGVyBQZjaGFuZ2UFDWNoYW5nZUFzc2V0SWQFA25pbAUMc2hhcmVUb2tlblNUBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEVcmVwbGVuaXNoV2l0aE9uZVRva2VuBAtjYWxsZXJCeXRlcwRhcmdzCHBBbW91bnRzCXBBc3NldElkcwkBC3ZhbHVlT3JFbHNlAgkBDGlzT3JhY2xlUG9vbAEJAKUIAQgFAWkGY2FsbGVyCQELdmFsdWVPckVsc2UCCQEIaXNBY3RpdmUABAZjYWxsZXIJAQdBZGRyZXNzAQULY2FsbGVyQnl0ZXMECnBtdEFzc2V0SWQJARFwYXJzZVBheW1lbnRBc3NldAEJAJEDAgUJcEFzc2V0SWRzAAAECXBtdEFtb3VudAkAkQMCBQhwQW1vdW50cwAABBB2aXJ0R2V0TWluQW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEYXJncwAABAxzdGFrZUZhcm1pbmcJAAACCQCRAwIFBGFyZ3MAAQIEdHJ1ZQQNJHQwMjI4NTUyMjk0NQkBDWdldFBvb2xBc3NldHMBCAUBaQZjYWxsZXIEC3N0ckFzc2V0SWRBCAUNJHQwMjI4NTUyMjk0NQJfMQQLc3RyQXNzZXRJZEIIBQ0kdDAyMjg1NTIyOTQ1Al8yBAhhc3NldElkQQgFDSR0MDIyODU1MjI5NDUCXzMECGFzc2V0SWRCCAUNJHQwMjI4NTUyMjk0NQJfNAQMc2hhcmVBc3NldElkCAUNJHQwMjI4NTUyMjk0NQJfNQQNJHQwMjI5NTgyMzA4MgkBD2dldFBvb2xCYWxhbmNlcwMIBQFpBmNhbGxlcgUIYXNzZXRJZEEFCGFzc2V0SWRCBAhiYWxhbmNlQQgFDSR0MDIyOTU4MjMwODICXzEECGJhbGFuY2VCCAUNJHQwMjI5NTgyMzA4MgJfMgQPYWNjb3VudEJhbGFuY2VBCAUNJHQwMjI5NTgyMzA4MgJfMwQPYWNjb3VudEJhbGFuY2VCCAUNJHQwMjI5NTgyMzA4MgJfNAQQc2hhcmVBc3NldFN1cHBseQgFDSR0MDIyOTU4MjMwODICXzUEB2luaXRpYWwJAAACCQBkAgUIYmFsYW5jZUEFCGJhbGFuY2VCAAADCQECIT0CCQCQAwEFCHBBbW91bnRzAAEJAAIBAhxPbmUgYXR0YWNoZWQgYXNzZXRzIGV4cGVjdGVkAwMJAQIhPQIFCnBtdEFzc2V0SWQFCGFzc2V0SWRBCQECIT0CBQpwbXRBc3NldElkBQhhc3NldElkQgcJAAIBCQCsAgIJAKwCAgkArAICAiRJbmNvcnJlY3QgYXNzZXQgYXR0YWNoZWQuIEV4cGVjdGVkOiAFC3N0ckFzc2V0SWRBAgQgb3IgBQtzdHJBc3NldElkQgMFB2luaXRpYWwJAAIBAjBGb3IgaW5pdGlhbCBleGNoYW5nZXIgeW91IG5lZWQgdG8gdXNlIHR3byB0b2tlbnMDAwkAZgIFCGJhbGFuY2VBBQ9hY2NvdW50QmFsYW5jZUEGCQBmAgUIYmFsYW5jZUIFD2FjY291bnRCYWxhbmNlQgkAlAoCBQNuaWwJAM4IAgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQZjYWxsZXIFCXBtdEFtb3VudAUKcG10QXNzZXRJZAUDbmlsCQERc3VzcGVuZFN1c3BpY2lvdXMGBQ9hY2NvdW50QmFsYW5jZUEFD2FjY291bnRCYWxhbmNlQgUIYmFsYW5jZUEFCGJhbGFuY2VCBQtzdHJBc3NldElkQQULc3RyQXNzZXRJZEIEDSR0MDIzODM2MjM4OTQJAQxnZXRGZWVQYXJhbXMCCAUBaQZjYWxsZXIIBQFpDG9yaWdpbkNhbGxlcgQDZmVlCAUNJHQwMjM4MzYyMzg5NAJfMQQGZ292RmVlCAUNJHQwMjM4MzYyMzg5NAJfMgQNJHQwMjM5MTEyNTc5NwMJAAACBQpwbXRBc3NldElkBQhhc3NldElkQQQNdmlydFBheUFtb3VudAkBEGNhbGN1bGF0ZVZpcnRHZXQDBQlwbXRBbW91bnQFCGJhbGFuY2VBBQNmZWUEDSR0MDI0MTkwMjQzMjcJAQ1jYWxjdWxhdGVGZWVzBgUNdmlydFBheUFtb3VudAUQdmlydEdldE1pbkFtb3VudAUIYmFsYW5jZUEFCGJhbGFuY2VCBQNmZWUFBmdvdkZlZQQQYW1vdW50V2l0aG91dEZlZQgFDSR0MDI0MTkwMjQzMjcCXzEEDWFtb3VudFdpdGhGZWUIBQ0kdDAyNDE5MDI0MzI3Al8yBBBnb3Zlcm5hbmNlUmV3YXJkCAUNJHQwMjQxOTAyNDMyNwJfMwQLbmV3QmFsYW5jZUEJAGQCBQhiYWxhbmNlQQUJcG10QW1vdW50BAtuZXdCYWxhbmNlQgkAZQIFCGJhbGFuY2VCBRBnb3Zlcm5hbmNlUmV3YXJkBBNyYXRpb1NoYXJlVG9rZW5zSW5BCQBrAwkAZQIFCXBtdEFtb3VudAUNdmlydFBheUFtb3VudAUGc2NhbGU4BQtuZXdCYWxhbmNlQQQTcmF0aW9TaGFyZVRva2Vuc0luQgkAawMFDWFtb3VudFdpdGhGZWUFBnNjYWxlOAULbmV3QmFsYW5jZUIEFXNoYXJlVG9rZW5Ub1BheUFtb3VudAkAawMJAJcDAQkAzAgCBRNyYXRpb1NoYXJlVG9rZW5zSW5BCQDMCAIFE3JhdGlvU2hhcmVUb2tlbnNJbkIFA25pbAUQc2hhcmVBc3NldFN1cHBseQUGc2NhbGU4CQCZCgcFC25ld0JhbGFuY2VBBQtuZXdCYWxhbmNlQgUVc2hhcmVUb2tlblRvUGF5QW1vdW50BRBnb3Zlcm5hbmNlUmV3YXJkBQhhc3NldElkQgULc3RyQXNzZXRJZEIFC3N0ckFzc2V0SWRBBA12aXJ0UGF5QW1vdW50CQEQY2FsY3VsYXRlVmlydEdldAMFCXBtdEFtb3VudAUIYmFsYW5jZUIFA2ZlZQQNJHQwMjUwNjIyNTE5OQkBDWNhbGN1bGF0ZUZlZXMGBQ12aXJ0UGF5QW1vdW50BRB2aXJ0R2V0TWluQW1vdW50BQhiYWxhbmNlQgUIYmFsYW5jZUEFA2ZlZQUGZ292RmVlBBBhbW91bnRXaXRob3V0RmVlCAUNJHQwMjUwNjIyNTE5OQJfMQQNYW1vdW50V2l0aEZlZQgFDSR0MDI1MDYyMjUxOTkCXzIEEGdvdmVybmFuY2VSZXdhcmQIBQ0kdDAyNTA2MjI1MTk5Al8zBAtuZXdCYWxhbmNlQQkAZQIFCGJhbGFuY2VBBRBnb3Zlcm5hbmNlUmV3YXJkBAtuZXdCYWxhbmNlQgkAZAIFCGJhbGFuY2VCBQlwbXRBbW91bnQEE3JhdGlvU2hhcmVUb2tlbnNJbkEJAGsDBQ1hbW91bnRXaXRoRmVlBQZzY2FsZTgFC25ld0JhbGFuY2VBBBNyYXRpb1NoYXJlVG9rZW5zSW5CCQBrAwkAZQIFCXBtdEFtb3VudAUNdmlydFBheUFtb3VudAUGc2NhbGU4BQtuZXdCYWxhbmNlQgQVc2hhcmVUb2tlblRvUGF5QW1vdW50CQBrAwkAlwMBCQDMCAIFE3JhdGlvU2hhcmVUb2tlbnNJbkEJAMwIAgUTcmF0aW9TaGFyZVRva2Vuc0luQgUDbmlsBRBzaGFyZUFzc2V0U3VwcGx5BQZzY2FsZTgJAJkKBwULbmV3QmFsYW5jZUEFC25ld0JhbGFuY2VCBRVzaGFyZVRva2VuVG9QYXlBbW91bnQFEGdvdmVybmFuY2VSZXdhcmQFCGFzc2V0SWRBBQtzdHJBc3NldElkQQULc3RyQXNzZXRJZEIEC25ld0JhbGFuY2VBCAUNJHQwMjM5MTEyNTc5NwJfMQQLbmV3QmFsYW5jZUIIBQ0kdDAyMzkxMTI1Nzk3Al8yBBVzaGFyZVRva2VuVG9QYXlBbW91bnQIBQ0kdDAyMzkxMTI1Nzk3Al8zBAlnb3ZSZXdhcmQIBQ0kdDAyMzkxMTI1Nzk3Al80BA5nb3ZSZXdhcmRBc3NldAgFDSR0MDIzOTExMjU3OTcCXzUEEWdvdlJld2FyZEFzc2V0U3RyCAUNJHQwMjM5MTEyNTc5NwJfNgQNcG10QXNzZXRJZFN0cggFDSR0MDIzOTExMjU3OTcCXzcDCQAAAgUVc2hhcmVUb2tlblRvUGF5QW1vdW50AAAJAAIBAh1Ub28gc21hbGwgYW1vdW50IHRvIHJlcGxlbmlzaAQGc3Rha2UxAwkBCGNvbnRhaW5zAgUNc3Rha2luZ0Fzc2V0cwUNcG10QXNzZXRJZFN0cgkA/AcECAUBaQZjYWxsZXICDHN0YWtlVW5zdGFrZQkAzAgCBgkAzAgCBQlwbXRBbW91bnQJAMwIAgUNcG10QXNzZXRJZFN0cgUDbmlsBQNuaWwAAAMJAAACBQZzdGFrZTEFBnN0YWtlMQQGc3Rha2UyAwkBCGNvbnRhaW5zAgUNc3Rha2luZ0Fzc2V0cwURZ292UmV3YXJkQXNzZXRTdHIJAPwHBAgFAWkGY2FsbGVyAgxzdGFrZVVuc3Rha2UJAMwIAgcJAMwIAgUJZ292UmV3YXJkCQDMCAIFEWdvdlJld2FyZEFzc2V0U3RyBQNuaWwFA25pbAAAAwkAAAIFBnN0YWtlMgUGc3Rha2UyBAxzaGFyZVRva2VuU1QDBQxzdGFrZUZhcm1pbmcEB3JlaXNzdWUJAPwHBAgFAWkGY2FsbGVyAhFyZWlzc3VlU2hhcmVUb2tlbgkAzAgCBRVzaGFyZVRva2VuVG9QYXlBbW91bnQFA25pbAUDbmlsAwkAAAIFB3JlaXNzdWUFB3JlaXNzdWUEBnN0YWtlMwkA/AcEBQ5mYXJtaW5nQWRkcmVzcwIPbG9ja1NoYXJlVG9rZW5zCQDMCAIJAKUIAQgFAWkGY2FsbGVyBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFDHNoYXJlQXNzZXRJZAUVc2hhcmVUb2tlblRvUGF5QW1vdW50BQNuaWwDCQAAAgUGc3Rha2UzBQZzdGFrZTMFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAzAgCCQEHUmVpc3N1ZQMFDHNoYXJlQXNzZXRJZAUVc2hhcmVUb2tlblRvUGF5QW1vdW50BgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQZjYWxsZXIFFXNoYXJlVG9rZW5Ub1BheUFtb3VudAUMc2hhcmVBc3NldElkBQNuaWwJAJQKAgUDbmlsCQCUCgIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUJa0JhbGFuY2VBBQtuZXdCYWxhbmNlQQkAzAgCCQEMSW50ZWdlckVudHJ5AgUJa0JhbGFuY2VCBQtuZXdCYWxhbmNlQgkAzAgCCQEMSW50ZWdlckVudHJ5AgURa1NoYXJlQXNzZXRTdXBwbHkJAGQCBRBzaGFyZUFzc2V0U3VwcGx5BRVzaGFyZVRva2VuVG9QYXlBbW91bnQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUPbW9uZXlCb3hBZGRyZXNzBQlnb3ZSZXdhcmQFDmdvdlJld2FyZEFzc2V0BQNuaWwFDHNoYXJlVG9rZW5TVAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCHdpdGhkcmF3BAtjYWxsZXJCeXRlcwRhcmdzCHBBbW91bnRzCXBBc3NldElkcwkBC3ZhbHVlT3JFbHNlAgkBDGlzT3JhY2xlUG9vbAEJAKUIAQgFAWkGY2FsbGVyCQELdmFsdWVPckVsc2UCCQEIaXNBY3RpdmUABAZjYWxsZXIJAQdBZGRyZXNzAQULY2FsbGVyQnl0ZXMEDSR0MDI3NjA5Mjc2OTkJAQ1nZXRQb29sQXNzZXRzAQgFAWkGY2FsbGVyBAtzdHJBc3NldElkQQgFDSR0MDI3NjA5Mjc2OTkCXzEEC3N0ckFzc2V0SWRCCAUNJHQwMjc2MDkyNzY5OQJfMgQIYXNzZXRJZEEIBQ0kdDAyNzYwOTI3Njk5Al8zBAhhc3NldElkQggFDSR0MDI3NjA5Mjc2OTkCXzQEDHNoYXJlQXNzZXRJZAgFDSR0MDI3NjA5Mjc2OTkCXzUEDSR0MDI3NzEyMjc4MzYJAQ9nZXRQb29sQmFsYW5jZXMDCAUBaQZjYWxsZXIFCGFzc2V0SWRBBQhhc3NldElkQgQIYmFsYW5jZUEIBQ0kdDAyNzcxMjI3ODM2Al8xBAhiYWxhbmNlQggFDSR0MDI3NzEyMjc4MzYCXzIED2FjY291bnRCYWxhbmNlQQgFDSR0MDI3NzEyMjc4MzYCXzMED2FjY291bnRCYWxhbmNlQggFDSR0MDI3NzEyMjc4MzYCXzQEEHNoYXJlQXNzZXRTdXBwbHkIBQ0kdDAyNzcxMjI3ODM2Al81BA0kdDAyNzg0OTI4MjU3AwkAAAIJAJADAQUIcEFtb3VudHMAAQQGcEFzc2V0CQERcGFyc2VQYXltZW50QXNzZXQBCQCRAwIFCXBBc3NldElkcwAAAwkBAiE9AgUGcEFzc2V0BQxzaGFyZUFzc2V0SWQJAAIBCQCsAgICJEluY29ycmVjdCBhc3NldCBhdHRhY2hlZC4gRXhwZWN0ZWQ6IAkA2AQBBQxzaGFyZUFzc2V0SWQJAJQKAgkAkQMCBQhwQW1vdW50cwAABQZwQXNzZXQJAJQKAgAABQxzaGFyZUFzc2V0SWQECXBtdEFtb3VudAgFDSR0MDI3ODQ5MjgyNTcCXzEECnBtdEFzc2V0SWQIBQ0kdDAyNzg0OTI4MjU3Al8yAwkAZgIJAJADAQUIcEFtb3VudHMAAQkAAgECHU9uZSBhdHRhY2hlZCBwYXltZW50IGV4cGVjdGVkAwMJAGYCBQhiYWxhbmNlQQUPYWNjb3VudEJhbGFuY2VBBgkAZgIFCGJhbGFuY2VCBQ9hY2NvdW50QmFsYW5jZUIJAJQKAgUDbmlsCQDOCAIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUGY2FsbGVyBQlwbXRBbW91bnQFCnBtdEFzc2V0SWQFA25pbAkBEXN1c3BlbmRTdXNwaWNpb3VzBgUPYWNjb3VudEJhbGFuY2VBBQ9hY2NvdW50QmFsYW5jZUIFCGJhbGFuY2VBBQhiYWxhbmNlQgULc3RyQXNzZXRJZEEFC3N0ckFzc2V0SWRCBAx1bmxvY2tBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkBC3ZhbHVlT3JFbHNlAgkAkQMCBQRhcmdzAAACATAEBnVubG9jawMJAGYCBQx1bmxvY2tBbW91bnQAAAkA/AcEBQ5mYXJtaW5nQWRkcmVzcwITd2l0aGRyYXdTaGFyZVRva2VucwkAzAgCCQClCAEIBQFpBmNhbGxlcgkAzAgCBQx1bmxvY2tBbW91bnQFA25pbAUDbmlsAAADCQAAAgUGdW5sb2NrBQZ1bmxvY2sEDndpdGhkcmF3QW1vdW50CQBkAgUJcG10QW1vdW50BQx1bmxvY2tBbW91bnQEDGFtb3VudFRvUGF5QQkAawMFDndpdGhkcmF3QW1vdW50BQhiYWxhbmNlQQUQc2hhcmVBc3NldFN1cHBseQQMYW1vdW50VG9QYXlCCQBrAwUOd2l0aGRyYXdBbW91bnQFCGJhbGFuY2VCBRBzaGFyZUFzc2V0U3VwcGx5BAZzdGFrZTEDCQEIY29udGFpbnMCBQ1zdGFraW5nQXNzZXRzBQtzdHJBc3NldElkQQkA/AcECAUBaQZjYWxsZXICDHN0YWtlVW5zdGFrZQkAzAgCBwkAzAgCBQxhbW91bnRUb1BheUEJAMwIAgULc3RyQXNzZXRJZEEFA25pbAUDbmlsAAADCQAAAgUGc3Rha2UxBQZzdGFrZTEEBnN0YWtlMgMJAQhjb250YWlucwIFDXN0YWtpbmdBc3NldHMFC3N0ckFzc2V0SWRCCQD8BwQIBQFpBmNhbGxlcgIMc3Rha2VVbnN0YWtlCQDMCAIHCQDMCAIFDGFtb3VudFRvUGF5QgkAzAgCBQtzdHJBc3NldElkQgUDbmlsBQNuaWwAAAMJAAACBQZzdGFrZTIFBnN0YWtlMgkAlAoCCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgUMdW5sb2NrQW1vdW50BQxzaGFyZUFzc2V0SWQFA25pbAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQlrQmFsYW5jZUEJAGUCBQhiYWxhbmNlQQUMYW1vdW50VG9QYXlBCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQlrQmFsYW5jZUIJAGUCBQhiYWxhbmNlQgUMYW1vdW50VG9QYXlCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRFrU2hhcmVBc3NldFN1cHBseQkAZQIFEHNoYXJlQXNzZXRTdXBwbHkFDndpdGhkcmF3QW1vdW50CQDMCAIJAQRCdXJuAgUMc2hhcmVBc3NldElkBQ53aXRoZHJhd0Ftb3VudAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQZjYWxsZXIFDGFtb3VudFRvUGF5QQUIYXNzZXRJZEEJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUGY2FsbGVyBQxhbW91bnRUb1BheUIFCGFzc2V0SWRCBQNuaWwFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARB3aXRoZHJhd09uZVRva2VuBAtjYWxsZXJCeXRlcwRhcmdzCHBBbW91bnRzCXBBc3NldElkcwkBC3ZhbHVlT3JFbHNlAgkBDGlzT3JhY2xlUG9vbAEJAKUIAQgFAWkGY2FsbGVyCQELdmFsdWVPckVsc2UCCQEIaXNBY3RpdmUABAZjYWxsZXIJAQdBZGRyZXNzAQULY2FsbGVyQnl0ZXMEDXdpdGhkcmF3QXNzZXQDCQAAAgkAkQMCBQRhcmdzAAACAAUEdW5pdAkA2QQBCQCRAwIFBGFyZ3MAAAQNJHQwMzA0NjUzMDU1NQkBDWdldFBvb2xBc3NldHMBCAUBaQZjYWxsZXIEC3N0ckFzc2V0SWRBCAUNJHQwMzA0NjUzMDU1NQJfMQQLc3RyQXNzZXRJZEIIBQ0kdDAzMDQ2NTMwNTU1Al8yBAhhc3NldElkQQgFDSR0MDMwNDY1MzA1NTUCXzMECGFzc2V0SWRCCAUNJHQwMzA0NjUzMDU1NQJfNAQMc2hhcmVBc3NldElkCAUNJHQwMzA0NjUzMDU1NQJfNQQNJHQwMzA1NjgzMDY5MgkBD2dldFBvb2xCYWxhbmNlcwMIBQFpBmNhbGxlcgUIYXNzZXRJZEEFCGFzc2V0SWRCBAhiYWxhbmNlQQgFDSR0MDMwNTY4MzA2OTICXzEECGJhbGFuY2VCCAUNJHQwMzA1NjgzMDY5MgJfMgQPYWNjb3VudEJhbGFuY2VBCAUNJHQwMzA1NjgzMDY5MgJfMwQPYWNjb3VudEJhbGFuY2VCCAUNJHQwMzA1NjgzMDY5MgJfNAQQc2hhcmVBc3NldFN1cHBseQgFDSR0MDMwNTY4MzA2OTICXzUEDSR0MDMwNzA1MzEwODUDCQAAAgkAkAMBBQhwQW1vdW50cwABBAZwQXNzZXQJARFwYXJzZVBheW1lbnRBc3NldAEJAJEDAgUJcEFzc2V0SWRzAAADCQECIT0CBQZwQXNzZXQFDHNoYXJlQXNzZXRJZAkAAgEJAKwCAgIkSW5jb3JyZWN0IGFzc2V0IGF0dGFjaGVkLiBFeHBlY3RlZDogCQDYBAEFDHNoYXJlQXNzZXRJZAkAlAoCCQCRAwIFCHBBbW91bnRzAAAFBnBBc3NldAkAlAoCAAAFDHNoYXJlQXNzZXRJZAQJcG10QW1vdW50CAUNJHQwMzA3MDUzMTA4NQJfMQQKcG10QXNzZXRJZAgFDSR0MDMwNzA1MzEwODUCXzIED3ZpcnRNaW5Ub1JlY2l2ZQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGFyZ3MAAQMJAQIhPQIJAJADAQUIcEFtb3VudHMAAQkAAgECHU9uZSBhdHRhY2hlZCBwYXltZW50IGV4cGVjdGVkAwkBAiE9AgUKcG10QXNzZXRJZAUMc2hhcmVBc3NldElkCQACAQkArAICAiRJbmNvcnJlY3QgYXNzZXQgYXR0YWNoZWQuIEV4cGVjdGVkOiAJANgEAQUMc2hhcmVBc3NldElkAwkBASEBCQEPY29udGFpbnNFbGVtZW50AgkAzAgCBQhhc3NldElkQQkAzAgCBQhhc3NldElkQgUDbmlsBQ13aXRoZHJhd0Fzc2V0CQACAQIZSW5jb3JyZWN0IHdpdGhkcmF3IGFzc2V0LgMDCQBmAgUIYmFsYW5jZUEFD2FjY291bnRCYWxhbmNlQQYJAGYCBQhiYWxhbmNlQgUPYWNjb3VudEJhbGFuY2VCCQCUCgIFA25pbAkAzggCCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFBmNhbGxlcgUJcG10QW1vdW50BQpwbXRBc3NldElkBQNuaWwJARFzdXNwZW5kU3VzcGljaW91cwYFD2FjY291bnRCYWxhbmNlQQUPYWNjb3VudEJhbGFuY2VCBQhiYWxhbmNlQQUIYmFsYW5jZUIFC3N0ckFzc2V0SWRBBQtzdHJBc3NldElkQgQMdW5sb2NrQW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAQt2YWx1ZU9yRWxzZQIJAJEDAgUEYXJncwACAgEwBAZ1bmxvY2sDCQBmAgUMdW5sb2NrQW1vdW50AAAJAPwHBAUOZmFybWluZ0FkZHJlc3MCE3dpdGhkcmF3U2hhcmVUb2tlbnMJAMwIAgkApQgBCAUBaQZjYWxsZXIJAMwIAgUMdW5sb2NrQW1vdW50BQNuaWwFA25pbAAAAwkAAAIFBnVubG9jawUGdW5sb2NrBA53aXRoZHJhd0Ftb3VudAkAZAIFCXBtdEFtb3VudAUMdW5sb2NrQW1vdW50BAxhbW91bnRUb1BheUEJAGsDBQ53aXRoZHJhd0Ftb3VudAUIYmFsYW5jZUEFEHNoYXJlQXNzZXRTdXBwbHkEDGFtb3VudFRvUGF5QgkAawMFDndpdGhkcmF3QW1vdW50BQhiYWxhbmNlQgUQc2hhcmVBc3NldFN1cHBseQQNJHQwMzIzMzAzMjM4OAkBDGdldEZlZVBhcmFtcwIIBQFpBmNhbGxlcggFAWkMb3JpZ2luQ2FsbGVyBANmZWUIBQ0kdDAzMjMzMDMyMzg4Al8xBAZnb3ZGZWUIBQ0kdDAzMjMzMDMyMzg4Al8yBA0kdDAzMjQwNTMyNzQ1AwkAAAIFDXdpdGhkcmF3QXNzZXQFCGFzc2V0SWRBCQENY2FsY3VsYXRlRmVlcwYFDGFtb3VudFRvUGF5QgUPdmlydE1pblRvUmVjaXZlBQhiYWxhbmNlQgUIYmFsYW5jZUEFA2ZlZQUGZ292RmVlCQENY2FsY3VsYXRlRmVlcwYFDGFtb3VudFRvUGF5QQUPdmlydE1pblRvUmVjaXZlBQhiYWxhbmNlQQUIYmFsYW5jZUIFA2ZlZQUGZ292RmVlBBBhbW91bnRXaXRob3V0RmVlCAUNJHQwMzI0MDUzMjc0NQJfMQQNYW1vdW50V2l0aEZlZQgFDSR0MDMyNDA1MzI3NDUCXzIEEGdvdmVybmFuY2VSZXdhcmQIBQ0kdDAzMjQwNTMyNzQ1Al8zBA0kdDAzMjc2MjM0MTA4AwkAAAIFDXdpdGhkcmF3QXNzZXQFCGFzc2V0SWRBBAd1bnN0YWtlAwkBCGNvbnRhaW5zAgUNc3Rha2luZ0Fzc2V0cwULc3RyQXNzZXRJZEEJAPwHBAgFAWkGY2FsbGVyAgxzdGFrZVVuc3Rha2UJAMwIAgcJAMwIAgkAZAIJAGQCBQxhbW91bnRUb1BheUEFDWFtb3VudFdpdGhGZWUFEGdvdmVybmFuY2VSZXdhcmQJAMwIAgULc3RyQXNzZXRJZEEFA25pbAUDbmlsAAADCQAAAgUHdW5zdGFrZQUHdW5zdGFrZQkAlgoECQBlAgkAZQIJAGUCBQhiYWxhbmNlQQUMYW1vdW50VG9QYXlBBQ1hbW91bnRXaXRoRmVlBRBnb3Zlcm5hbmNlUmV3YXJkBQhiYWxhbmNlQgUIYXNzZXRJZEEJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUGY2FsbGVyCQBkAgUMYW1vdW50VG9QYXlBBQ1hbW91bnRXaXRoRmVlBQhhc3NldElkQQUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBAd1bnN0YWtlAwkBCGNvbnRhaW5zAgUNc3Rha2luZ0Fzc2V0cwULc3RyQXNzZXRJZEIJAPwHBAgFAWkGY2FsbGVyAgxzdGFrZVVuc3Rha2UJAMwIAgcJAMwIAgkAZAIJAGQCBQxhbW91bnRUb1BheUIFDWFtb3VudFdpdGhGZWUFEGdvdmVybmFuY2VSZXdhcmQJAMwIAgULc3RyQXNzZXRJZEIFA25pbAUDbmlsAAADCQAAAgUHdW5zdGFrZQUHdW5zdGFrZQkAlgoEBQhiYWxhbmNlQQkAZQIJAGUCCQBlAgUIYmFsYW5jZUIFDGFtb3VudFRvUGF5QgUNYW1vdW50V2l0aEZlZQUQZ292ZXJuYW5jZVJld2FyZAUIYXNzZXRJZEIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUGY2FsbGVyCQBkAgUMYW1vdW50VG9QYXlCBQ1hbW91bnRXaXRoRmVlBQhhc3NldElkQgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBAtuZXdCYWxhbmNlQQgFDSR0MDMyNzYyMzQxMDgCXzEEC25ld0JhbGFuY2VCCAUNJHQwMzI3NjIzNDEwOAJfMgQQZ292UmV3YXJkQXNzZXRJZAgFDSR0MDMyNzYyMzQxMDgCXzMEDHVzZXJUcmFuc2ZlcggFDSR0MDMyNzYyMzQxMDgCXzQJAJQKAgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFDHVubG9ja0Ftb3VudAUMc2hhcmVBc3NldElkBQNuaWwJAJQKAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQlrQmFsYW5jZUEFC25ld0JhbGFuY2VBCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQlrQmFsYW5jZUIFC25ld0JhbGFuY2VCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRFrU2hhcmVBc3NldFN1cHBseQkAZQIFEHNoYXJlQXNzZXRTdXBwbHkFDndpdGhkcmF3QW1vdW50CQDMCAIJAQRCdXJuAgUMc2hhcmVBc3NldElkBQ53aXRoZHJhd0Ftb3VudAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQ9tb25leUJveEFkZHJlc3MFEGdvdmVybmFuY2VSZXdhcmQFEGdvdlJld2FyZEFzc2V0SWQFA25pbAUMdXNlclRyYW5zZmVyBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEZdGFrZUludG9BY2NvdW50RXh0cmFGdW5kcwQLY2FsbGVyQnl0ZXMEYXJncwhwQW1vdW50cwlwQXNzZXRJZHMJAQt2YWx1ZU9yRWxzZQIJAQxpc09yYWNsZVBvb2wBCQClCAEIBQFpBmNhbGxlcgkBC3ZhbHVlT3JFbHNlAgkBCGlzQWN0aXZlAAQNJHQwMzQ4MzMzNDkwOQkBDWdldFBvb2xBc3NldHMBCAUBaQZjYWxsZXIEC3N0ckFzc2V0SWRBCAUNJHQwMzQ4MzMzNDkwOQJfMQQLc3RyQXNzZXRJZEIIBQ0kdDAzNDgzMzM0OTA5Al8yBAhhc3NldElkQQgFDSR0MDM0ODMzMzQ5MDkCXzMECGFzc2V0SWRCCAUNJHQwMzQ4MzMzNDkwOQJfNAQNJHQwMzQ5MjIzNTAyOAkBD2dldFBvb2xCYWxhbmNlcwMIBQFpBmNhbGxlcgUIYXNzZXRJZEEFCGFzc2V0SWRCBAhiYWxhbmNlQQgFDSR0MDM0OTIyMzUwMjgCXzEECGJhbGFuY2VCCAUNJHQwMzQ5MjIzNTAyOAJfMgQPYWNjb3VudEJhbGFuY2VBCAUNJHQwMzQ5MjIzNTAyOAJfMwQPYWNjb3VudEJhbGFuY2VCCAUNJHQwMzQ5MjIzNTAyOAJfNAQNYW1vdW50RW5yb2xsQQkAZQIFD2FjY291bnRCYWxhbmNlQQUIYmFsYW5jZUEEDWFtb3VudEVucm9sbEIJAGUCBQ9hY2NvdW50QmFsYW5jZUIFCGJhbGFuY2VCAwkBAiE9AgUPbW9uZXlCb3hBZGRyZXNzCAUBaQxvcmlnaW5DYWxsZXIJAAIBAiZPbmx5IHRoZSB3YWxsZXQgY2FuIGNhbGwgdGhpcyBmdW5jdGlvbgMDCQBmAgAABQ1hbW91bnRFbnJvbGxBBgkAZgIAAAUNYW1vdW50RW5yb2xsQgkBB3N1c3BlbmQBAhZFbnJvbGwgYW1vdW50IG5lZ2F0aXZlAwMJAAACBQ1hbW91bnRFbnJvbGxBAAAJAAACBQ1hbW91bnRFbnJvbGxCAAAHCQACAQIQTm8gbW9uZXkgdG8gdGFrZQQGc3Rha2UxAwMJAQhjb250YWlucwIFDXN0YWtpbmdBc3NldHMFC3N0ckFzc2V0SWRBCQBmAgUNYW1vdW50RW5yb2xsQQAABwkA/AcEBQR0aGlzAgxzdGFrZVVuc3Rha2UJAMwIAgYJAMwIAgUNYW1vdW50RW5yb2xsQQkAzAgCBQtzdHJBc3NldElkQQUDbmlsBQNuaWwAAAMJAAACBQZzdGFrZTEFBnN0YWtlMQQGc3Rha2UyAwMJAQhjb250YWlucwIFDXN0YWtpbmdBc3NldHMFC3N0ckFzc2V0SWRCCQBmAgUNYW1vdW50RW5yb2xsQgAABwkA/AcEBQR0aGlzAgxzdGFrZVVuc3Rha2UJAMwIAgYJAMwIAgUNYW1vdW50RW5yb2xsQgkAzAgCBQtzdHJBc3NldElkQgUDbmlsBQNuaWwAAAMJAAACBQZzdGFrZTIFBnN0YWtlMgkAlAoCBQNuaWwJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUJa0JhbGFuY2VBCQBkAgUIYmFsYW5jZUEFDWFtb3VudEVucm9sbEEJAMwIAgkBDEludGVnZXJFbnRyeQIFCWtCYWxhbmNlQgkAZAIFCGJhbGFuY2VCBQ1hbW91bnRFbnJvbGxCBQNuaWwFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECdHgBBnZlcmlmeQAEE211bHRpU2lnbmVkQnlBZG1pbnMEEmFkbWluUHViS2V5MVNpZ25lZAMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAFDGFkbWluUHViS2V5MQABAAAEEmFkbWluUHViS2V5MlNpZ25lZAMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAEFDGFkbWluUHViS2V5MgABAAAEEmFkbWluUHViS2V5M1NpZ25lZAMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAIFDGFkbWluUHViS2V5MwABAAAJAGcCCQBkAgkAZAIFEmFkbWluUHViS2V5MVNpZ25lZAUSYWRtaW5QdWJLZXkyU2lnbmVkBRJhZG1pblB1YktleTNTaWduZWQAAgUTbXVsdGlTaWduZWRCeUFkbWluczvT2SU=", "height": 2118881, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: CgVZmLAtrgWv2UwNfL7Reazswo2WebQZsK434ZcXta3N Next: DtFwinjC8cbkAWcPjTwRSSqTs1VXSbLgXbVWL43u6jTs Diff:
OldNewDifferences
1-{-# STDLIB_VERSION 5 #-}
1+{-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let version = "1.0.0"
5555
5656 let kOracleActiveExchangers = "active_global_exchangers"
5757
58+let kDiscounts = "discounts"
59+
60+let kDiscountValues = "discount_values"
61+
62+let kUserSwopInGov = "_SWOP_amount"
63+
64+let kOraclePool = "pool_"
65+
5866 let kAdminPubKey1 = "admin_pub_1"
5967
6068 let kAdminPubKey2 = "admin_pub_2"
6674 let kMoneyBoxAddress = "money_box_address"
6775
6876 let kVotingAddress = "voting_address"
77+
78+let kGovAddress = "governance_address"
79+
80+let kFarmingAddress = "farming_address"
6981
7082 let oracle = Address(base58'3NBBWfzZtZtszaXbitTKnrB2xXwv26Bn7H9')
7183
88100 let moneyBoxAddress = Address(getBase58FromOracle(kMoneyBoxAddress))
89101
90102 let votingAddress = Address(getBase58FromOracle(kVotingAddress))
103+
104+let govAddress = Address(getBase58FromOracle(kGovAddress))
105+
106+let farmingAddress = Address(getBase58FromOracle(kFarmingAddress))
91107
92108 let USDN = getBase58FromOracle(kUSDNAssetId)
93109
149165
150166 func getAssetInfo (assetId) = match assetId {
151167 case id: String|ByteVector =>
152- let $t036343806 = match id {
168+ let $t039674139 = match id {
153169 case aId: ByteVector =>
154170 $Tuple2(toBase58String(aId), aId)
155171 case aId: String =>
157173 case _ =>
158174 throw("Match error")
159175 }
160- let stringId = $t036343806._1
161- let bytesId = $t036343806._2
176+ let stringId = $t039674139._1
177+ let bytesId = $t039674139._2
162178 let info = valueOrErrorMessage(assetInfo(bytesId), (("Asset " + stringId) + " doesn't exist"))
163179 $Tuple3(stringId, info.name, info.decimals)
164180 case waves: Unit =>
171187 func suspend (cause) = [BooleanEntry(kActive, false), StringEntry(kCause, cause)]
172188
173189
190+func calculateFeeDiscount (userAddr) = {
191+ let swopAmount = valueOrElse(getInteger(govAddress, (toString(userAddr) + kUserSwopInGov)), 0)
192+ let discountValues = split(getStringValue(oracle, kDiscountValues), ",")
193+ let discounts = split(getStringValue(oracle, kDiscounts), ",")
194+ if (if ((swopAmount >= parseIntValue(discountValues[0])))
195+ then (parseIntValue(discountValues[1]) > swopAmount)
196+ else false)
197+ then (feeScale6 - parseIntValue(discounts[0]))
198+ else if (if ((swopAmount >= parseIntValue(discountValues[1])))
199+ then (parseIntValue(discountValues[2]) > swopAmount)
200+ else false)
201+ then (feeScale6 - parseIntValue(discounts[1]))
202+ else if (if ((swopAmount >= parseIntValue(discountValues[2])))
203+ then (parseIntValue(discountValues[3]) > swopAmount)
204+ else false)
205+ then (feeScale6 - parseIntValue(discounts[2]))
206+ else if (if ((swopAmount >= parseIntValue(discountValues[3])))
207+ then (parseIntValue(discountValues[4]) > swopAmount)
208+ else false)
209+ then (feeScale6 - parseIntValue(discounts[3]))
210+ else if ((swopAmount >= parseIntValue(discountValues[4])))
211+ then (feeScale6 - parseIntValue(discounts[4]))
212+ else feeScale6
213+ }
214+
215+
174216 func calculateFees (pmtAmount,minAmountToReceive,tokenFrom,tokenTo,fee,feeGovernance) = {
175217 let amountWithoutFee = fraction(tokenTo, pmtAmount, (pmtAmount + tokenFrom))
176218 let amountWithFee = fraction(amountWithoutFee, (feeScale6 - fee), feeScale6)
181223 }
182224
183225
226+func calculateVirtGet (pmtAmount,balance,fee) = {
227+ let a = 1
228+ let b = (((balance + fraction(balance, (feeScale6 - fee), feeScale6)) + fraction(pmtAmount, (feeScale6 - fee), feeScale6)) - pmtAmount)
229+ let c = (-(toBigInt(balance)) * toBigInt(pmtAmount))
230+ let D = ((toBigInt(b) * toBigInt(b)) - ((toBigInt(4) * toBigInt(a)) * c))
231+ (toInt(((-(toBigInt(b)) + pow(D, 0, toBigInt(5), 1, 0, DOWN)) / toBigInt(2))) * a)
232+ }
233+
234+
235+func parsePaymentAsset (assetId) = if ((assetId == base58''))
236+ then unit
237+ else assetId
238+
239+
184240 func suspendSuspicious (accountBalanceA,accountBalanceB,balanceA,balanceB,assetIdA,assetIdB) = suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(accountBalanceA)) + " ") + assetIdA) + ", ") + toString(accountBalanceB)) + " ") + assetIdB) + ". State: ") + toString(balanceA)) + " ") + assetIdA) + ", ") + toString(balanceB)) + " ") + assetIdB))
185241
186242
187243 func isActive () = if (active)
188244 then unit
189245 else throw("DApp is inactive at this moment")
246+
247+
248+func isOraclePool (poolAddress) = if (isDefined(getString(oracle, (kOraclePool + poolAddress))))
249+ then unit
250+ else throw("DApp is not registered pool")
190251
191252
192253 func getPoolBalances (pool,assetIdA,assetIdB) = {
215276 }
216277
217278
218-func getFeeParams (pool) = {
219- let fee = getIntegerValue(pool, kFee)
220- let govFee = fraction(fee, 40, 100)
279+func getFeeParams (pool,caller) = {
280+ let feeDiscount = calculateFeeDiscount(caller)
281+ let fee = fraction(getIntegerValue(pool, kFee), feeDiscount, feeScale6, CEILING)
282+ let govFee = fraction(fraction(fee, 40, 100), feeDiscount, feeScale6, CEILING)
221283 $Tuple2(fee, govFee)
222284 }
223285
225287 @Callable(i)
226288 func init (callerBytes,args,pAmounts,pAssetIds) = {
227289 let caller = Address(callerBytes)
228- let $t066046663 = $Tuple2(pAmounts[0], pAssetIds[0])
229- let pmtAmountA = $t066046663._1
230- let pmtAssetIdA = $t066046663._2
231- let $t066686727 = $Tuple2(pAmounts[1], pAssetIds[1])
232- let pmtAmountB = $t066686727._1
233- let pmtAssetIdB = $t066686727._2
290+ let $t088518929 = $Tuple2(pAmounts[0], parsePaymentAsset(pAssetIds[0]))
291+ let pmtAmountA = $t088518929._1
292+ let pmtAssetIdA = $t088518929._2
293+ let $t089349012 = $Tuple2(pAmounts[1], parsePaymentAsset(pAssetIds[1]))
294+ let pmtAmountB = $t089349012._1
295+ let pmtAssetIdB = $t089349012._2
234296 if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminInvokePubKey], i.originCallerPublicKey)))
235297 then throw("Only admin can call this function")
236298 else if (isDefined(getBoolean(caller, kActive)))
238300 else if ((pmtAssetIdA == pmtAssetIdB))
239301 then throw("Assets must be different")
240302 else {
241- let $t070977174 = getAssetInfo(pmtAssetIdA)
242- let pmtStrAssetIdA = $t070977174._1
243- let pmtAssetNameA = $t070977174._2
244- let pmtDecimalsA = $t070977174._3
245- let $t071837260 = getAssetInfo(pmtAssetIdB)
246- let pmtStrAssetIdB = $t071837260._1
247- let pmtAssetNameB = $t071837260._2
248- let pmtDecimalsB = $t071837260._3
303+ let $t093829459 = getAssetInfo(pmtAssetIdA)
304+ let pmtStrAssetIdA = $t093829459._1
305+ let pmtAssetNameA = $t093829459._2
306+ let pmtDecimalsA = $t093829459._3
307+ let $t094689545 = getAssetInfo(pmtAssetIdB)
308+ let pmtStrAssetIdB = $t094689545._1
309+ let pmtAssetNameB = $t094689545._2
310+ let pmtDecimalsB = $t094689545._3
249311 let firstHarvest = (args[0] == "true")
250312 let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
251313 let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
268330 then {
269331 let baseEntry = [StringEntry(kVersion, version), BooleanEntry(kActive, true), StringEntry(kAssetIdA, pmtStrAssetIdA), StringEntry(kAssetIdB, pmtStrAssetIdB), IntegerEntry(kBalanceA, pmtAmountA), IntegerEntry(kBalanceB, pmtAmountB), IntegerEntry(kFee, getIntegerValue(oracle, "base_fee_cpmm")), shareIssue, StringEntry(kShareAssetId, toBase58String(shareIssueId)), IntegerEntry(kShareAssetSupply, shareInitialSupply), ScriptTransfer(caller, shareInitialSupply, shareIssueId)]
270332 if (firstHarvest)
271- then $Tuple2(nil, (baseEntry ++ [BooleanEntry(kFirstHarvest, firstHarvest), IntegerEntry(kFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))]))
272- else $Tuple2(nil, baseEntry)
333+ then $Tuple2(nil, $Tuple2((baseEntry ++ [BooleanEntry(kFirstHarvest, firstHarvest), IntegerEntry(kFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))]), nil))
334+ else $Tuple2(nil, $Tuple2(baseEntry, nil))
273335 }
274336 else throw("Strict value is not equal to itself.")
275337 }
282344 @Callable(i)
283345 func initWithInitRatio (callerBytes,args,pAmounts,pAssetIds) = {
284346 let caller = Address(callerBytes)
285- let $t094939693 = $Tuple5(parseIntValue(args[0]), parseIntValue(args[1]), args[2], args[3], (args[4] == "true"))
286- let amtAssetA = $t094939693._1
287- let amtAssetB = $t094939693._2
288- let assetIdAStr = $t094939693._3
289- let assetIdBStr = $t094939693._4
290- let firstHarvest = $t094939693._5
347+ let $t01179011990 = $Tuple5(parseIntValue(args[0]), parseIntValue(args[1]), args[2], args[3], (args[4] == "true"))
348+ let amtAssetA = $t01179011990._1
349+ let amtAssetB = $t01179011990._2
350+ let assetIdAStr = $t01179011990._3
351+ let assetIdBStr = $t01179011990._4
352+ let firstHarvest = $t01179011990._5
291353 if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminInvokePubKey], i.originCallerPublicKey)))
292354 then throw("Only admin can call this function")
293355 else if (isDefined(getBoolean(caller, kActive)))
295357 else if ((assetIdAStr == assetIdBStr))
296358 then throw("Assets must be different")
297359 else {
298- let $t01006310140 = getAssetInfo(assetIdAStr)
299- let pmtStrAssetIdA = $t01006310140._1
300- let pmtAssetNameA = $t01006310140._2
301- let pmtDecimalsA = $t01006310140._3
302- let $t01014910226 = getAssetInfo(assetIdBStr)
303- let pmtStrAssetIdB = $t01014910226._1
304- let pmtAssetNameB = $t01014910226._2
305- let pmtDecimalsB = $t01014910226._3
360+ let $t01236012437 = getAssetInfo(assetIdAStr)
361+ let pmtStrAssetIdA = $t01236012437._1
362+ let pmtAssetNameA = $t01236012437._2
363+ let pmtDecimalsA = $t01236012437._3
364+ let $t01244612523 = getAssetInfo(assetIdBStr)
365+ let pmtStrAssetIdB = $t01244612523._1
366+ let pmtAssetNameB = $t01244612523._2
367+ let pmtDecimalsB = $t01244612523._3
306368 let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
307369 let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
308370 let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
311373 let shareIssueId = calculateAssetId(shareIssue)
312374 let baseEntry = [StringEntry(kVersion, version), BooleanEntry(kActive, true), StringEntry(kAssetIdA, pmtStrAssetIdA), StringEntry(kAssetIdB, pmtStrAssetIdB), IntegerEntry(kBalanceInitA, amtAssetA), IntegerEntry(kBalanceInitB, amtAssetB), IntegerEntry(kBalanceA, 0), IntegerEntry(kBalanceB, 0), IntegerEntry(kFee, getIntegerValue(oracle, "base_fee_cpmm")), shareIssue, StringEntry(kShareAssetId, toBase58String(shareIssueId)), IntegerEntry(kShareAssetSupply, shareInitialSupply)]
313375 if (firstHarvest)
314- then $Tuple2(nil, (baseEntry ++ [BooleanEntry(kFirstHarvest, firstHarvest), IntegerEntry(kFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))]))
315- else $Tuple2(nil, baseEntry)
376+ then $Tuple2(nil, $Tuple2((baseEntry ++ [BooleanEntry(kFirstHarvest, firstHarvest), IntegerEntry(kFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))]), nil))
377+ else $Tuple2(nil, $Tuple2(baseEntry, nil))
316378 }
317379 }
318380
319381
320382
321383 @Callable(i)
322-func keepLimitForFirstHarvest (callerBytes,args,pAmounts,pAssetIds) = valueOrElse(isActive(), if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminInvokePubKey], i.originCallerPublicKey)))
384+func keepLimitForFirstHarvest (callerBytes,args,pAmounts,pAssetIds) = valueOrElse(isOraclePool(toString(i.caller)), valueOrElse(isActive(), if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminInvokePubKey], i.originCallerPublicKey)))
323385 then throw("Only admin can call this function")
324386 else {
325387 let shareLimit = parseIntValue(args[0])
326- $Tuple2(nil, [IntegerEntry(kShareLimit, shareLimit)])
327- })
388+ $Tuple2(nil, $Tuple2([IntegerEntry(kShareLimit, shareLimit)], nil))
389+ }))
328390
329391
330392
331393 @Callable(i)
332-func exchange (callerBytes,args,pAmounts,pAssetIds) = valueOrElse(isActive(), {
394+func exchange (callerBytes,args,pAmounts,pAssetIds) = valueOrElse(isOraclePool(toString(i.caller)), valueOrElse(isActive(), {
333395 let caller = Address(callerBytes)
334- let $t01232612383 = $Tuple2(pAmounts[0], pAssetIds[0])
335- let pmtAmount = $t01232612383._1
336- let pmtAssetId = $t01232612383._2
396+ let $t01484814924 = $Tuple2(pAmounts[0], parsePaymentAsset(pAssetIds[0]))
397+ let pmtAmount = $t01484814924._1
398+ let pmtAssetId = $t01484814924._2
337399 let minAmountToReceive = parseIntValue(args[0])
338- let $t01244012516 = getPoolAssets(i.caller)
339- let strAssetIdA = $t01244012516._1
340- let strAssetIdB = $t01244012516._2
341- let assetIdA = $t01244012516._3
342- let assetIdB = $t01244012516._4
343- let $t01252112627 = getPoolBalances(i.caller, assetIdA, assetIdB)
344- let balanceA = $t01252112627._1
345- let balanceB = $t01252112627._2
346- let accountBalanceA = $t01252112627._3
347- let accountBalanceB = $t01252112627._4
400+ let $t01499715073 = getPoolAssets(i.caller)
401+ let strAssetIdA = $t01499715073._1
402+ let strAssetIdB = $t01499715073._2
403+ let assetIdA = $t01499715073._3
404+ let assetIdB = $t01499715073._4
405+ let $t01508615192 = getPoolBalances(i.caller, assetIdA, assetIdB)
406+ let balanceA = $t01508615192._1
407+ let balanceB = $t01508615192._2
408+ let accountBalanceA = $t01508615192._3
409+ let accountBalanceB = $t01508615192._4
348410 if (if ((balanceA == 0))
349411 then true
350412 else (balanceB == 0))
360422 else (balanceB > accountBalanceB))
361423 then $Tuple2(nil, ([ScriptTransfer(caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious(accountBalanceA, accountBalanceB, balanceA, balanceB, strAssetIdA, strAssetIdB)))
362424 else {
363- let $t01339213434 = getFeeParams(i.caller)
364- let fee = $t01339213434._1
365- let govFee = $t01339213434._2
366- let $t01344313748 = if ((pmtAssetId == assetIdA))
425+ let $t01607716135 = getFeeParams(i.caller, i.originCaller)
426+ let fee = $t01607716135._1
427+ let govFee = $t01607716135._2
428+ let $t01615216489 = if ((pmtAssetId == assetIdA))
367429 then calculateFees(pmtAmount, minAmountToReceive, balanceA, balanceB, fee, govFee)
368430 else calculateFees(pmtAmount, minAmountToReceive, balanceB, balanceA, fee, govFee)
369- let amountWithoutFee = $t01344313748._1
370- let amountWithFee = $t01344313748._2
371- let governanceReward = $t01344313748._3
372- let $t01375814207 = if ((pmtAssetId == assetIdA))
431+ let amountWithoutFee = $t01615216489._1
432+ let amountWithFee = $t01615216489._2
433+ let governanceReward = $t01615216489._3
434+ let $t01650716832 = if ((pmtAssetId == assetIdA))
373435 then $Tuple3((balanceA + pmtAmount), ((balanceB - amountWithFee) - governanceReward), assetIdB)
374436 else $Tuple3(((balanceA - amountWithFee) - governanceReward), (balanceB + pmtAmount), assetIdA)
375- let newBalanceA = $t01375814207._1
376- let newBalanceB = $t01375814207._2
377- let assetIdSend = $t01375814207._3
378- let $t01421714435 = if ((pmtAssetId == assetIdA))
437+ let newBalanceA = $t01650716832._1
438+ let newBalanceB = $t01650716832._2
439+ let assetIdSend = $t01650716832._3
440+ let $t01685017100 = if ((pmtAssetId == assetIdA))
379441 then $Tuple2(pmtAmount, (amountWithFee + governanceReward))
380442 else $Tuple2((amountWithFee + governanceReward), pmtAmount)
381- let stakeAmountA = $t01421714435._1
382- let stakeAmountB = $t01421714435._2
443+ let stakeAmountA = $t01685017100._1
444+ let stakeAmountB = $t01685017100._2
383445 let stake1 = if (contains(stakingAssets, strAssetIdA))
384446 then invoke(i.caller, "stakeUnstake", [(pmtAssetId == assetIdA), stakeAmountA, strAssetIdA], nil)
385447 else 0
389451 then invoke(i.caller, "stakeUnstake", [(pmtAssetId == assetIdB), stakeAmountB, strAssetIdB], nil)
390452 else 0
391453 if ((stake2 == stake2))
392- then $Tuple2(nil, [IntegerEntry(kBalanceA, newBalanceA), IntegerEntry(kBalanceB, newBalanceB), ScriptTransfer(caller, amountWithFee, assetIdSend), ScriptTransfer(moneyBoxAddress, governanceReward, assetIdSend)])
454+ then $Tuple2(nil, $Tuple2([IntegerEntry(kBalanceA, newBalanceA), IntegerEntry(kBalanceB, newBalanceB), ScriptTransfer(caller, amountWithFee, assetIdSend), ScriptTransfer(moneyBoxAddress, governanceReward, assetIdSend)], [amountWithFee, assetIdSend]))
393455 else throw("Strict value is not equal to itself.")
394456 }
395457 else throw("Strict value is not equal to itself.")
396458 }
397- })
459+ }))
398460
399461
400462
401463 @Callable(i)
402-func replenishWithTwoTokens (callerBytes,args,pAmounts,pAssetIds) = valueOrElse(isActive(), {
464+func replenishWithTwoTokens (callerBytes,args,pAmounts,pAssetIds) = valueOrElse(isOraclePool(toString(i.caller)), valueOrElse(isActive(), {
403465 let caller = Address(callerBytes)
404- let pmtAssetIdA = pAssetIds[0]
405- let pmtAssetIdB = pAssetIds[1]
406- let $t01529715387 = getPoolAssets(i.caller)
407- let strAssetIdA = $t01529715387._1
408- let strAssetIdB = $t01529715387._2
409- let assetIdA = $t01529715387._3
410- let assetIdB = $t01529715387._4
411- let shareAssetId = $t01529715387._5
412- let $t01539215516 = getPoolBalances(i.caller, assetIdA, assetIdB)
413- let balanceA = $t01539215516._1
414- let balanceB = $t01539215516._2
415- let accountBalanceA = $t01539215516._3
416- let accountBalanceB = $t01539215516._4
417- let shareAssetSupply = $t01539215516._5
466+ let pmtAssetIdA = parsePaymentAsset(pAssetIds[0])
467+ let pmtAssetIdB = parsePaymentAsset(pAssetIds[1])
468+ let stakeFarming = (args[0] == "true")
469+ let $t01831218402 = getPoolAssets(i.caller)
470+ let strAssetIdA = $t01831218402._1
471+ let strAssetIdB = $t01831218402._2
472+ let assetIdA = $t01831218402._3
473+ let assetIdB = $t01831218402._4
474+ let shareAssetId = $t01831218402._5
475+ let $t01841518539 = getPoolBalances(i.caller, assetIdA, assetIdB)
476+ let balanceA = $t01841518539._1
477+ let balanceB = $t01841518539._2
478+ let accountBalanceA = $t01841518539._3
479+ let accountBalanceB = $t01841518539._4
480+ let shareAssetSupply = $t01841518539._5
418481 if ((size(pAmounts) != 2))
419482 then throw("Two attached assets expected")
420483 else if (if ((pmtAssetIdA != assetIdA))
426489 else (balanceB > accountBalanceB))
427490 then $Tuple2(nil, ([ScriptTransfer(caller, pAmounts[0], pmtAssetIdA), ScriptTransfer(caller, pAmounts[1], pmtAssetIdB)] ++ suspendSuspicious(accountBalanceA, accountBalanceB, balanceA, balanceB, strAssetIdA, strAssetIdB)))
428491 else {
429- let $t01610116178 = getAssetInfo(pmtAssetIdA)
430- let pmtStrAssetIdA = $t01610116178._1
431- let pmtAssetNameA = $t01610116178._2
432- let pmtDecimalsA = $t01610116178._3
433- let $t01618716264 = getAssetInfo(pmtAssetIdB)
434- let pmtStrAssetIdB = $t01618716264._1
435- let pmtAssetNameB = $t01618716264._2
436- let pmtDecimalsB = $t01618716264._3
492+ let $t01921119288 = getAssetInfo(pmtAssetIdA)
493+ let pmtStrAssetIdA = $t01921119288._1
494+ let pmtAssetNameA = $t01921119288._2
495+ let pmtDecimalsA = $t01921119288._3
496+ let $t01930519382 = getAssetInfo(pmtAssetIdB)
497+ let pmtStrAssetIdB = $t01930519382._1
498+ let pmtAssetNameB = $t01930519382._2
499+ let pmtDecimalsB = $t01930519382._3
437500 let initial = ((balanceA + balanceB) == 0)
438- let $t01632317078 = if (initial)
501+ let $t01945720300 = if (initial)
439502 then $Tuple5(pAmounts[0], pAmounts[1], 0, pmtAssetIdA, 1)
440503 else {
441504 let ratioShareTokensInA = fraction(scale8, pAmounts[0], balanceA)
450513 $Tuple5(pmt, pAmounts[1], (pAmounts[0] - pmt), pmtAssetIdA, ratioShareTokensInB)
451514 }
452515 }
453- let pmtAmountA = $t01632317078._1
454- let pmtAmountB = $t01632317078._2
455- let change = $t01632317078._3
456- let changeAssetId = $t01632317078._4
457- let shareTokenRatio = $t01632317078._5
516+ let pmtAmountA = $t01945720300._1
517+ let pmtAmountB = $t01945720300._2
518+ let change = $t01945720300._3
519+ let changeAssetId = $t01945720300._4
520+ let shareTokenRatio = $t01945720300._5
458521 let shareTokenToPayAmount = if (initial)
459522 then {
460523 let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
463526 else fraction(shareTokenRatio, shareAssetSupply, scale8)
464527 if ((shareTokenToPayAmount == 0))
465528 then throw("Too small amount to replenish")
466- else {
467- let stake1 = if (contains(stakingAssets, pmtStrAssetIdA))
468- then invoke(i.caller, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
469- else 0
470- if ((stake1 == stake1))
471- then {
472- let stake2 = if (contains(stakingAssets, pmtStrAssetIdB))
473- then invoke(i.caller, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
474- else 0
475- if ((stake2 == stake2))
476- then $Tuple2(nil, [Reissue(shareAssetId, shareTokenToPayAmount, true), IntegerEntry(kBalanceA, (balanceA + pmtAmountA)), IntegerEntry(kBalanceB, (balanceB + pmtAmountB)), IntegerEntry(kShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), ScriptTransfer(caller, shareTokenToPayAmount, shareAssetId), ScriptTransfer(caller, change, changeAssetId)])
477- else throw("Strict value is not equal to itself.")
478- }
479- else throw("Strict value is not equal to itself.")
480- }
529+ else if ((0 > change))
530+ then throw("Change < 0")
531+ else {
532+ let stake1 = if (contains(stakingAssets, pmtStrAssetIdA))
533+ then invoke(i.caller, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
534+ else 0
535+ if ((stake1 == stake1))
536+ then {
537+ let stake2 = if (contains(stakingAssets, pmtStrAssetIdB))
538+ then invoke(i.caller, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
539+ else 0
540+ if ((stake2 == stake2))
541+ then {
542+ let shareTokenST = if (stakeFarming)
543+ then {
544+ let reissue = invoke(i.caller, "reissueShareToken", [shareTokenToPayAmount], nil)
545+ if ((reissue == reissue))
546+ then {
547+ let stake3 = invoke(farmingAddress, "lockShareTokens", [toString(i.caller)], [AttachedPayment(shareAssetId, shareTokenToPayAmount)])
548+ if ((stake3 == stake3))
549+ then nil
550+ else throw("Strict value is not equal to itself.")
551+ }
552+ else throw("Strict value is not equal to itself.")
553+ }
554+ else [Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(caller, shareTokenToPayAmount, shareAssetId)]
555+ $Tuple2(nil, $Tuple2(([IntegerEntry(kBalanceA, (balanceA + pmtAmountA)), IntegerEntry(kBalanceB, (balanceB + pmtAmountB)), IntegerEntry(kShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), ScriptTransfer(caller, change, changeAssetId)] ++ shareTokenST), nil))
556+ }
557+ else throw("Strict value is not equal to itself.")
558+ }
559+ else throw("Strict value is not equal to itself.")
560+ }
481561 }
482- })
562+ }))
483563
484564
485565
486566 @Callable(i)
487-func replenishWithOneToken (callerBytes,args,pAmounts,pAssetIds) = valueOrElse(isActive(), {
567+func replenishWithOneToken (callerBytes,args,pAmounts,pAssetIds) = valueOrElse(isOraclePool(toString(i.caller)), valueOrElse(isActive(), {
488568 let caller = Address(callerBytes)
489- let pmtAssetId = pAssetIds[0]
569+ let pmtAssetId = parsePaymentAsset(pAssetIds[0])
490570 let pmtAmount = pAmounts[0]
491- let virtMinAmount = parseIntValue(args[0])
492- let $t01868518775 = getPoolAssets(i.caller)
493- let strAssetIdA = $t01868518775._1
494- let strAssetIdB = $t01868518775._2
495- let assetIdA = $t01868518775._3
496- let assetIdB = $t01868518775._4
497- let shareAssetId = $t01868518775._5
498- let $t01878018904 = getPoolBalances(i.caller, assetIdA, assetIdB)
499- let balanceA = $t01878018904._1
500- let balanceB = $t01878018904._2
501- let accountBalanceA = $t01878018904._3
502- let accountBalanceB = $t01878018904._4
503- let shareAssetSupply = $t01878018904._5
571+ let virtGetMinAmount = parseIntValue(args[0])
572+ let stakeFarming = (args[1] == "true")
573+ let $t02285522945 = getPoolAssets(i.caller)
574+ let strAssetIdA = $t02285522945._1
575+ let strAssetIdB = $t02285522945._2
576+ let assetIdA = $t02285522945._3
577+ let assetIdB = $t02285522945._4
578+ let shareAssetId = $t02285522945._5
579+ let $t02295823082 = getPoolBalances(i.caller, assetIdA, assetIdB)
580+ let balanceA = $t02295823082._1
581+ let balanceB = $t02295823082._2
582+ let accountBalanceA = $t02295823082._3
583+ let accountBalanceB = $t02295823082._4
584+ let shareAssetSupply = $t02295823082._5
504585 let initial = ((balanceA + balanceB) == 0)
505586 if ((size(pAmounts) != 1))
506587 then throw("One attached assets expected")
515596 else (balanceB > accountBalanceB))
516597 then $Tuple2(nil, ([ScriptTransfer(caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious(accountBalanceA, accountBalanceB, balanceA, balanceB, strAssetIdA, strAssetIdB)))
517598 else {
518- let $t01955519597 = getFeeParams(i.caller)
519- let fee = $t01955519597._1
520- let govFee = $t01955519597._2
521- let $t01960621113 = if ((pmtAssetId == assetIdA))
599+ let $t02383623894 = getFeeParams(i.caller, i.originCaller)
600+ let fee = $t02383623894._1
601+ let govFee = $t02383623894._2
602+ let $t02391125797 = if ((pmtAssetId == assetIdA))
522603 then {
523- let $t01976719898 = calculateFees(pmtAmount, virtMinAmount, balanceA, balanceB, fee, govFee)
524- let amountWithoutFee = $t01976719898._1
525- let amountWithFee = $t01976719898._2
526- let governanceReward = $t01976719898._3
604+ let virtPayAmount = calculateVirtGet(pmtAmount, balanceA, fee)
605+ let $t02419024327 = calculateFees(virtPayAmount, virtGetMinAmount, balanceA, balanceB, fee, govFee)
606+ let amountWithoutFee = $t02419024327._1
607+ let amountWithFee = $t02419024327._2
608+ let governanceReward = $t02419024327._3
527609 let newBalanceA = (balanceA + pmtAmount)
528610 let newBalanceB = (balanceB - governanceReward)
529- let ratioShareTokensInA = fraction((pmtAmount / 2), scale8, newBalanceA)
611+ let ratioShareTokensInA = fraction((pmtAmount - virtPayAmount), scale8, newBalanceA)
530612 let ratioShareTokensInB = fraction(amountWithFee, scale8, newBalanceB)
531613 let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scale8)
532- $Tuple6(newBalanceA, newBalanceB, shareTokenToPayAmount, governanceReward, assetIdB, strAssetIdB)
614+ $Tuple7(newBalanceA, newBalanceB, shareTokenToPayAmount, governanceReward, assetIdB, strAssetIdB, strAssetIdA)
533615 }
534616 else {
535- let $t02045720588 = calculateFees(pmtAmount, virtMinAmount, balanceB, balanceA, fee, govFee)
536- let amountWithoutFee = $t02045720588._1
537- let amountWithFee = $t02045720588._2
538- let governanceReward = $t02045720588._3
617+ let virtPayAmount = calculateVirtGet(pmtAmount, balanceB, fee)
618+ let $t02506225199 = calculateFees(virtPayAmount, virtGetMinAmount, balanceB, balanceA, fee, govFee)
619+ let amountWithoutFee = $t02506225199._1
620+ let amountWithFee = $t02506225199._2
621+ let governanceReward = $t02506225199._3
539622 let newBalanceA = (balanceA - governanceReward)
540623 let newBalanceB = (balanceB + pmtAmount)
541624 let ratioShareTokensInA = fraction(amountWithFee, scale8, newBalanceA)
542- let ratioShareTokensInB = fraction((pmtAmount / 2), scale8, newBalanceB)
625+ let ratioShareTokensInB = fraction((pmtAmount - virtPayAmount), scale8, newBalanceB)
543626 let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scale8)
544- $Tuple6(newBalanceA, newBalanceB, shareTokenToPayAmount, governanceReward, assetIdA, strAssetIdA)
627+ $Tuple7(newBalanceA, newBalanceB, shareTokenToPayAmount, governanceReward, assetIdA, strAssetIdA, strAssetIdB)
545628 }
546- let newBalanceA = $t01960621113._1
547- let newBalanceB = $t01960621113._2
548- let shareTokenToPayAmount = $t01960621113._3
549- let govReward = $t01960621113._4
550- let govRewardAsset = $t01960621113._5
551- let govRewardAssetStr = $t01960621113._6
629+ let newBalanceA = $t02391125797._1
630+ let newBalanceB = $t02391125797._2
631+ let shareTokenToPayAmount = $t02391125797._3
632+ let govReward = $t02391125797._4
633+ let govRewardAsset = $t02391125797._5
634+ let govRewardAssetStr = $t02391125797._6
635+ let pmtAssetIdStr = $t02391125797._7
552636 if ((shareTokenToPayAmount == 0))
553637 then throw("Too small amount to replenish")
554638 else {
555- let stake1 = if (contains(stakingAssets, govRewardAssetStr))
556- then invoke(i.caller, "stakeUnstake", [false, govReward, govRewardAssetStr], nil)
639+ let stake1 = if (contains(stakingAssets, pmtAssetIdStr))
640+ then invoke(i.caller, "stakeUnstake", [true, pmtAmount, pmtAssetIdStr], nil)
557641 else 0
558642 if ((stake1 == stake1))
559- then $Tuple2(nil, [IntegerEntry(kBalanceA, newBalanceA), IntegerEntry(kBalanceB, newBalanceB), IntegerEntry(kShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(caller, shareTokenToPayAmount, shareAssetId), ScriptTransfer(moneyBoxAddress, govReward, govRewardAsset)])
643+ then {
644+ let stake2 = if (contains(stakingAssets, govRewardAssetStr))
645+ then invoke(i.caller, "stakeUnstake", [false, govReward, govRewardAssetStr], nil)
646+ else 0
647+ if ((stake2 == stake2))
648+ then {
649+ let shareTokenST = if (stakeFarming)
650+ then {
651+ let reissue = invoke(i.caller, "reissueShareToken", [shareTokenToPayAmount], nil)
652+ if ((reissue == reissue))
653+ then {
654+ let stake3 = invoke(farmingAddress, "lockShareTokens", [toString(i.caller)], [AttachedPayment(shareAssetId, shareTokenToPayAmount)])
655+ if ((stake3 == stake3))
656+ then nil
657+ else throw("Strict value is not equal to itself.")
658+ }
659+ else throw("Strict value is not equal to itself.")
660+ }
661+ else [Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(caller, shareTokenToPayAmount, shareAssetId)]
662+ $Tuple2(nil, $Tuple2(([IntegerEntry(kBalanceA, newBalanceA), IntegerEntry(kBalanceB, newBalanceB), IntegerEntry(kShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), ScriptTransfer(moneyBoxAddress, govReward, govRewardAsset)] ++ shareTokenST), nil))
663+ }
664+ else throw("Strict value is not equal to itself.")
665+ }
560666 else throw("Strict value is not equal to itself.")
561667 }
562668 }
563- })
669+ }))
564670
565671
566672
567673 @Callable(i)
568-func withdraw (callerBytes,args,pAmounts,pAssetIds) = valueOrElse(isActive(), {
674+func withdraw (callerBytes,args,pAmounts,pAssetIds) = valueOrElse(isOraclePool(toString(i.caller)), valueOrElse(isActive(), {
569675 let caller = Address(callerBytes)
570- let $t02206722124 = $Tuple2(pAmounts[0], pAssetIds[0])
571- let pmtAmount = $t02206722124._1
572- let pmtAssetId = $t02206722124._2
573- let $t02213022220 = getPoolAssets(i.caller)
574- let strAssetIdA = $t02213022220._1
575- let strAssetIdB = $t02213022220._2
576- let assetIdA = $t02213022220._3
577- let assetIdB = $t02213022220._4
578- let shareAssetId = $t02213022220._5
579- let $t02222522349 = getPoolBalances(i.caller, assetIdA, assetIdB)
580- let balanceA = $t02222522349._1
581- let balanceB = $t02222522349._2
582- let accountBalanceA = $t02222522349._3
583- let accountBalanceB = $t02222522349._4
584- let shareAssetSupply = $t02222522349._5
676+ let $t02760927699 = getPoolAssets(i.caller)
677+ let strAssetIdA = $t02760927699._1
678+ let strAssetIdB = $t02760927699._2
679+ let assetIdA = $t02760927699._3
680+ let assetIdB = $t02760927699._4
681+ let shareAssetId = $t02760927699._5
682+ let $t02771227836 = getPoolBalances(i.caller, assetIdA, assetIdB)
683+ let balanceA = $t02771227836._1
684+ let balanceB = $t02771227836._2
685+ let accountBalanceA = $t02771227836._3
686+ let accountBalanceB = $t02771227836._4
687+ let shareAssetSupply = $t02771227836._5
688+ let $t02784928257 = if ((size(pAmounts) == 1))
689+ then {
690+ let pAsset = parsePaymentAsset(pAssetIds[0])
691+ if ((pAsset != shareAssetId))
692+ then throw(("Incorrect asset attached. Expected: " + toBase58String(shareAssetId)))
693+ else $Tuple2(pAmounts[0], pAsset)
694+ }
695+ else $Tuple2(0, shareAssetId)
696+ let pmtAmount = $t02784928257._1
697+ let pmtAssetId = $t02784928257._2
698+ if ((size(pAmounts) > 1))
699+ then throw("One attached payment expected")
700+ else if (if ((balanceA > accountBalanceA))
701+ then true
702+ else (balanceB > accountBalanceB))
703+ then $Tuple2(nil, ([ScriptTransfer(caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious(accountBalanceA, accountBalanceB, balanceA, balanceB, strAssetIdA, strAssetIdB)))
704+ else {
705+ let unlockAmount = parseIntValue(valueOrElse(args[0], "0"))
706+ let unlock = if ((unlockAmount > 0))
707+ then invoke(farmingAddress, "withdrawShareTokens", [toString(i.caller), unlockAmount], nil)
708+ else 0
709+ if ((unlock == unlock))
710+ then {
711+ let withdrawAmount = (pmtAmount + unlockAmount)
712+ let amountToPayA = fraction(withdrawAmount, balanceA, shareAssetSupply)
713+ let amountToPayB = fraction(withdrawAmount, balanceB, shareAssetSupply)
714+ let stake1 = if (contains(stakingAssets, strAssetIdA))
715+ then invoke(i.caller, "stakeUnstake", [false, amountToPayA, strAssetIdA], nil)
716+ else 0
717+ if ((stake1 == stake1))
718+ then {
719+ let stake2 = if (contains(stakingAssets, strAssetIdB))
720+ then invoke(i.caller, "stakeUnstake", [false, amountToPayB, strAssetIdB], nil)
721+ else 0
722+ if ((stake2 == stake2))
723+ then $Tuple2([ScriptTransfer(i.caller, unlockAmount, shareAssetId)], $Tuple2([IntegerEntry(kBalanceA, (balanceA - amountToPayA)), IntegerEntry(kBalanceB, (balanceB - amountToPayB)), IntegerEntry(kShareAssetSupply, (shareAssetSupply - withdrawAmount)), Burn(shareAssetId, withdrawAmount), ScriptTransfer(caller, amountToPayA, assetIdA), ScriptTransfer(caller, amountToPayB, assetIdB)], nil))
724+ else throw("Strict value is not equal to itself.")
725+ }
726+ else throw("Strict value is not equal to itself.")
727+ }
728+ else throw("Strict value is not equal to itself.")
729+ }
730+ }))
731+
732+
733+
734+@Callable(i)
735+func withdrawOneToken (callerBytes,args,pAmounts,pAssetIds) = valueOrElse(isOraclePool(toString(i.caller)), valueOrElse(isActive(), {
736+ let caller = Address(callerBytes)
737+ let withdrawAsset = if ((args[0] == ""))
738+ then unit
739+ else fromBase58String(args[0])
740+ let $t03046530555 = getPoolAssets(i.caller)
741+ let strAssetIdA = $t03046530555._1
742+ let strAssetIdB = $t03046530555._2
743+ let assetIdA = $t03046530555._3
744+ let assetIdB = $t03046530555._4
745+ let shareAssetId = $t03046530555._5
746+ let $t03056830692 = getPoolBalances(i.caller, assetIdA, assetIdB)
747+ let balanceA = $t03056830692._1
748+ let balanceB = $t03056830692._2
749+ let accountBalanceA = $t03056830692._3
750+ let accountBalanceB = $t03056830692._4
751+ let shareAssetSupply = $t03056830692._5
752+ let $t03070531085 = if ((size(pAmounts) == 1))
753+ then {
754+ let pAsset = parsePaymentAsset(pAssetIds[0])
755+ if ((pAsset != shareAssetId))
756+ then throw(("Incorrect asset attached. Expected: " + toBase58String(shareAssetId)))
757+ else $Tuple2(pAmounts[0], pAsset)
758+ }
759+ else $Tuple2(0, shareAssetId)
760+ let pmtAmount = $t03070531085._1
761+ let pmtAssetId = $t03070531085._2
762+ let virtMinToRecive = parseIntValue(args[1])
585763 if ((size(pAmounts) != 1))
586764 then throw("One attached payment expected")
587765 else if ((pmtAssetId != shareAssetId))
588766 then throw(("Incorrect asset attached. Expected: " + toBase58String(shareAssetId)))
589- else if (if ((balanceA > accountBalanceA))
590- then true
591- else (balanceB > accountBalanceB))
592- then $Tuple2(nil, ([ScriptTransfer(caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious(accountBalanceA, accountBalanceB, balanceA, balanceB, strAssetIdA, strAssetIdB)))
593- else {
594- let amountToPayA = fraction(pmtAmount, balanceA, shareAssetSupply)
595- let amountToPayB = fraction(pmtAmount, balanceB, shareAssetSupply)
596- let stake1 = if (contains(stakingAssets, strAssetIdA))
597- then invoke(i.caller, "stakeUnstake", [false, amountToPayA, strAssetIdA], nil)
598- else 0
599- if ((stake1 == stake1))
600- then {
601- let stake2 = if (contains(stakingAssets, strAssetIdB))
602- then invoke(i.caller, "stakeUnstake", [false, amountToPayB, strAssetIdB], nil)
603- else 0
604- if ((stake2 == stake2))
605- then $Tuple2(nil, [IntegerEntry(kBalanceA, (balanceA - amountToPayA)), IntegerEntry(kBalanceB, (balanceB - amountToPayB)), IntegerEntry(kShareAssetSupply, (shareAssetSupply - pmtAmount)), Burn(shareAssetId, pmtAmount), ScriptTransfer(caller, amountToPayA, assetIdA), ScriptTransfer(caller, amountToPayB, assetIdB)])
606- else throw("Strict value is not equal to itself.")
607- }
608- else throw("Strict value is not equal to itself.")
609- }
610- })
767+ else if (!(containsElement([assetIdA, assetIdB], withdrawAsset)))
768+ then throw("Incorrect withdraw asset.")
769+ else if (if ((balanceA > accountBalanceA))
770+ then true
771+ else (balanceB > accountBalanceB))
772+ then $Tuple2(nil, ([ScriptTransfer(caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious(accountBalanceA, accountBalanceB, balanceA, balanceB, strAssetIdA, strAssetIdB)))
773+ else {
774+ let unlockAmount = parseIntValue(valueOrElse(args[2], "0"))
775+ let unlock = if ((unlockAmount > 0))
776+ then invoke(farmingAddress, "withdrawShareTokens", [toString(i.caller), unlockAmount], nil)
777+ else 0
778+ if ((unlock == unlock))
779+ then {
780+ let withdrawAmount = (pmtAmount + unlockAmount)
781+ let amountToPayA = fraction(withdrawAmount, balanceA, shareAssetSupply)
782+ let amountToPayB = fraction(withdrawAmount, balanceB, shareAssetSupply)
783+ let $t03233032388 = getFeeParams(i.caller, i.originCaller)
784+ let fee = $t03233032388._1
785+ let govFee = $t03233032388._2
786+ let $t03240532745 = if ((withdrawAsset == assetIdA))
787+ then calculateFees(amountToPayB, virtMinToRecive, balanceB, balanceA, fee, govFee)
788+ else calculateFees(amountToPayA, virtMinToRecive, balanceA, balanceB, fee, govFee)
789+ let amountWithoutFee = $t03240532745._1
790+ let amountWithFee = $t03240532745._2
791+ let governanceReward = $t03240532745._3
792+ let $t03276234108 = if ((withdrawAsset == assetIdA))
793+ then {
794+ let unstake = if (contains(stakingAssets, strAssetIdA))
795+ then invoke(i.caller, "stakeUnstake", [false, ((amountToPayA + amountWithFee) + governanceReward), strAssetIdA], nil)
796+ else 0
797+ if ((unstake == unstake))
798+ then $Tuple4((((balanceA - amountToPayA) - amountWithFee) - governanceReward), balanceB, assetIdA, [ScriptTransfer(caller, (amountToPayA + amountWithFee), assetIdA)])
799+ else throw("Strict value is not equal to itself.")
800+ }
801+ else {
802+ let unstake = if (contains(stakingAssets, strAssetIdB))
803+ then invoke(i.caller, "stakeUnstake", [false, ((amountToPayB + amountWithFee) + governanceReward), strAssetIdB], nil)
804+ else 0
805+ if ((unstake == unstake))
806+ then $Tuple4(balanceA, (((balanceB - amountToPayB) - amountWithFee) - governanceReward), assetIdB, [ScriptTransfer(caller, (amountToPayB + amountWithFee), assetIdB)])
807+ else throw("Strict value is not equal to itself.")
808+ }
809+ let newBalanceA = $t03276234108._1
810+ let newBalanceB = $t03276234108._2
811+ let govRewardAssetId = $t03276234108._3
812+ let userTransfer = $t03276234108._4
813+ $Tuple2([ScriptTransfer(i.caller, unlockAmount, shareAssetId)], $Tuple2(([IntegerEntry(kBalanceA, newBalanceA), IntegerEntry(kBalanceB, newBalanceB), IntegerEntry(kShareAssetSupply, (shareAssetSupply - withdrawAmount)), Burn(shareAssetId, withdrawAmount), ScriptTransfer(moneyBoxAddress, governanceReward, govRewardAssetId)] ++ userTransfer), nil))
814+ }
815+ else throw("Strict value is not equal to itself.")
816+ }
817+ }))
611818
612819
613820
614821 @Callable(i)
615-func takeIntoAccountExtraFunds (callerBytes,args,pAmounts,pAssetIds) = valueOrElse(isActive(), {
616- let $t02385823934 = getPoolAssets(i.caller)
617- let strAssetIdA = $t02385823934._1
618- let strAssetIdB = $t02385823934._2
619- let assetIdA = $t02385823934._3
620- let assetIdB = $t02385823934._4
621- let $t02393924045 = getPoolBalances(i.caller, assetIdA, assetIdB)
622- let balanceA = $t02393924045._1
623- let balanceB = $t02393924045._2
624- let accountBalanceA = $t02393924045._3
625- let accountBalanceB = $t02393924045._4
822+func takeIntoAccountExtraFunds (callerBytes,args,pAmounts,pAssetIds) = valueOrElse(isOraclePool(toString(i.caller)), valueOrElse(isActive(), {
823+ let $t03483334909 = getPoolAssets(i.caller)
824+ let strAssetIdA = $t03483334909._1
825+ let strAssetIdB = $t03483334909._2
826+ let assetIdA = $t03483334909._3
827+ let assetIdB = $t03483334909._4
828+ let $t03492235028 = getPoolBalances(i.caller, assetIdA, assetIdB)
829+ let balanceA = $t03492235028._1
830+ let balanceB = $t03492235028._2
831+ let accountBalanceA = $t03492235028._3
832+ let accountBalanceB = $t03492235028._4
626833 let amountEnrollA = (accountBalanceA - balanceA)
627834 let amountEnrollB = (accountBalanceB - balanceB)
628835 if ((moneyBoxAddress != i.originCaller))
649856 then invoke(this, "stakeUnstake", [true, amountEnrollB, strAssetIdB], nil)
650857 else 0
651858 if ((stake2 == stake2))
652- then $Tuple2(nil, [IntegerEntry(kBalanceA, (balanceA + amountEnrollA)), IntegerEntry(kBalanceB, (balanceB + amountEnrollB))])
859+ then $Tuple2(nil, $Tuple2([IntegerEntry(kBalanceA, (balanceA + amountEnrollA)), IntegerEntry(kBalanceB, (balanceB + amountEnrollB))], nil))
653860 else throw("Strict value is not equal to itself.")
654861 }
655862 else throw("Strict value is not equal to itself.")
656863 }
657- })
864+ }))
658865
659866
660867 @Verifier(tx)
Full:
OldNewDifferences
1-{-# STDLIB_VERSION 5 #-}
1+{-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let version = "1.0.0"
55
66 let kVersion = "version"
77
88 let kActive = "active"
99
1010 let kAssetIdA = "A_asset_id"
1111
1212 let kAssetIdB = "B_asset_id"
1313
1414 let kBalanceA = "A_asset_balance"
1515
1616 let kBalanceB = "B_asset_balance"
1717
1818 let kBalanceInitA = "A_asset_init"
1919
2020 let kBalanceInitB = "B_asset_init"
2121
2222 let kShareAssetId = "share_asset_id"
2323
2424 let kShareAssetSupply = "share_asset_supply"
2525
2626 let kFee = "commission"
2727
2828 let kCause = "shutdown_cause"
2929
3030 let kFirstHarvest = "first_harvest"
3131
3232 let kFirstHarvestHeight = "first_harvest_height"
3333
3434 let kShareLimit = "share_limit_on_first_harvest"
3535
3636 let kBasePeriod = "base_period"
3737
3838 let kPeriodLength = "period_length"
3939
4040 let kStartHeight = "start_height"
4141
4242 let kUSDNAddress = "staking_usdnnsbt_address"
4343
4444 let kEURNAddress = "staking_eurn_address"
4545
4646 let kLeasingAmount = "leasing_amount"
4747
4848 let kUSDNAssetId = "usdn_asset_id"
4949
5050 let kEURNAssetId = "eurn_asset_id"
5151
5252 let kStakingAssets = "staking_assets"
5353
5454 let kOracleActive = "active_all_contracts"
5555
5656 let kOracleActiveExchangers = "active_global_exchangers"
5757
58+let kDiscounts = "discounts"
59+
60+let kDiscountValues = "discount_values"
61+
62+let kUserSwopInGov = "_SWOP_amount"
63+
64+let kOraclePool = "pool_"
65+
5866 let kAdminPubKey1 = "admin_pub_1"
5967
6068 let kAdminPubKey2 = "admin_pub_2"
6169
6270 let kAdminPubKey3 = "admin_pub_3"
6371
6472 let kAdminInvokePubKey = "admin_invoke_pub"
6573
6674 let kMoneyBoxAddress = "money_box_address"
6775
6876 let kVotingAddress = "voting_address"
77+
78+let kGovAddress = "governance_address"
79+
80+let kFarmingAddress = "farming_address"
6981
7082 let oracle = Address(base58'3NBBWfzZtZtszaXbitTKnrB2xXwv26Bn7H9')
7183
7284 func getBase58FromOracle (key) = match getString(oracle, key) {
7385 case string: String =>
7486 fromBase58String(string)
7587 case nothing =>
7688 throw((key + "is empty"))
7789 }
7890
7991
8092 let adminPubKey1 = getBase58FromOracle(kAdminPubKey1)
8193
8294 let adminPubKey2 = getBase58FromOracle(kAdminPubKey2)
8395
8496 let adminPubKey3 = getBase58FromOracle(kAdminPubKey3)
8597
8698 let adminInvokePubKey = getBase58FromOracle(kAdminInvokePubKey)
8799
88100 let moneyBoxAddress = Address(getBase58FromOracle(kMoneyBoxAddress))
89101
90102 let votingAddress = Address(getBase58FromOracle(kVotingAddress))
103+
104+let govAddress = Address(getBase58FromOracle(kGovAddress))
105+
106+let farmingAddress = Address(getBase58FromOracle(kFarmingAddress))
91107
92108 let USDN = getBase58FromOracle(kUSDNAssetId)
93109
94110 let EURN = getBase58FromOracle(kEURNAssetId)
95111
96112 let stakingAssets = getStringValue(oracle, kStakingAssets)
97113
98114 let stakingUSDNAddress = Address(getBase58FromOracle(kUSDNAddress))
99115
100116 let stakingEURNAddress = Address(getBase58FromOracle(kEURNAddress))
101117
102118 let basePeriod = valueOrErrorMessage(getInteger(votingAddress, kBasePeriod), "Empty kBasePeriod")
103119
104120 let startHeight = valueOrErrorMessage(getInteger(votingAddress, kStartHeight), "Empty kStartHeight")
105121
106122 let periodLength = valueOrErrorMessage(getInteger(votingAddress, kPeriodLength), "Empty kPeriodLength")
107123
108124 let firstHarvestEndPeriod = ((basePeriod + ((height - startHeight) / periodLength)) + 3)
109125
110126 let active = if (getBooleanValue(oracle, kOracleActive))
111127 then getBooleanValue(oracle, kOracleActiveExchangers)
112128 else false
113129
114130 let feeScale6 = 1000000
115131
116132 let scale8 = 100000000
117133
118134 func accountBalance (assetId,pool) = match assetId {
119135 case id: ByteVector =>
120136 assetBalance(pool, id)
121137 case waves: Unit =>
122138 wavesBalance(pool).available
123139 case _ =>
124140 throw("Match error")
125141 }
126142
127143
128144 func stakedAmount (assetId,pool) = {
129145 let stakedAmountCalculated = match assetId {
130146 case aId: ByteVector =>
131147 if ((aId == USDN))
132148 then getInteger(stakingUSDNAddress, ((("rpd_balance_" + toBase58String(aId)) + "_") + toString(pool)))
133149 else if ((aId == EURN))
134150 then getInteger(stakingEURNAddress, ((("%s%s%s__stakingBalance__" + toBase58String(aId)) + "__") + toString(pool)))
135151 else 0
136152 case _: Unit =>
137153 valueOrElse(getInteger(pool, kLeasingAmount), 0)
138154 case _ =>
139155 throw("Match error")
140156 }
141157 match stakedAmountCalculated {
142158 case i: Int =>
143159 i
144160 case _ =>
145161 0
146162 }
147163 }
148164
149165
150166 func getAssetInfo (assetId) = match assetId {
151167 case id: String|ByteVector =>
152- let $t036343806 = match id {
168+ let $t039674139 = match id {
153169 case aId: ByteVector =>
154170 $Tuple2(toBase58String(aId), aId)
155171 case aId: String =>
156172 $Tuple2(aId, fromBase58String(aId))
157173 case _ =>
158174 throw("Match error")
159175 }
160- let stringId = $t036343806._1
161- let bytesId = $t036343806._2
176+ let stringId = $t039674139._1
177+ let bytesId = $t039674139._2
162178 let info = valueOrErrorMessage(assetInfo(bytesId), (("Asset " + stringId) + " doesn't exist"))
163179 $Tuple3(stringId, info.name, info.decimals)
164180 case waves: Unit =>
165181 $Tuple3("WAVES", "WAVES", 8)
166182 case _ =>
167183 throw("Match error")
168184 }
169185
170186
171187 func suspend (cause) = [BooleanEntry(kActive, false), StringEntry(kCause, cause)]
172188
173189
190+func calculateFeeDiscount (userAddr) = {
191+ let swopAmount = valueOrElse(getInteger(govAddress, (toString(userAddr) + kUserSwopInGov)), 0)
192+ let discountValues = split(getStringValue(oracle, kDiscountValues), ",")
193+ let discounts = split(getStringValue(oracle, kDiscounts), ",")
194+ if (if ((swopAmount >= parseIntValue(discountValues[0])))
195+ then (parseIntValue(discountValues[1]) > swopAmount)
196+ else false)
197+ then (feeScale6 - parseIntValue(discounts[0]))
198+ else if (if ((swopAmount >= parseIntValue(discountValues[1])))
199+ then (parseIntValue(discountValues[2]) > swopAmount)
200+ else false)
201+ then (feeScale6 - parseIntValue(discounts[1]))
202+ else if (if ((swopAmount >= parseIntValue(discountValues[2])))
203+ then (parseIntValue(discountValues[3]) > swopAmount)
204+ else false)
205+ then (feeScale6 - parseIntValue(discounts[2]))
206+ else if (if ((swopAmount >= parseIntValue(discountValues[3])))
207+ then (parseIntValue(discountValues[4]) > swopAmount)
208+ else false)
209+ then (feeScale6 - parseIntValue(discounts[3]))
210+ else if ((swopAmount >= parseIntValue(discountValues[4])))
211+ then (feeScale6 - parseIntValue(discounts[4]))
212+ else feeScale6
213+ }
214+
215+
174216 func calculateFees (pmtAmount,minAmountToReceive,tokenFrom,tokenTo,fee,feeGovernance) = {
175217 let amountWithoutFee = fraction(tokenTo, pmtAmount, (pmtAmount + tokenFrom))
176218 let amountWithFee = fraction(amountWithoutFee, (feeScale6 - fee), feeScale6)
177219 let governanceReward = fraction(amountWithoutFee, feeGovernance, feeScale6)
178220 if ((minAmountToReceive > amountWithFee))
179221 then throw(((("Calculated amount to receive " + toString(amountWithFee)) + " is less than specified minimum ") + toString(minAmountToReceive)))
180222 else $Tuple3(amountWithoutFee, amountWithFee, governanceReward)
181223 }
182224
183225
226+func calculateVirtGet (pmtAmount,balance,fee) = {
227+ let a = 1
228+ let b = (((balance + fraction(balance, (feeScale6 - fee), feeScale6)) + fraction(pmtAmount, (feeScale6 - fee), feeScale6)) - pmtAmount)
229+ let c = (-(toBigInt(balance)) * toBigInt(pmtAmount))
230+ let D = ((toBigInt(b) * toBigInt(b)) - ((toBigInt(4) * toBigInt(a)) * c))
231+ (toInt(((-(toBigInt(b)) + pow(D, 0, toBigInt(5), 1, 0, DOWN)) / toBigInt(2))) * a)
232+ }
233+
234+
235+func parsePaymentAsset (assetId) = if ((assetId == base58''))
236+ then unit
237+ else assetId
238+
239+
184240 func suspendSuspicious (accountBalanceA,accountBalanceB,balanceA,balanceB,assetIdA,assetIdB) = suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(accountBalanceA)) + " ") + assetIdA) + ", ") + toString(accountBalanceB)) + " ") + assetIdB) + ". State: ") + toString(balanceA)) + " ") + assetIdA) + ", ") + toString(balanceB)) + " ") + assetIdB))
185241
186242
187243 func isActive () = if (active)
188244 then unit
189245 else throw("DApp is inactive at this moment")
246+
247+
248+func isOraclePool (poolAddress) = if (isDefined(getString(oracle, (kOraclePool + poolAddress))))
249+ then unit
250+ else throw("DApp is not registered pool")
190251
191252
192253 func getPoolBalances (pool,assetIdA,assetIdB) = {
193254 let balanceA = getIntegerValue(pool, kBalanceA)
194255 let balanceB = getIntegerValue(pool, kBalanceB)
195256 let stakedAmountA = stakedAmount(assetIdA, pool)
196257 let stakedAmountB = stakedAmount(assetIdB, pool)
197258 let accountBalanceA = (accountBalance(assetIdA, pool) + stakedAmountA)
198259 let accountBalanceB = (accountBalance(assetIdB, pool) + stakedAmountB)
199260 let shareSupply = getIntegerValue(pool, kShareAssetSupply)
200261 $Tuple5(balanceA, balanceB, accountBalanceA, accountBalanceB, shareSupply)
201262 }
202263
203264
204265 func getPoolAssets (pool) = {
205266 let strAssetIdA = getStringValue(pool, kAssetIdA)
206267 let strAssetIdB = getStringValue(pool, kAssetIdB)
207268 let assetIdA = if ((strAssetIdA == "WAVES"))
208269 then unit
209270 else fromBase58String(strAssetIdA)
210271 let assetIdB = if ((strAssetIdB == "WAVES"))
211272 then unit
212273 else fromBase58String(strAssetIdB)
213274 let shareAssetId = fromBase58String(getStringValue(pool, kShareAssetId))
214275 $Tuple5(strAssetIdA, strAssetIdB, assetIdA, assetIdB, shareAssetId)
215276 }
216277
217278
218-func getFeeParams (pool) = {
219- let fee = getIntegerValue(pool, kFee)
220- let govFee = fraction(fee, 40, 100)
279+func getFeeParams (pool,caller) = {
280+ let feeDiscount = calculateFeeDiscount(caller)
281+ let fee = fraction(getIntegerValue(pool, kFee), feeDiscount, feeScale6, CEILING)
282+ let govFee = fraction(fraction(fee, 40, 100), feeDiscount, feeScale6, CEILING)
221283 $Tuple2(fee, govFee)
222284 }
223285
224286
225287 @Callable(i)
226288 func init (callerBytes,args,pAmounts,pAssetIds) = {
227289 let caller = Address(callerBytes)
228- let $t066046663 = $Tuple2(pAmounts[0], pAssetIds[0])
229- let pmtAmountA = $t066046663._1
230- let pmtAssetIdA = $t066046663._2
231- let $t066686727 = $Tuple2(pAmounts[1], pAssetIds[1])
232- let pmtAmountB = $t066686727._1
233- let pmtAssetIdB = $t066686727._2
290+ let $t088518929 = $Tuple2(pAmounts[0], parsePaymentAsset(pAssetIds[0]))
291+ let pmtAmountA = $t088518929._1
292+ let pmtAssetIdA = $t088518929._2
293+ let $t089349012 = $Tuple2(pAmounts[1], parsePaymentAsset(pAssetIds[1]))
294+ let pmtAmountB = $t089349012._1
295+ let pmtAssetIdB = $t089349012._2
234296 if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminInvokePubKey], i.originCallerPublicKey)))
235297 then throw("Only admin can call this function")
236298 else if (isDefined(getBoolean(caller, kActive)))
237299 then throw("DApp is already active")
238300 else if ((pmtAssetIdA == pmtAssetIdB))
239301 then throw("Assets must be different")
240302 else {
241- let $t070977174 = getAssetInfo(pmtAssetIdA)
242- let pmtStrAssetIdA = $t070977174._1
243- let pmtAssetNameA = $t070977174._2
244- let pmtDecimalsA = $t070977174._3
245- let $t071837260 = getAssetInfo(pmtAssetIdB)
246- let pmtStrAssetIdB = $t071837260._1
247- let pmtAssetNameB = $t071837260._2
248- let pmtDecimalsB = $t071837260._3
303+ let $t093829459 = getAssetInfo(pmtAssetIdA)
304+ let pmtStrAssetIdA = $t093829459._1
305+ let pmtAssetNameA = $t093829459._2
306+ let pmtDecimalsA = $t093829459._3
307+ let $t094689545 = getAssetInfo(pmtAssetIdB)
308+ let pmtStrAssetIdB = $t094689545._1
309+ let pmtAssetNameB = $t094689545._2
310+ let pmtDecimalsB = $t094689545._3
249311 let firstHarvest = (args[0] == "true")
250312 let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
251313 let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
252314 let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
253315 let arg1 = pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN)
254316 let arg2 = pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN)
255317 let arg3 = pow(10, 0, shareDecimals, 0, 0, DOWN)
256318 let shareInitialSupply = fraction(arg1, arg2, arg3)
257319 let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
258320 let shareIssueId = calculateAssetId(shareIssue)
259321 let stake1 = if (contains(stakingAssets, pmtStrAssetIdA))
260322 then invoke(i.caller, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
261323 else 0
262324 if ((stake1 == stake1))
263325 then {
264326 let stake2 = if (contains(stakingAssets, pmtStrAssetIdB))
265327 then invoke(i.caller, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
266328 else 0
267329 if ((stake2 == stake2))
268330 then {
269331 let baseEntry = [StringEntry(kVersion, version), BooleanEntry(kActive, true), StringEntry(kAssetIdA, pmtStrAssetIdA), StringEntry(kAssetIdB, pmtStrAssetIdB), IntegerEntry(kBalanceA, pmtAmountA), IntegerEntry(kBalanceB, pmtAmountB), IntegerEntry(kFee, getIntegerValue(oracle, "base_fee_cpmm")), shareIssue, StringEntry(kShareAssetId, toBase58String(shareIssueId)), IntegerEntry(kShareAssetSupply, shareInitialSupply), ScriptTransfer(caller, shareInitialSupply, shareIssueId)]
270332 if (firstHarvest)
271- then $Tuple2(nil, (baseEntry ++ [BooleanEntry(kFirstHarvest, firstHarvest), IntegerEntry(kFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))]))
272- else $Tuple2(nil, baseEntry)
333+ then $Tuple2(nil, $Tuple2((baseEntry ++ [BooleanEntry(kFirstHarvest, firstHarvest), IntegerEntry(kFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))]), nil))
334+ else $Tuple2(nil, $Tuple2(baseEntry, nil))
273335 }
274336 else throw("Strict value is not equal to itself.")
275337 }
276338 else throw("Strict value is not equal to itself.")
277339 }
278340 }
279341
280342
281343
282344 @Callable(i)
283345 func initWithInitRatio (callerBytes,args,pAmounts,pAssetIds) = {
284346 let caller = Address(callerBytes)
285- let $t094939693 = $Tuple5(parseIntValue(args[0]), parseIntValue(args[1]), args[2], args[3], (args[4] == "true"))
286- let amtAssetA = $t094939693._1
287- let amtAssetB = $t094939693._2
288- let assetIdAStr = $t094939693._3
289- let assetIdBStr = $t094939693._4
290- let firstHarvest = $t094939693._5
347+ let $t01179011990 = $Tuple5(parseIntValue(args[0]), parseIntValue(args[1]), args[2], args[3], (args[4] == "true"))
348+ let amtAssetA = $t01179011990._1
349+ let amtAssetB = $t01179011990._2
350+ let assetIdAStr = $t01179011990._3
351+ let assetIdBStr = $t01179011990._4
352+ let firstHarvest = $t01179011990._5
291353 if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminInvokePubKey], i.originCallerPublicKey)))
292354 then throw("Only admin can call this function")
293355 else if (isDefined(getBoolean(caller, kActive)))
294356 then throw("DApp is already active")
295357 else if ((assetIdAStr == assetIdBStr))
296358 then throw("Assets must be different")
297359 else {
298- let $t01006310140 = getAssetInfo(assetIdAStr)
299- let pmtStrAssetIdA = $t01006310140._1
300- let pmtAssetNameA = $t01006310140._2
301- let pmtDecimalsA = $t01006310140._3
302- let $t01014910226 = getAssetInfo(assetIdBStr)
303- let pmtStrAssetIdB = $t01014910226._1
304- let pmtAssetNameB = $t01014910226._2
305- let pmtDecimalsB = $t01014910226._3
360+ let $t01236012437 = getAssetInfo(assetIdAStr)
361+ let pmtStrAssetIdA = $t01236012437._1
362+ let pmtAssetNameA = $t01236012437._2
363+ let pmtDecimalsA = $t01236012437._3
364+ let $t01244612523 = getAssetInfo(assetIdBStr)
365+ let pmtStrAssetIdB = $t01244612523._1
366+ let pmtAssetNameB = $t01244612523._2
367+ let pmtDecimalsB = $t01244612523._3
306368 let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
307369 let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
308370 let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
309371 let shareInitialSupply = 0
310372 let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
311373 let shareIssueId = calculateAssetId(shareIssue)
312374 let baseEntry = [StringEntry(kVersion, version), BooleanEntry(kActive, true), StringEntry(kAssetIdA, pmtStrAssetIdA), StringEntry(kAssetIdB, pmtStrAssetIdB), IntegerEntry(kBalanceInitA, amtAssetA), IntegerEntry(kBalanceInitB, amtAssetB), IntegerEntry(kBalanceA, 0), IntegerEntry(kBalanceB, 0), IntegerEntry(kFee, getIntegerValue(oracle, "base_fee_cpmm")), shareIssue, StringEntry(kShareAssetId, toBase58String(shareIssueId)), IntegerEntry(kShareAssetSupply, shareInitialSupply)]
313375 if (firstHarvest)
314- then $Tuple2(nil, (baseEntry ++ [BooleanEntry(kFirstHarvest, firstHarvest), IntegerEntry(kFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))]))
315- else $Tuple2(nil, baseEntry)
376+ then $Tuple2(nil, $Tuple2((baseEntry ++ [BooleanEntry(kFirstHarvest, firstHarvest), IntegerEntry(kFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))]), nil))
377+ else $Tuple2(nil, $Tuple2(baseEntry, nil))
316378 }
317379 }
318380
319381
320382
321383 @Callable(i)
322-func keepLimitForFirstHarvest (callerBytes,args,pAmounts,pAssetIds) = valueOrElse(isActive(), if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminInvokePubKey], i.originCallerPublicKey)))
384+func keepLimitForFirstHarvest (callerBytes,args,pAmounts,pAssetIds) = valueOrElse(isOraclePool(toString(i.caller)), valueOrElse(isActive(), if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminInvokePubKey], i.originCallerPublicKey)))
323385 then throw("Only admin can call this function")
324386 else {
325387 let shareLimit = parseIntValue(args[0])
326- $Tuple2(nil, [IntegerEntry(kShareLimit, shareLimit)])
327- })
388+ $Tuple2(nil, $Tuple2([IntegerEntry(kShareLimit, shareLimit)], nil))
389+ }))
328390
329391
330392
331393 @Callable(i)
332-func exchange (callerBytes,args,pAmounts,pAssetIds) = valueOrElse(isActive(), {
394+func exchange (callerBytes,args,pAmounts,pAssetIds) = valueOrElse(isOraclePool(toString(i.caller)), valueOrElse(isActive(), {
333395 let caller = Address(callerBytes)
334- let $t01232612383 = $Tuple2(pAmounts[0], pAssetIds[0])
335- let pmtAmount = $t01232612383._1
336- let pmtAssetId = $t01232612383._2
396+ let $t01484814924 = $Tuple2(pAmounts[0], parsePaymentAsset(pAssetIds[0]))
397+ let pmtAmount = $t01484814924._1
398+ let pmtAssetId = $t01484814924._2
337399 let minAmountToReceive = parseIntValue(args[0])
338- let $t01244012516 = getPoolAssets(i.caller)
339- let strAssetIdA = $t01244012516._1
340- let strAssetIdB = $t01244012516._2
341- let assetIdA = $t01244012516._3
342- let assetIdB = $t01244012516._4
343- let $t01252112627 = getPoolBalances(i.caller, assetIdA, assetIdB)
344- let balanceA = $t01252112627._1
345- let balanceB = $t01252112627._2
346- let accountBalanceA = $t01252112627._3
347- let accountBalanceB = $t01252112627._4
400+ let $t01499715073 = getPoolAssets(i.caller)
401+ let strAssetIdA = $t01499715073._1
402+ let strAssetIdB = $t01499715073._2
403+ let assetIdA = $t01499715073._3
404+ let assetIdB = $t01499715073._4
405+ let $t01508615192 = getPoolBalances(i.caller, assetIdA, assetIdB)
406+ let balanceA = $t01508615192._1
407+ let balanceB = $t01508615192._2
408+ let accountBalanceA = $t01508615192._3
409+ let accountBalanceB = $t01508615192._4
348410 if (if ((balanceA == 0))
349411 then true
350412 else (balanceB == 0))
351413 then throw("Can't exchange with zero balance")
352414 else if ((0 >= minAmountToReceive))
353415 then throw(("Minimal amount to receive must be positive. Actual: " + toString(minAmountToReceive)))
354416 else if ((size(pAmounts) != 1))
355417 then throw("One attached payment expected")
356418 else if (!(containsElement([assetIdA, assetIdB], pmtAssetId)))
357419 then throw(((("Incorrect asset attached. Expected: " + strAssetIdA) + " or ") + strAssetIdB))
358420 else if (if ((balanceA > accountBalanceA))
359421 then true
360422 else (balanceB > accountBalanceB))
361423 then $Tuple2(nil, ([ScriptTransfer(caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious(accountBalanceA, accountBalanceB, balanceA, balanceB, strAssetIdA, strAssetIdB)))
362424 else {
363- let $t01339213434 = getFeeParams(i.caller)
364- let fee = $t01339213434._1
365- let govFee = $t01339213434._2
366- let $t01344313748 = if ((pmtAssetId == assetIdA))
425+ let $t01607716135 = getFeeParams(i.caller, i.originCaller)
426+ let fee = $t01607716135._1
427+ let govFee = $t01607716135._2
428+ let $t01615216489 = if ((pmtAssetId == assetIdA))
367429 then calculateFees(pmtAmount, minAmountToReceive, balanceA, balanceB, fee, govFee)
368430 else calculateFees(pmtAmount, minAmountToReceive, balanceB, balanceA, fee, govFee)
369- let amountWithoutFee = $t01344313748._1
370- let amountWithFee = $t01344313748._2
371- let governanceReward = $t01344313748._3
372- let $t01375814207 = if ((pmtAssetId == assetIdA))
431+ let amountWithoutFee = $t01615216489._1
432+ let amountWithFee = $t01615216489._2
433+ let governanceReward = $t01615216489._3
434+ let $t01650716832 = if ((pmtAssetId == assetIdA))
373435 then $Tuple3((balanceA + pmtAmount), ((balanceB - amountWithFee) - governanceReward), assetIdB)
374436 else $Tuple3(((balanceA - amountWithFee) - governanceReward), (balanceB + pmtAmount), assetIdA)
375- let newBalanceA = $t01375814207._1
376- let newBalanceB = $t01375814207._2
377- let assetIdSend = $t01375814207._3
378- let $t01421714435 = if ((pmtAssetId == assetIdA))
437+ let newBalanceA = $t01650716832._1
438+ let newBalanceB = $t01650716832._2
439+ let assetIdSend = $t01650716832._3
440+ let $t01685017100 = if ((pmtAssetId == assetIdA))
379441 then $Tuple2(pmtAmount, (amountWithFee + governanceReward))
380442 else $Tuple2((amountWithFee + governanceReward), pmtAmount)
381- let stakeAmountA = $t01421714435._1
382- let stakeAmountB = $t01421714435._2
443+ let stakeAmountA = $t01685017100._1
444+ let stakeAmountB = $t01685017100._2
383445 let stake1 = if (contains(stakingAssets, strAssetIdA))
384446 then invoke(i.caller, "stakeUnstake", [(pmtAssetId == assetIdA), stakeAmountA, strAssetIdA], nil)
385447 else 0
386448 if ((stake1 == stake1))
387449 then {
388450 let stake2 = if (contains(stakingAssets, strAssetIdB))
389451 then invoke(i.caller, "stakeUnstake", [(pmtAssetId == assetIdB), stakeAmountB, strAssetIdB], nil)
390452 else 0
391453 if ((stake2 == stake2))
392- then $Tuple2(nil, [IntegerEntry(kBalanceA, newBalanceA), IntegerEntry(kBalanceB, newBalanceB), ScriptTransfer(caller, amountWithFee, assetIdSend), ScriptTransfer(moneyBoxAddress, governanceReward, assetIdSend)])
454+ then $Tuple2(nil, $Tuple2([IntegerEntry(kBalanceA, newBalanceA), IntegerEntry(kBalanceB, newBalanceB), ScriptTransfer(caller, amountWithFee, assetIdSend), ScriptTransfer(moneyBoxAddress, governanceReward, assetIdSend)], [amountWithFee, assetIdSend]))
393455 else throw("Strict value is not equal to itself.")
394456 }
395457 else throw("Strict value is not equal to itself.")
396458 }
397- })
459+ }))
398460
399461
400462
401463 @Callable(i)
402-func replenishWithTwoTokens (callerBytes,args,pAmounts,pAssetIds) = valueOrElse(isActive(), {
464+func replenishWithTwoTokens (callerBytes,args,pAmounts,pAssetIds) = valueOrElse(isOraclePool(toString(i.caller)), valueOrElse(isActive(), {
403465 let caller = Address(callerBytes)
404- let pmtAssetIdA = pAssetIds[0]
405- let pmtAssetIdB = pAssetIds[1]
406- let $t01529715387 = getPoolAssets(i.caller)
407- let strAssetIdA = $t01529715387._1
408- let strAssetIdB = $t01529715387._2
409- let assetIdA = $t01529715387._3
410- let assetIdB = $t01529715387._4
411- let shareAssetId = $t01529715387._5
412- let $t01539215516 = getPoolBalances(i.caller, assetIdA, assetIdB)
413- let balanceA = $t01539215516._1
414- let balanceB = $t01539215516._2
415- let accountBalanceA = $t01539215516._3
416- let accountBalanceB = $t01539215516._4
417- let shareAssetSupply = $t01539215516._5
466+ let pmtAssetIdA = parsePaymentAsset(pAssetIds[0])
467+ let pmtAssetIdB = parsePaymentAsset(pAssetIds[1])
468+ let stakeFarming = (args[0] == "true")
469+ let $t01831218402 = getPoolAssets(i.caller)
470+ let strAssetIdA = $t01831218402._1
471+ let strAssetIdB = $t01831218402._2
472+ let assetIdA = $t01831218402._3
473+ let assetIdB = $t01831218402._4
474+ let shareAssetId = $t01831218402._5
475+ let $t01841518539 = getPoolBalances(i.caller, assetIdA, assetIdB)
476+ let balanceA = $t01841518539._1
477+ let balanceB = $t01841518539._2
478+ let accountBalanceA = $t01841518539._3
479+ let accountBalanceB = $t01841518539._4
480+ let shareAssetSupply = $t01841518539._5
418481 if ((size(pAmounts) != 2))
419482 then throw("Two attached assets expected")
420483 else if (if ((pmtAssetIdA != assetIdA))
421484 then true
422485 else (pmtAssetIdB != assetIdB))
423486 then throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
424487 else if (if ((balanceA > accountBalanceA))
425488 then true
426489 else (balanceB > accountBalanceB))
427490 then $Tuple2(nil, ([ScriptTransfer(caller, pAmounts[0], pmtAssetIdA), ScriptTransfer(caller, pAmounts[1], pmtAssetIdB)] ++ suspendSuspicious(accountBalanceA, accountBalanceB, balanceA, balanceB, strAssetIdA, strAssetIdB)))
428491 else {
429- let $t01610116178 = getAssetInfo(pmtAssetIdA)
430- let pmtStrAssetIdA = $t01610116178._1
431- let pmtAssetNameA = $t01610116178._2
432- let pmtDecimalsA = $t01610116178._3
433- let $t01618716264 = getAssetInfo(pmtAssetIdB)
434- let pmtStrAssetIdB = $t01618716264._1
435- let pmtAssetNameB = $t01618716264._2
436- let pmtDecimalsB = $t01618716264._3
492+ let $t01921119288 = getAssetInfo(pmtAssetIdA)
493+ let pmtStrAssetIdA = $t01921119288._1
494+ let pmtAssetNameA = $t01921119288._2
495+ let pmtDecimalsA = $t01921119288._3
496+ let $t01930519382 = getAssetInfo(pmtAssetIdB)
497+ let pmtStrAssetIdB = $t01930519382._1
498+ let pmtAssetNameB = $t01930519382._2
499+ let pmtDecimalsB = $t01930519382._3
437500 let initial = ((balanceA + balanceB) == 0)
438- let $t01632317078 = if (initial)
501+ let $t01945720300 = if (initial)
439502 then $Tuple5(pAmounts[0], pAmounts[1], 0, pmtAssetIdA, 1)
440503 else {
441504 let ratioShareTokensInA = fraction(scale8, pAmounts[0], balanceA)
442505 let ratioShareTokensInB = fraction(scale8, pAmounts[1], balanceB)
443506 if ((ratioShareTokensInB > ratioShareTokensInA))
444507 then {
445508 let pmt = fraction(pAmounts[0], balanceB, balanceA)
446509 $Tuple5(pAmounts[0], pmt, (pAmounts[1] - pmt), pmtAssetIdB, ratioShareTokensInA)
447510 }
448511 else {
449512 let pmt = fraction(pAmounts[1], balanceA, balanceB)
450513 $Tuple5(pmt, pAmounts[1], (pAmounts[0] - pmt), pmtAssetIdA, ratioShareTokensInB)
451514 }
452515 }
453- let pmtAmountA = $t01632317078._1
454- let pmtAmountB = $t01632317078._2
455- let change = $t01632317078._3
456- let changeAssetId = $t01632317078._4
457- let shareTokenRatio = $t01632317078._5
516+ let pmtAmountA = $t01945720300._1
517+ let pmtAmountB = $t01945720300._2
518+ let change = $t01945720300._3
519+ let changeAssetId = $t01945720300._4
520+ let shareTokenRatio = $t01945720300._5
458521 let shareTokenToPayAmount = if (initial)
459522 then {
460523 let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
461524 fraction(pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN), pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN), pow(10, 0, shareDecimals, 0, 0, DOWN))
462525 }
463526 else fraction(shareTokenRatio, shareAssetSupply, scale8)
464527 if ((shareTokenToPayAmount == 0))
465528 then throw("Too small amount to replenish")
466- else {
467- let stake1 = if (contains(stakingAssets, pmtStrAssetIdA))
468- then invoke(i.caller, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
469- else 0
470- if ((stake1 == stake1))
471- then {
472- let stake2 = if (contains(stakingAssets, pmtStrAssetIdB))
473- then invoke(i.caller, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
474- else 0
475- if ((stake2 == stake2))
476- then $Tuple2(nil, [Reissue(shareAssetId, shareTokenToPayAmount, true), IntegerEntry(kBalanceA, (balanceA + pmtAmountA)), IntegerEntry(kBalanceB, (balanceB + pmtAmountB)), IntegerEntry(kShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), ScriptTransfer(caller, shareTokenToPayAmount, shareAssetId), ScriptTransfer(caller, change, changeAssetId)])
477- else throw("Strict value is not equal to itself.")
478- }
479- else throw("Strict value is not equal to itself.")
480- }
529+ else if ((0 > change))
530+ then throw("Change < 0")
531+ else {
532+ let stake1 = if (contains(stakingAssets, pmtStrAssetIdA))
533+ then invoke(i.caller, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
534+ else 0
535+ if ((stake1 == stake1))
536+ then {
537+ let stake2 = if (contains(stakingAssets, pmtStrAssetIdB))
538+ then invoke(i.caller, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
539+ else 0
540+ if ((stake2 == stake2))
541+ then {
542+ let shareTokenST = if (stakeFarming)
543+ then {
544+ let reissue = invoke(i.caller, "reissueShareToken", [shareTokenToPayAmount], nil)
545+ if ((reissue == reissue))
546+ then {
547+ let stake3 = invoke(farmingAddress, "lockShareTokens", [toString(i.caller)], [AttachedPayment(shareAssetId, shareTokenToPayAmount)])
548+ if ((stake3 == stake3))
549+ then nil
550+ else throw("Strict value is not equal to itself.")
551+ }
552+ else throw("Strict value is not equal to itself.")
553+ }
554+ else [Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(caller, shareTokenToPayAmount, shareAssetId)]
555+ $Tuple2(nil, $Tuple2(([IntegerEntry(kBalanceA, (balanceA + pmtAmountA)), IntegerEntry(kBalanceB, (balanceB + pmtAmountB)), IntegerEntry(kShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), ScriptTransfer(caller, change, changeAssetId)] ++ shareTokenST), nil))
556+ }
557+ else throw("Strict value is not equal to itself.")
558+ }
559+ else throw("Strict value is not equal to itself.")
560+ }
481561 }
482- })
562+ }))
483563
484564
485565
486566 @Callable(i)
487-func replenishWithOneToken (callerBytes,args,pAmounts,pAssetIds) = valueOrElse(isActive(), {
567+func replenishWithOneToken (callerBytes,args,pAmounts,pAssetIds) = valueOrElse(isOraclePool(toString(i.caller)), valueOrElse(isActive(), {
488568 let caller = Address(callerBytes)
489- let pmtAssetId = pAssetIds[0]
569+ let pmtAssetId = parsePaymentAsset(pAssetIds[0])
490570 let pmtAmount = pAmounts[0]
491- let virtMinAmount = parseIntValue(args[0])
492- let $t01868518775 = getPoolAssets(i.caller)
493- let strAssetIdA = $t01868518775._1
494- let strAssetIdB = $t01868518775._2
495- let assetIdA = $t01868518775._3
496- let assetIdB = $t01868518775._4
497- let shareAssetId = $t01868518775._5
498- let $t01878018904 = getPoolBalances(i.caller, assetIdA, assetIdB)
499- let balanceA = $t01878018904._1
500- let balanceB = $t01878018904._2
501- let accountBalanceA = $t01878018904._3
502- let accountBalanceB = $t01878018904._4
503- let shareAssetSupply = $t01878018904._5
571+ let virtGetMinAmount = parseIntValue(args[0])
572+ let stakeFarming = (args[1] == "true")
573+ let $t02285522945 = getPoolAssets(i.caller)
574+ let strAssetIdA = $t02285522945._1
575+ let strAssetIdB = $t02285522945._2
576+ let assetIdA = $t02285522945._3
577+ let assetIdB = $t02285522945._4
578+ let shareAssetId = $t02285522945._5
579+ let $t02295823082 = getPoolBalances(i.caller, assetIdA, assetIdB)
580+ let balanceA = $t02295823082._1
581+ let balanceB = $t02295823082._2
582+ let accountBalanceA = $t02295823082._3
583+ let accountBalanceB = $t02295823082._4
584+ let shareAssetSupply = $t02295823082._5
504585 let initial = ((balanceA + balanceB) == 0)
505586 if ((size(pAmounts) != 1))
506587 then throw("One attached assets expected")
507588 else if (if ((pmtAssetId != assetIdA))
508589 then (pmtAssetId != assetIdB)
509590 else false)
510591 then throw(((("Incorrect asset attached. Expected: " + strAssetIdA) + " or ") + strAssetIdB))
511592 else if (initial)
512593 then throw("For initial exchanger you need to use two tokens")
513594 else if (if ((balanceA > accountBalanceA))
514595 then true
515596 else (balanceB > accountBalanceB))
516597 then $Tuple2(nil, ([ScriptTransfer(caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious(accountBalanceA, accountBalanceB, balanceA, balanceB, strAssetIdA, strAssetIdB)))
517598 else {
518- let $t01955519597 = getFeeParams(i.caller)
519- let fee = $t01955519597._1
520- let govFee = $t01955519597._2
521- let $t01960621113 = if ((pmtAssetId == assetIdA))
599+ let $t02383623894 = getFeeParams(i.caller, i.originCaller)
600+ let fee = $t02383623894._1
601+ let govFee = $t02383623894._2
602+ let $t02391125797 = if ((pmtAssetId == assetIdA))
522603 then {
523- let $t01976719898 = calculateFees(pmtAmount, virtMinAmount, balanceA, balanceB, fee, govFee)
524- let amountWithoutFee = $t01976719898._1
525- let amountWithFee = $t01976719898._2
526- let governanceReward = $t01976719898._3
604+ let virtPayAmount = calculateVirtGet(pmtAmount, balanceA, fee)
605+ let $t02419024327 = calculateFees(virtPayAmount, virtGetMinAmount, balanceA, balanceB, fee, govFee)
606+ let amountWithoutFee = $t02419024327._1
607+ let amountWithFee = $t02419024327._2
608+ let governanceReward = $t02419024327._3
527609 let newBalanceA = (balanceA + pmtAmount)
528610 let newBalanceB = (balanceB - governanceReward)
529- let ratioShareTokensInA = fraction((pmtAmount / 2), scale8, newBalanceA)
611+ let ratioShareTokensInA = fraction((pmtAmount - virtPayAmount), scale8, newBalanceA)
530612 let ratioShareTokensInB = fraction(amountWithFee, scale8, newBalanceB)
531613 let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scale8)
532- $Tuple6(newBalanceA, newBalanceB, shareTokenToPayAmount, governanceReward, assetIdB, strAssetIdB)
614+ $Tuple7(newBalanceA, newBalanceB, shareTokenToPayAmount, governanceReward, assetIdB, strAssetIdB, strAssetIdA)
533615 }
534616 else {
535- let $t02045720588 = calculateFees(pmtAmount, virtMinAmount, balanceB, balanceA, fee, govFee)
536- let amountWithoutFee = $t02045720588._1
537- let amountWithFee = $t02045720588._2
538- let governanceReward = $t02045720588._3
617+ let virtPayAmount = calculateVirtGet(pmtAmount, balanceB, fee)
618+ let $t02506225199 = calculateFees(virtPayAmount, virtGetMinAmount, balanceB, balanceA, fee, govFee)
619+ let amountWithoutFee = $t02506225199._1
620+ let amountWithFee = $t02506225199._2
621+ let governanceReward = $t02506225199._3
539622 let newBalanceA = (balanceA - governanceReward)
540623 let newBalanceB = (balanceB + pmtAmount)
541624 let ratioShareTokensInA = fraction(amountWithFee, scale8, newBalanceA)
542- let ratioShareTokensInB = fraction((pmtAmount / 2), scale8, newBalanceB)
625+ let ratioShareTokensInB = fraction((pmtAmount - virtPayAmount), scale8, newBalanceB)
543626 let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scale8)
544- $Tuple6(newBalanceA, newBalanceB, shareTokenToPayAmount, governanceReward, assetIdA, strAssetIdA)
627+ $Tuple7(newBalanceA, newBalanceB, shareTokenToPayAmount, governanceReward, assetIdA, strAssetIdA, strAssetIdB)
545628 }
546- let newBalanceA = $t01960621113._1
547- let newBalanceB = $t01960621113._2
548- let shareTokenToPayAmount = $t01960621113._3
549- let govReward = $t01960621113._4
550- let govRewardAsset = $t01960621113._5
551- let govRewardAssetStr = $t01960621113._6
629+ let newBalanceA = $t02391125797._1
630+ let newBalanceB = $t02391125797._2
631+ let shareTokenToPayAmount = $t02391125797._3
632+ let govReward = $t02391125797._4
633+ let govRewardAsset = $t02391125797._5
634+ let govRewardAssetStr = $t02391125797._6
635+ let pmtAssetIdStr = $t02391125797._7
552636 if ((shareTokenToPayAmount == 0))
553637 then throw("Too small amount to replenish")
554638 else {
555- let stake1 = if (contains(stakingAssets, govRewardAssetStr))
556- then invoke(i.caller, "stakeUnstake", [false, govReward, govRewardAssetStr], nil)
639+ let stake1 = if (contains(stakingAssets, pmtAssetIdStr))
640+ then invoke(i.caller, "stakeUnstake", [true, pmtAmount, pmtAssetIdStr], nil)
557641 else 0
558642 if ((stake1 == stake1))
559- then $Tuple2(nil, [IntegerEntry(kBalanceA, newBalanceA), IntegerEntry(kBalanceB, newBalanceB), IntegerEntry(kShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(caller, shareTokenToPayAmount, shareAssetId), ScriptTransfer(moneyBoxAddress, govReward, govRewardAsset)])
643+ then {
644+ let stake2 = if (contains(stakingAssets, govRewardAssetStr))
645+ then invoke(i.caller, "stakeUnstake", [false, govReward, govRewardAssetStr], nil)
646+ else 0
647+ if ((stake2 == stake2))
648+ then {
649+ let shareTokenST = if (stakeFarming)
650+ then {
651+ let reissue = invoke(i.caller, "reissueShareToken", [shareTokenToPayAmount], nil)
652+ if ((reissue == reissue))
653+ then {
654+ let stake3 = invoke(farmingAddress, "lockShareTokens", [toString(i.caller)], [AttachedPayment(shareAssetId, shareTokenToPayAmount)])
655+ if ((stake3 == stake3))
656+ then nil
657+ else throw("Strict value is not equal to itself.")
658+ }
659+ else throw("Strict value is not equal to itself.")
660+ }
661+ else [Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(caller, shareTokenToPayAmount, shareAssetId)]
662+ $Tuple2(nil, $Tuple2(([IntegerEntry(kBalanceA, newBalanceA), IntegerEntry(kBalanceB, newBalanceB), IntegerEntry(kShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), ScriptTransfer(moneyBoxAddress, govReward, govRewardAsset)] ++ shareTokenST), nil))
663+ }
664+ else throw("Strict value is not equal to itself.")
665+ }
560666 else throw("Strict value is not equal to itself.")
561667 }
562668 }
563- })
669+ }))
564670
565671
566672
567673 @Callable(i)
568-func withdraw (callerBytes,args,pAmounts,pAssetIds) = valueOrElse(isActive(), {
674+func withdraw (callerBytes,args,pAmounts,pAssetIds) = valueOrElse(isOraclePool(toString(i.caller)), valueOrElse(isActive(), {
569675 let caller = Address(callerBytes)
570- let $t02206722124 = $Tuple2(pAmounts[0], pAssetIds[0])
571- let pmtAmount = $t02206722124._1
572- let pmtAssetId = $t02206722124._2
573- let $t02213022220 = getPoolAssets(i.caller)
574- let strAssetIdA = $t02213022220._1
575- let strAssetIdB = $t02213022220._2
576- let assetIdA = $t02213022220._3
577- let assetIdB = $t02213022220._4
578- let shareAssetId = $t02213022220._5
579- let $t02222522349 = getPoolBalances(i.caller, assetIdA, assetIdB)
580- let balanceA = $t02222522349._1
581- let balanceB = $t02222522349._2
582- let accountBalanceA = $t02222522349._3
583- let accountBalanceB = $t02222522349._4
584- let shareAssetSupply = $t02222522349._5
676+ let $t02760927699 = getPoolAssets(i.caller)
677+ let strAssetIdA = $t02760927699._1
678+ let strAssetIdB = $t02760927699._2
679+ let assetIdA = $t02760927699._3
680+ let assetIdB = $t02760927699._4
681+ let shareAssetId = $t02760927699._5
682+ let $t02771227836 = getPoolBalances(i.caller, assetIdA, assetIdB)
683+ let balanceA = $t02771227836._1
684+ let balanceB = $t02771227836._2
685+ let accountBalanceA = $t02771227836._3
686+ let accountBalanceB = $t02771227836._4
687+ let shareAssetSupply = $t02771227836._5
688+ let $t02784928257 = if ((size(pAmounts) == 1))
689+ then {
690+ let pAsset = parsePaymentAsset(pAssetIds[0])
691+ if ((pAsset != shareAssetId))
692+ then throw(("Incorrect asset attached. Expected: " + toBase58String(shareAssetId)))
693+ else $Tuple2(pAmounts[0], pAsset)
694+ }
695+ else $Tuple2(0, shareAssetId)
696+ let pmtAmount = $t02784928257._1
697+ let pmtAssetId = $t02784928257._2
698+ if ((size(pAmounts) > 1))
699+ then throw("One attached payment expected")
700+ else if (if ((balanceA > accountBalanceA))
701+ then true
702+ else (balanceB > accountBalanceB))
703+ then $Tuple2(nil, ([ScriptTransfer(caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious(accountBalanceA, accountBalanceB, balanceA, balanceB, strAssetIdA, strAssetIdB)))
704+ else {
705+ let unlockAmount = parseIntValue(valueOrElse(args[0], "0"))
706+ let unlock = if ((unlockAmount > 0))
707+ then invoke(farmingAddress, "withdrawShareTokens", [toString(i.caller), unlockAmount], nil)
708+ else 0
709+ if ((unlock == unlock))
710+ then {
711+ let withdrawAmount = (pmtAmount + unlockAmount)
712+ let amountToPayA = fraction(withdrawAmount, balanceA, shareAssetSupply)
713+ let amountToPayB = fraction(withdrawAmount, balanceB, shareAssetSupply)
714+ let stake1 = if (contains(stakingAssets, strAssetIdA))
715+ then invoke(i.caller, "stakeUnstake", [false, amountToPayA, strAssetIdA], nil)
716+ else 0
717+ if ((stake1 == stake1))
718+ then {
719+ let stake2 = if (contains(stakingAssets, strAssetIdB))
720+ then invoke(i.caller, "stakeUnstake", [false, amountToPayB, strAssetIdB], nil)
721+ else 0
722+ if ((stake2 == stake2))
723+ then $Tuple2([ScriptTransfer(i.caller, unlockAmount, shareAssetId)], $Tuple2([IntegerEntry(kBalanceA, (balanceA - amountToPayA)), IntegerEntry(kBalanceB, (balanceB - amountToPayB)), IntegerEntry(kShareAssetSupply, (shareAssetSupply - withdrawAmount)), Burn(shareAssetId, withdrawAmount), ScriptTransfer(caller, amountToPayA, assetIdA), ScriptTransfer(caller, amountToPayB, assetIdB)], nil))
724+ else throw("Strict value is not equal to itself.")
725+ }
726+ else throw("Strict value is not equal to itself.")
727+ }
728+ else throw("Strict value is not equal to itself.")
729+ }
730+ }))
731+
732+
733+
734+@Callable(i)
735+func withdrawOneToken (callerBytes,args,pAmounts,pAssetIds) = valueOrElse(isOraclePool(toString(i.caller)), valueOrElse(isActive(), {
736+ let caller = Address(callerBytes)
737+ let withdrawAsset = if ((args[0] == ""))
738+ then unit
739+ else fromBase58String(args[0])
740+ let $t03046530555 = getPoolAssets(i.caller)
741+ let strAssetIdA = $t03046530555._1
742+ let strAssetIdB = $t03046530555._2
743+ let assetIdA = $t03046530555._3
744+ let assetIdB = $t03046530555._4
745+ let shareAssetId = $t03046530555._5
746+ let $t03056830692 = getPoolBalances(i.caller, assetIdA, assetIdB)
747+ let balanceA = $t03056830692._1
748+ let balanceB = $t03056830692._2
749+ let accountBalanceA = $t03056830692._3
750+ let accountBalanceB = $t03056830692._4
751+ let shareAssetSupply = $t03056830692._5
752+ let $t03070531085 = if ((size(pAmounts) == 1))
753+ then {
754+ let pAsset = parsePaymentAsset(pAssetIds[0])
755+ if ((pAsset != shareAssetId))
756+ then throw(("Incorrect asset attached. Expected: " + toBase58String(shareAssetId)))
757+ else $Tuple2(pAmounts[0], pAsset)
758+ }
759+ else $Tuple2(0, shareAssetId)
760+ let pmtAmount = $t03070531085._1
761+ let pmtAssetId = $t03070531085._2
762+ let virtMinToRecive = parseIntValue(args[1])
585763 if ((size(pAmounts) != 1))
586764 then throw("One attached payment expected")
587765 else if ((pmtAssetId != shareAssetId))
588766 then throw(("Incorrect asset attached. Expected: " + toBase58String(shareAssetId)))
589- else if (if ((balanceA > accountBalanceA))
590- then true
591- else (balanceB > accountBalanceB))
592- then $Tuple2(nil, ([ScriptTransfer(caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious(accountBalanceA, accountBalanceB, balanceA, balanceB, strAssetIdA, strAssetIdB)))
593- else {
594- let amountToPayA = fraction(pmtAmount, balanceA, shareAssetSupply)
595- let amountToPayB = fraction(pmtAmount, balanceB, shareAssetSupply)
596- let stake1 = if (contains(stakingAssets, strAssetIdA))
597- then invoke(i.caller, "stakeUnstake", [false, amountToPayA, strAssetIdA], nil)
598- else 0
599- if ((stake1 == stake1))
600- then {
601- let stake2 = if (contains(stakingAssets, strAssetIdB))
602- then invoke(i.caller, "stakeUnstake", [false, amountToPayB, strAssetIdB], nil)
603- else 0
604- if ((stake2 == stake2))
605- then $Tuple2(nil, [IntegerEntry(kBalanceA, (balanceA - amountToPayA)), IntegerEntry(kBalanceB, (balanceB - amountToPayB)), IntegerEntry(kShareAssetSupply, (shareAssetSupply - pmtAmount)), Burn(shareAssetId, pmtAmount), ScriptTransfer(caller, amountToPayA, assetIdA), ScriptTransfer(caller, amountToPayB, assetIdB)])
606- else throw("Strict value is not equal to itself.")
607- }
608- else throw("Strict value is not equal to itself.")
609- }
610- })
767+ else if (!(containsElement([assetIdA, assetIdB], withdrawAsset)))
768+ then throw("Incorrect withdraw asset.")
769+ else if (if ((balanceA > accountBalanceA))
770+ then true
771+ else (balanceB > accountBalanceB))
772+ then $Tuple2(nil, ([ScriptTransfer(caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious(accountBalanceA, accountBalanceB, balanceA, balanceB, strAssetIdA, strAssetIdB)))
773+ else {
774+ let unlockAmount = parseIntValue(valueOrElse(args[2], "0"))
775+ let unlock = if ((unlockAmount > 0))
776+ then invoke(farmingAddress, "withdrawShareTokens", [toString(i.caller), unlockAmount], nil)
777+ else 0
778+ if ((unlock == unlock))
779+ then {
780+ let withdrawAmount = (pmtAmount + unlockAmount)
781+ let amountToPayA = fraction(withdrawAmount, balanceA, shareAssetSupply)
782+ let amountToPayB = fraction(withdrawAmount, balanceB, shareAssetSupply)
783+ let $t03233032388 = getFeeParams(i.caller, i.originCaller)
784+ let fee = $t03233032388._1
785+ let govFee = $t03233032388._2
786+ let $t03240532745 = if ((withdrawAsset == assetIdA))
787+ then calculateFees(amountToPayB, virtMinToRecive, balanceB, balanceA, fee, govFee)
788+ else calculateFees(amountToPayA, virtMinToRecive, balanceA, balanceB, fee, govFee)
789+ let amountWithoutFee = $t03240532745._1
790+ let amountWithFee = $t03240532745._2
791+ let governanceReward = $t03240532745._3
792+ let $t03276234108 = if ((withdrawAsset == assetIdA))
793+ then {
794+ let unstake = if (contains(stakingAssets, strAssetIdA))
795+ then invoke(i.caller, "stakeUnstake", [false, ((amountToPayA + amountWithFee) + governanceReward), strAssetIdA], nil)
796+ else 0
797+ if ((unstake == unstake))
798+ then $Tuple4((((balanceA - amountToPayA) - amountWithFee) - governanceReward), balanceB, assetIdA, [ScriptTransfer(caller, (amountToPayA + amountWithFee), assetIdA)])
799+ else throw("Strict value is not equal to itself.")
800+ }
801+ else {
802+ let unstake = if (contains(stakingAssets, strAssetIdB))
803+ then invoke(i.caller, "stakeUnstake", [false, ((amountToPayB + amountWithFee) + governanceReward), strAssetIdB], nil)
804+ else 0
805+ if ((unstake == unstake))
806+ then $Tuple4(balanceA, (((balanceB - amountToPayB) - amountWithFee) - governanceReward), assetIdB, [ScriptTransfer(caller, (amountToPayB + amountWithFee), assetIdB)])
807+ else throw("Strict value is not equal to itself.")
808+ }
809+ let newBalanceA = $t03276234108._1
810+ let newBalanceB = $t03276234108._2
811+ let govRewardAssetId = $t03276234108._3
812+ let userTransfer = $t03276234108._4
813+ $Tuple2([ScriptTransfer(i.caller, unlockAmount, shareAssetId)], $Tuple2(([IntegerEntry(kBalanceA, newBalanceA), IntegerEntry(kBalanceB, newBalanceB), IntegerEntry(kShareAssetSupply, (shareAssetSupply - withdrawAmount)), Burn(shareAssetId, withdrawAmount), ScriptTransfer(moneyBoxAddress, governanceReward, govRewardAssetId)] ++ userTransfer), nil))
814+ }
815+ else throw("Strict value is not equal to itself.")
816+ }
817+ }))
611818
612819
613820
614821 @Callable(i)
615-func takeIntoAccountExtraFunds (callerBytes,args,pAmounts,pAssetIds) = valueOrElse(isActive(), {
616- let $t02385823934 = getPoolAssets(i.caller)
617- let strAssetIdA = $t02385823934._1
618- let strAssetIdB = $t02385823934._2
619- let assetIdA = $t02385823934._3
620- let assetIdB = $t02385823934._4
621- let $t02393924045 = getPoolBalances(i.caller, assetIdA, assetIdB)
622- let balanceA = $t02393924045._1
623- let balanceB = $t02393924045._2
624- let accountBalanceA = $t02393924045._3
625- let accountBalanceB = $t02393924045._4
822+func takeIntoAccountExtraFunds (callerBytes,args,pAmounts,pAssetIds) = valueOrElse(isOraclePool(toString(i.caller)), valueOrElse(isActive(), {
823+ let $t03483334909 = getPoolAssets(i.caller)
824+ let strAssetIdA = $t03483334909._1
825+ let strAssetIdB = $t03483334909._2
826+ let assetIdA = $t03483334909._3
827+ let assetIdB = $t03483334909._4
828+ let $t03492235028 = getPoolBalances(i.caller, assetIdA, assetIdB)
829+ let balanceA = $t03492235028._1
830+ let balanceB = $t03492235028._2
831+ let accountBalanceA = $t03492235028._3
832+ let accountBalanceB = $t03492235028._4
626833 let amountEnrollA = (accountBalanceA - balanceA)
627834 let amountEnrollB = (accountBalanceB - balanceB)
628835 if ((moneyBoxAddress != i.originCaller))
629836 then throw("Only the wallet can call this function")
630837 else if (if ((0 > amountEnrollA))
631838 then true
632839 else (0 > amountEnrollB))
633840 then suspend("Enroll amount negative")
634841 else if (if ((amountEnrollA == 0))
635842 then (amountEnrollB == 0)
636843 else false)
637844 then throw("No money to take")
638845 else {
639846 let stake1 = if (if (contains(stakingAssets, strAssetIdA))
640847 then (amountEnrollA > 0)
641848 else false)
642849 then invoke(this, "stakeUnstake", [true, amountEnrollA, strAssetIdA], nil)
643850 else 0
644851 if ((stake1 == stake1))
645852 then {
646853 let stake2 = if (if (contains(stakingAssets, strAssetIdB))
647854 then (amountEnrollB > 0)
648855 else false)
649856 then invoke(this, "stakeUnstake", [true, amountEnrollB, strAssetIdB], nil)
650857 else 0
651858 if ((stake2 == stake2))
652- then $Tuple2(nil, [IntegerEntry(kBalanceA, (balanceA + amountEnrollA)), IntegerEntry(kBalanceB, (balanceB + amountEnrollB))])
859+ then $Tuple2(nil, $Tuple2([IntegerEntry(kBalanceA, (balanceA + amountEnrollA)), IntegerEntry(kBalanceB, (balanceB + amountEnrollB))], nil))
653860 else throw("Strict value is not equal to itself.")
654861 }
655862 else throw("Strict value is not equal to itself.")
656863 }
657- })
864+ }))
658865
659866
660867 @Verifier(tx)
661868 func verify () = {
662869 let multiSignedByAdmins = {
663870 let adminPubKey1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
664871 then 1
665872 else 0
666873 let adminPubKey2Signed = if (sigVerify(tx.bodyBytes, tx.proofs[1], adminPubKey2))
667874 then 1
668875 else 0
669876 let adminPubKey3Signed = if (sigVerify(tx.bodyBytes, tx.proofs[2], adminPubKey3))
670877 then 1
671878 else 0
672879 (((adminPubKey1Signed + adminPubKey2Signed) + adminPubKey3Signed) >= 2)
673880 }
674881 multiSignedByAdmins
675882 }
676883

github/deemru/w8io/873ac7e 
175.86 ms