2022.10.18 17:29 [3343356] smart account 3PJKKT7gsWiPBJj11gkF3Xv7gKt8s2WPdTr > SELF 0.00000000 Waves

{ "type": 13, "id": "2FdU7eyXXUdXiMCfXY6CqAuCkfBZeqZmXU1pD8hKaunk", "fee": 1200000, "feeAssetId": null, "timestamp": 1666103356584, "version": 1, "sender": "3PJKKT7gsWiPBJj11gkF3Xv7gKt8s2WPdTr", "senderPublicKey": "FAqqjX7JqvqLh2QGTR3ziyCnSsWSoj9gVo4uPahtmhKr", "proofs": [ "4Sm1LqH1vS3z6fy1i3iYpt167Nupn94KrAfA3WT5Hy9Tqus2fmYidJWNPWwntnSb8tz9NB8D8QeoDQ6Hbvj8Ma2M" ], "script": "base64:BgIuCAISAwoBCBIDCgEIEgASAwoBCBIAEgMKAQgSBQoDCAgBEgQKAggIEgUKAwgIASoBB3Rocm93SWYCCWNvbmRpdGlvbgVlcnJvcgMFCWNvbmRpdGlvbgkAAgEFBWVycm9yBgEId3JpdGVJbnQCA2tleQV2YWx1ZQMJAGYCAAAFBXZhbHVlCQACAQkArAICCQCsAgIJAKwCAgIXd3JpdGluZyBuZWdhdGl2ZSB2YWx1ZSAJAKQDAQUFdmFsdWUCCSBmb3Iga2V5IAUDa2V5CQEMSW50ZWdlckVudHJ5AgUDa2V5BQV2YWx1ZQEIY2hhbmdlQnkCA2tleQV2YWx1ZQkBCHdyaXRlSW50AgUDa2V5CQBkAgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQNrZXkAAAUFdmFsdWUBDGZyYWN0aW9uQ2VpbAMFdmFsdWUJbnVtZXJhdG9yC2Rlbm9taW5hdG9yBARjYW5kCQBrAwUFdmFsdWUFCW51bWVyYXRvcgULZGVub21pbmF0b3IEAUQAs+aTqAsEBWV4YWN0CQAAAgkAagIJAGgCCQBqAgUEY2FuZAUBRAkAagIFC2Rlbm9taW5hdG9yBQFEBQFECQBqAgkAaAIJAGoCBQV2YWx1ZQUBRAkAagIFCW51bWVyYXRvcgUBRAUBRAMFBWV4YWN0BQRjYW5kCQBkAgUEY2FuZAABARB3cml0ZUNvbnN0U3RyaW5nAgNrZXkFdmFsdWUDCQEBIQEJAQlpc0RlZmluZWQBCQCdCAIFBHRoaXMFA2tleQkBC1N0cmluZ0VudHJ5AgUDa2V5BQV2YWx1ZQkAAgEJAKwCAgIVYWxyZWFkeSBpbml0aWFsaXplZDogBQNrZXkAEmNvbmZpZ0FkZHJlc3NTdG9yZQINY29uZmlnQWRkcmVzcwALb3JhY2xlU3RvcmUCDm9yYWNsZV9hZGRyZXNzARJyZXNlcnZlRmFjdG9yU3RvcmUBB2Fzc2V0SWQJAKwCAgUHYXNzZXRJZAIOX1Jlc2VydmVGYWN0b3IACW1haW5TdG9yZQIEbWFpbgANY29uZmlnQWRkcmVzcwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQR0aGlzBRJjb25maWdBZGRyZXNzU3RvcmUCI3Byb3RlY3RlZC1yZXNlcnZlOiBubyBjb25maWdBZGRyZXNzAhZpbnZhbGlkIGNvbmZpZyBhZGRyZXNzAQ1yZXNlcnZlRmFjdG9yAQdhc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUNY29uZmlnQWRkcmVzcwkBEnJlc2VydmVGYWN0b3JTdG9yZQEFB2Fzc2V0SWQCEG5vIHJlc2VydmVGYWN0b3IBCmdldEJhbGFuY2UCDmFkZHJlc3NPckFsaWFzB2Fzc2V0SWQEByRtYXRjaDAFB2Fzc2V0SWQDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQCYnYFByRtYXRjaDAJAPAHAgUOYWRkcmVzc09yQWxpYXMFAmJ2AwkAAQIFByRtYXRjaDACBFVuaXQEAXUFByRtYXRjaDAICQDvBwEFDmFkZHJlc3NPckFsaWFzCWF2YWlsYWJsZQkAAgECC01hdGNoIGVycm9yAQlvcEFsbG93ZWQCB2Fzc2V0SWQCb3AEByRtYXRjaDAJAPwHBAUNY29uZmlnQWRkcmVzcwIJb3BBbGxvd2VkCQDMCAIFB2Fzc2V0SWQJAMwIAgUCb3AFA25pbAUDbmlsAwkAAQIFByRtYXRjaDACB0Jvb2xlYW4EAWIFByRtYXRjaDADBQFiBgkAAgECC25vdCBhbGxvd2VkCQACAQIhb3BBbGxvd2VkOiB1bmV4cGVjdGVkIHJlc3VsdCB0eXBlAQhtYWluT25seQEBaQMJAQhjb250YWlucwIJARFAZXh0ck5hdGl2ZSgxMDUzKQIFDWNvbmZpZ0FkZHJlc3MCBG1haW4JAKUIAQgFAWkGY2FsbGVyBgkAAgECEG9ubHkgbWFpbiBjYW4gZG8AEm1heWJlT3JhY2xlQWRkcmVzcwQHJG1hdGNoMAkAnQgCBQ1jb25maWdBZGRyZXNzBQtvcmFjbGVTdG9yZQMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAJAKYIAQUBcwUEdW5pdAELb3JhY2xlUHJpY2UBB2Fzc2V0SWQEByRtYXRjaDAJAPwHBAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCBRJtYXliZU9yYWNsZUFkZHJlc3MCCW5vIG9yYWNsZQIFcHJpY2UJAMwIAgUHYXNzZXRJZAUDbmlsBQNuaWwDCQABAgUHJG1hdGNoMAIDSW50BAFpBQckbWF0Y2gwBQFpCQACAQIPYmFkIG9yYWNsZSBkYXRhAAZIRUlHSFQFBmhlaWdodAAGYXNzZXRzCQELdmFsdWVPckVsc2UCCQCdCAIFDWNvbmZpZ0FkZHJlc3MCGHByb3RlY3RlZF9yZXNlcnZlX2Fzc2V0cwIAAAthc3NldHNBcnJheQMJAAACBQZhc3NldHMCAAUDbmlsCQC8CQIFBmFzc2V0cwIBfAERdG90YWxEZXBvc2l0U3RvcmUBB2Fzc2V0SWQJAKwCAgIMdG90YWxTdXBwbHlfBQdhc3NldElkARB0b3RhbFNoYXJlc1N0b3JlAQdhc3NldElkCQCsAgICDHRvdGFsU2hhcmVzXwUHYXNzZXRJZAEPdXNlclNoYXJlc1N0b3JlAgdhc3NldElkBHVzZXIJAKwCAgkArAICCQCsAgICC3VzZXJTaGFyZXNfBQdhc3NldElkAgFfBQR1c2VyARFoYXNQcm90ZWN0ZWRTdG9yZQEEdXNlcgkArAICAhVwcm90ZWN0ZWRfY29sbGF0ZXJhbF8FBHVzZXIBE3Byb3RlY3RlZEFzc2V0U3RvcmUBBHVzZXIJAKwCAgIQcHJvdGVjdGVkX2Fzc2V0XwUEdXNlcgEMdG90YWxEZXBvc2l0AQdhc3NldElkCQELdmFsdWVPckVsc2UCCQCfCAEJARF0b3RhbERlcG9zaXRTdG9yZQEFB2Fzc2V0SWQAAAELdG90YWxTaGFyZXMBB2Fzc2V0SWQJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBEHRvdGFsU2hhcmVzU3RvcmUBBQdhc3NldElkAAABCnVzZXJTaGFyZXMCB2Fzc2V0SWQEdXNlcgkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEPdXNlclNoYXJlc1N0b3JlAgUHYXNzZXRJZAUEdXNlcgAAAQt1c2VyRGVwb3NpdAIHYXNzZXRJZAR1c2VyBAJ0cwkBC3RvdGFsU2hhcmVzAQUHYXNzZXRJZAQCdGQJAQx0b3RhbERlcG9zaXQBBQdhc3NldElkBAJ1cwkBCnVzZXJTaGFyZXMCBQdhc3NldElkBQR1c2VyAwkAAAIFAnRzAAAAAAkAawMFAnRkBQJ1cwUCdHMBEWhhc1JlZ3VsYXJEZXBvc2l0AQR1c2Vy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MQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUAQ5zaGFyZXNUb0Ftb3VudAIHYXNzZXRJZAZzaGFyZXMEAnRzCQELdG90YWxTaGFyZXMBBQdhc3NldElkBAJ0ZAkBDHRvdGFsRGVwb3NpdAEFB2Fzc2V0SWQDAwkAAAIFAnRzAAAGCQAAAgUCdGQAAAUGc2hhcmVzCQBrAwUGc2hhcmVzBQJ0ZAUCdHMBDmFtb3VudFRvU2hhcmVzAwdhc3NldElkA2FtdARjZWlsBAJ0cwkBC3RvdGFsU2hhcmVzAQUHYXNzZXRJZAQCdGQJAQx0b3RhbERlcG9zaXQBBQdhc3NldElkAwMJAAACBQJ0cwAABgkAAAIFAnRkAAAFA2FtdAMFBGNlaWwJAQxmcmFjdGlvbkNlaWwDBQNhbXQFAnRzBQJ0ZAkAawMFA2FtdAUCdHMFAnRkAQ92YWxpZGF0ZUFzc2V0SWQBB2Fzc2V0SWQJAQd0aHJvd0lmAgkBASEBCQEIY29udGFpbnMCBQZhc3NldHMFB2Fzc2V0SWQCFWFzc2V0SWQgbm90IHBlcm1pdHRlZAEKYXNzZXRJZFN0cgEDYWlkBAckbWF0Y2gwBQNhaWQDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQCYnYFByRtYXRjaDAJANgEAQUCYnYDCQABAgUHJG1hdGNoMAIEVW5pdAQBdQUHJG1hdGNoMAIFV0FWRVMJAAIBAgtNYXRjaCBlcnJvcgEMYXNzZXRTdHJUb0lkAQdhc3NldElkAwkAAAIFB2Fzc2V0SWQCBVdBVkVTBQR1bml0CQDZBAEFB2Fzc2V0SWQBDnN0YWtpbmdFbmFibGVkAQdhc3NldElkCQELdmFsdWVPckVsc2UCCQCbCAIFDWNvbmZpZ0FkZHJlc3MJAKwCAgIacHJvdGVjdGVkX3N0YWtpbmdfZW5hYmxlZF8FB2Fzc2V0SWQHAQ5zdGFraW5nQWRkcmVzcwEHYXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ1jb25maWdBZGRyZXNzCQCsAgICGXByb3RlY3RlZF9zdGFraW5nX2NvbmZpZ18FB2Fzc2V0SWQJAKwCAgIXbm8gc3Rha2luZyBhZGRyZXNzIGZvciAFB2Fzc2V0SWQJAKwCAgIqcHJvdGVjdGVkUmVzZXJ2ZTogYmFkIHN0YWtpbmcgYWRkcmVzcyBmb3IgBQdhc3NldElkAQ1zdGFraW5nQWN0aW9uAgdhc3NldElkDWtlZXBBdEJhbGFuY2UEDWFjdHVhbEJhbGFuY2UDCQAAAgUHYXNzZXRJZAIFV0FWRVMICQDvBwEFBHRoaXMJYXZhaWxhYmxlCQDwBwIFBHRoaXMJANkEAQUHYXNzZXRJZAMJAAACBQ1hY3R1YWxCYWxhbmNlBQ1rZWVwQXRCYWxhbmNlBQR1bml0AwkBASEBCQEOc3Rha2luZ0VuYWJsZWQBBQdhc3NldElkBQR1bml0BAJzYQkBDnN0YWtpbmdBZGRyZXNzAQUHYXNzZXRJZAMJAGYCBQ1hY3R1YWxCYWxhbmNlBQ1rZWVwQXRCYWxhbmNlCQD8BwQFAnNhAgNwdXQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBDGFzc2V0U3RyVG9JZAEFB2Fzc2V0SWQJAGUCBQ1hY3R1YWxCYWxhbmNlBQ1rZWVwQXRCYWxhbmNlBQNuaWwJAPwHBAUCc2ECA2dldAkAzAgCCQBlAgUNa2VlcEF0QmFsYW5jZQUNYWN0dWFsQmFsYW5jZQUDbmlsBQNuaWwBEHdpdGhkcmF3SW50ZXJuYWwEBGZyb20CdG8HYXNzZXRJZAZhbW91bnQEBmNoZWNrcwkBD3ZhbGlkYXRlQXNzZXRJZAEFB2Fzc2V0SWQDCQAAAgUGY2hlY2tzBQZjaGVja3MECnJlYWxTaGFyZXMJAQp1c2VyU2hhcmVzAgUHYXNzZXRJZAUEZnJvbQQLJHQwNzQyNzc3MTEDCQAAAgUGYW1vdW50AP///////////wEECnJlYWxBbW91bnQJAQ5zaGFyZXNUb0Ftb3VudAIFB2Fzc2V0SWQFCnJlYWxTaGFyZXMJAJQKAgUKcmVhbFNoYXJlcwUKcmVhbEFtb3VudAMJAGcCAAAFBmFtb3VudAkAAgECJnByb3RlY3RlZC1yZXNlcnZlOiBub24tcG9zaXRpdmUgYW1vdW50CQCUCgIJAQ5hbW91bnRUb1NoYXJlcwMFB2Fzc2V0SWQFBmFtb3VudAYFBmFtb3VudAQId2RTaGFyZXMIBQskdDA3NDI3NzcxMQJfMQQId2RBbW91bnQIBQskdDA3NDI3NzcxMQJfMgQMbWF5YmVDbGVhblVwAwkAAAIFCnJlYWxTaGFyZXMFCHdkU2hhcmVzCQDMCAIJAQxCb29sZWFuRW50cnkCCQERaGFzUHJvdGVjdGVkU3RvcmUBBQRmcm9tBwkAzAgCCQELRGVsZXRlRW50cnkBCQETcHJvdGVjdGVkQXNzZXRTdG9yZQEFBGZyb20FA25pbAUDbmlsBAdzdGFraW5nCQENc3Rha2luZ0FjdGlvbgIFB2Fzc2V0SWQFCHdkQW1vdW50AwkAAAIFB3N0YWtpbmcFB3N0YWtpbmcJAJQKAgkAzggCBQxtYXliZUNsZWFuVXAJAMwIAgkBCGNoYW5nZUJ5AgkBEXRvdGFsRGVwb3NpdFN0b3JlAQUHYXNzZXRJZAkBAS0BBQh3ZEFtb3VudAkAzAgCCQEIY2hhbmdlQnkCCQEQdG90YWxTaGFyZXNTdG9yZQEFB2Fzc2V0SWQJAQEtAQUId2RTaGFyZXMJAMwIAgkBCGNoYW5nZUJ5AgkBD3VzZXJTaGFyZXNTdG9yZQIFB2Fzc2V0SWQFBGZyb20JAQEtAQUId2RTaGFyZXMJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwkBEUBleHRyTmF0aXZlKDEwNjIpAQUCdG8FCHdkQW1vdW50CQEMYXNzZXRTdHJUb0lkAQUHYXNzZXRJZAUDbmlsBQh3ZEFtb3VudAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgEOc3VwcGx5SW50ZXJuYWwCBHVzZXIBaQMJARFoYXNSZWd1bGFyRGVwb3NpdAEFBHVzZXIJAAIBAjtwcm90ZWN0ZWQtcmVzZXJ2ZTogY2FuJ3QgaGF2ZSBwcm90ZWN0ZWQgd2hlbiByZWd1bGFyIGV4aXN0cwMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECKnByb3RlY3RlZC1yZXNlcnZlOiBzaW5nbGUgcGF5bWVudCByZXF1aXJlZAQHYXNzZXRJZAkBCmFzc2V0SWRTdHIBCAkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQEBmFtb3VudAgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQDCQAAAgUGYW1vdW50AAAFA25pbAQGY2hlY2tzAwkBD3ZhbGlkYXRlQXNzZXRJZAEFB2Fzc2V0SWQJAQlvcEFsbG93ZWQCBQdhc3NldElkAhtzdXBwbHlfcHJvdGVjdGVkX2NvbGxhdGVyYWwHAwkAAAIFBmNoZWNrcwUGY2hlY2tzBA1wcm90ZWN0ZWRGbGFnCQELdmFsdWVPckVsc2UCCQCbCAIFBHRoaXMJARFoYXNQcm90ZWN0ZWRTdG9yZQEFBHVzZXIHBA5wcm90ZWN0ZWRBc3NldAkAnQgCBQR0aGlzCQETcHJvdGVjdGVkQXNzZXRTdG9yZQEFBHVzZXIEC2NvbnNpc3RlbmN5AwUNcHJvdGVjdGVkRmxhZwQHJG1hdGNoMAUOcHJvdGVjdGVkQXNzZXQDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwAwkAAAIFAXMFB2Fzc2V0SWQGCQACAQI7cHJvdGVjdGVkLXJlc2VydmU6IGNhbid0IGhhdmUgbW9yZSB0aGFuIG9uZSBhc3NldCBwcm90ZWN0ZWQJAAIBAiBwcm90ZWN0ZWQtcmVzZXJ2ZTpjbGVhbiB1cCBmaXJzdAQHJG1hdGNoMAUOcHJvdGVjdGVkQXNzZXQDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwCQACAQIjcHJvdGVjdGVkLXJlc2VydmU6IG1pc2NvbmZpZ3VyYXRpb24GBBBjb25zaXN0ZW5jeUNoZWNrCQEHdGhyb3dJZgIJAQEhAQULY29uc2lzdGVuY3kCDWluY29uc2lzdGVuY3kDCQAAAgUQY29uc2lzdGVuY3lDaGVjawUQY29uc2lzdGVuY3lDaGVjawQJbmV3U2hhcmVzCQEOYW1vdW50VG9TaGFyZXMDBQdhc3NldElkBQZhbW91bnQHBAdzdGFraW5nCQENc3Rha2luZ0FjdGlvbgIFB2Fzc2V0SWQAAAMJAAACBQdzdGFraW5nBQdzdGFraW5nCQDMCAIJAQhjaGFuZ2VCeQIJARF0b3RhbERlcG9zaXRTdG9yZQEFB2Fzc2V0SWQFBmFtb3VudAkAzAgCCQEIY2hhbmdlQnkCCQEQdG90YWxTaGFyZXNTdG9yZQEFB2Fzc2V0SWQFCW5ld1NoYXJlcwkAzAgCCQEIY2hhbmdlQnkCCQEPdXNlclNoYXJlc1N0b3JlAgUHYXNzZXRJZAUEdXNlcgUJbmV3U2hhcmVzCQDMCAIJAQxCb29sZWFuRW50cnkCCQERaGFzUHJvdGVjdGVkU3RvcmUBBQR1c2VyBgkAzAgCCQELU3RyaW5nRW50cnkCCQETcHJvdGVjdGVkQXNzZXRTdG9yZQEFBHVzZXIFB2Fzc2V0SWQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkBaQEKaW5pdGlhbGl6ZQENY29uZmlnQWRkcmVzcwkAzAgCCQEQd3JpdGVDb25zdFN0cmluZwIFEmNvbmZpZ0FkZHJlc3NTdG9yZQUNY29uZmlnQWRkcmVzcwUDbmlsAWkBB3Vuc3Rha2UBB2Fzc2V0SWQKAQVhc0ludAEFdmFsdWUEByRtYXRjaDAFBXZhbHVlAwkAAQIFByRtYXRjaDACA0ludAQDaW50BQckbWF0Y2gwBQNpbnQJAAIBAgVfcHI6MQMJAQ5zdGFraW5nRW5hYmxlZAEFB2Fzc2V0SWQJAAIBCQCsAgICKnByb3RlY3RlZC1yZXNlcnZlOiBzdGFraW5nIGlzIGVuYWJsZWQgZm9yIAUHYXNzZXRJZAQCc2EJAQ5zdGFraW5nQWRkcmVzcwEFB2Fzc2V0SWQEBnN0YWtlZAkBBWFzSW50AQkA/AcEBQJzYQIEaW5mbwUDbmlsBQNuaWwDCQAAAgUGc3Rha2VkBQZzdGFrZWQECXVuc3Rha2luZwkA/AcEBQJzYQIDZ2V0CQDMCAIFBnN0YWtlZAUDbmlsBQNuaWwDCQAAAgUJdW5zdGFraW5nBQl1bnN0YWtpbmcJAJQKAgUDbmlsBQZzdGFrZWQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQELYWRkSW50ZXJlc3QABAdhc3NldElkCQEKYXNzZXRJZFN0cgEICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAQGY2hlY2tzCQEPdmFsaWRhdGVBc3NldElkAQUHYXNzZXRJZAMJAAACBQZjaGVja3MFBmNoZWNrcwQHc3Rha2luZwkBDXN0YWtpbmdBY3Rpb24CBQdhc3NldElkAAADCQAAAgUHc3Rha2luZwUHc3Rha2luZwQGYW1vdW50CAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAkAzAgCCQEIY2hhbmdlQnkCCQERdG90YWxEZXBvc2l0U3RvcmUBBQdhc3NldElkBQZhbW91bnQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQtib3Jyb3dQb3dlcgEEdXNlcgkAlAoCBQNuaWwJAQJicAEFBHVzZXIBaQEGc3VwcGx5AAkBDnN1cHBseUludGVybmFsAgkApQgBCAUBaQZjYWxsZXIFAWkBaQEJc3VwcGx5Rm9yAQR1c2VyBAZjaGVja3MJAQhtYWluT25seQEFAWkDCQAAAgUGY2hlY2tzBQZjaGVja3MJAQ5zdXBwbHlJbnRlcm5hbAIFBHVzZXIFAWkJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQELd2l0aGRyYXdGb3IDBHVzZXIHYXNzZXRJZAZhbW91bnQEBmNoZWNrcwMJAQhtYWluT25seQEFAWkJAQlvcEFsbG93ZWQCBQdhc3NldElkAh13aXRoZHJhd19wcm90ZWN0ZWRfY29sbGF0ZXJhbAcDCQAAAgUGY2hlY2tzBQZjaGVja3MJARB3aXRoZHJhd0ludGVybmFsBAUEdXNlcgUEdXNlcgUHYXNzZXRJZAUGYW1vdW50CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDndpdGhkcmF3VG9NYWluAgR1c2VyB2Fzc2V0SWQEBmNoZWNrcwMJAQhtYWluT25seQEFAWkJAQlvcEFsbG93ZWQCBQdhc3NldElkAh1jb2xsYXBzZV9wcm90ZWN0ZWRfY29sbGF0ZXJhbAcDCQAAAgUGY2hlY2tzBQZjaGVja3MJARB3aXRoZHJhd0ludGVybmFsBAUEdXNlcgkApQgBCAUBaQZjYWxsZXIFB2Fzc2V0SWQA////////////AQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQ93aXRoZHJhd1RvTWFpbjIDBHVzZXIHYXNzZXRJZANhbXQEBmNoZWNrcwMJAQhtYWluT25seQEFAWkJAQlvcEFsbG93ZWQCBQdhc3NldElkAhh3aXRoZHJhd1Byb3RlY3RlZFRvTWFpbjIHAwkAAAIFBmNoZWNrcwUGY2hlY2tzCQEQd2l0aGRyYXdJbnRlcm5hbAQFBHVzZXIJAKUIAQgFAWkGY2FsbGVyBQdhc3NldElkBQNhbXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4A3z/R+Q==", "chainId": 87, "height": 3343356, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 7j9MVKoVvcrjGzez3tMkEWvqB1cMUBmvetZ6iLicQbsz Next: 6MeKBuANR4e1e7XNHPwfvn2UFarieZZJzi7vrptpphcZ Diff:
OldNewDifferences
275275 else fromBase58String(assetId)
276276
277277
278+func stakingEnabled (assetId) = valueOrElse(getBoolean(configAddress, ("protected_staking_enabled_" + assetId)), false)
279+
280+
281+func stakingAddress (assetId) = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(configAddress, ("protected_staking_config_" + assetId)), ("no staking address for " + assetId))), ("protectedReserve: bad staking address for " + assetId))
282+
283+
278284 func stakingAction (assetId,keepAtBalance) = {
279285 let actualBalance = if ((assetId == "WAVES"))
280286 then wavesBalance(this).available
281287 else assetBalance(this, fromBase58String(assetId))
282288 if ((actualBalance == keepAtBalance))
283289 then unit
284- else {
285- let stakingEnabled = valueOrElse(getBoolean(configAddress, ("protected_staking_enabled_" + assetId)), false)
286- if (!(stakingEnabled))
287- then unit
288- else {
289- let stakingAddress = {
290- let addr = valueOrErrorMessage(getString(configAddress, ("protected_staking_config_" + assetId)), ("no staking address for " + assetId))
291- valueOrErrorMessage(addressFromString(addr), ((("protectedReserve: bad staking address for " + assetId) + ": ") + addr))
292- }
293- if ((actualBalance > keepAtBalance))
294- then invoke(stakingAddress, "put", nil, [AttachedPayment(assetStrToId(assetId), (actualBalance - keepAtBalance))])
295- else invoke(stakingAddress, "get", [(keepAtBalance - actualBalance)], nil)
296- }
297- }
290+ else if (!(stakingEnabled(assetId)))
291+ then unit
292+ else {
293+ let sa = stakingAddress(assetId)
294+ if ((actualBalance > keepAtBalance))
295+ then invoke(sa, "put", nil, [AttachedPayment(assetStrToId(assetId), (actualBalance - keepAtBalance))])
296+ else invoke(sa, "get", [(keepAtBalance - actualBalance)], nil)
297+ }
298298 }
299299
300300
303303 if ((checks == checks))
304304 then {
305305 let realShares = userShares(assetId, from)
306- let $t074677751 = if ((amount == -1))
306+ let $t074277711 = if ((amount == -1))
307307 then {
308308 let realAmount = sharesToAmount(assetId, realShares)
309309 $Tuple2(realShares, realAmount)
311311 else if ((0 >= amount))
312312 then throw("protected-reserve: non-positive amount")
313313 else $Tuple2(amountToShares(assetId, amount, true), amount)
314- let wdShares = $t074677751._1
315- let wdAmount = $t074677751._2
314+ let wdShares = $t074277711._1
315+ let wdAmount = $t074277711._2
316316 let maybeCleanUp = if ((realShares == wdShares))
317317 then [BooleanEntry(hasProtectedStore(from), false), DeleteEntry(protectedAssetStore(from))]
318318 else nil
375375
376376 @Callable(i)
377377 func initialize (configAddress) = [writeConstString(configAddressStore, configAddress)]
378+
379+
380+
381+@Callable(i)
382+func unstake (assetId) = {
383+ func asInt (value) = match value {
384+ case int: Int =>
385+ int
386+ case _ =>
387+ throw("_pr:1")
388+ }
389+
390+ if (stakingEnabled(assetId))
391+ then throw(("protected-reserve: staking is enabled for " + assetId))
392+ else {
393+ let sa = stakingAddress(assetId)
394+ let staked = asInt(invoke(sa, "info", nil, nil))
395+ if ((staked == staked))
396+ then {
397+ let unstaking = invoke(sa, "get", [staked], nil)
398+ if ((unstaking == unstaking))
399+ then $Tuple2(nil, staked)
400+ else throw("Strict value is not equal to itself.")
401+ }
402+ else throw("Strict value is not equal to itself.")
403+ }
404+ }
378405
379406
380407
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 func throwIf (condition,error) = if (condition)
55 then throw(error)
66 else true
77
88
99 func writeInt (key,value) = if ((0 > value))
1010 then throw(((("writing negative value " + toString(value)) + " for key ") + key))
1111 else IntegerEntry(key, value)
1212
1313
1414 func changeBy (key,value) = writeInt(key, (valueOrElse(getInteger(this, key), 0) + value))
1515
1616
1717 func fractionCeil (value,numerator,denominator) = {
1818 let cand = fraction(value, numerator, denominator)
1919 let D = 3037000499
2020 let exact = ((((cand % D) * (denominator % D)) % D) == (((value % D) * (numerator % D)) % D))
2121 if (exact)
2222 then cand
2323 else (cand + 1)
2424 }
2525
2626
2727 func writeConstString (key,value) = if (!(isDefined(getString(this, key))))
2828 then StringEntry(key, value)
2929 else throw(("already initialized: " + key))
3030
3131
3232 let configAddressStore = "configAddress"
3333
3434 let oracleStore = "oracle_address"
3535
3636 func reserveFactorStore (assetId) = (assetId + "_ReserveFactor")
3737
3838
3939 let mainStore = "main"
4040
4141 let configAddress = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(this, configAddressStore), "protected-reserve: no configAddress")), "invalid config address")
4242
4343 func reserveFactor (assetId) = valueOrErrorMessage(getInteger(configAddress, reserveFactorStore(assetId)), "no reserveFactor")
4444
4545
4646 func getBalance (addressOrAlias,assetId) = match assetId {
4747 case bv: ByteVector =>
4848 assetBalance(addressOrAlias, bv)
4949 case u: Unit =>
5050 wavesBalance(addressOrAlias).available
5151 case _ =>
5252 throw("Match error")
5353 }
5454
5555
5656 func opAllowed (assetId,op) = match invoke(configAddress, "opAllowed", [assetId, op], nil) {
5757 case b: Boolean =>
5858 if (b)
5959 then true
6060 else throw("not allowed")
6161 case _ =>
6262 throw("opAllowed: unexpected result type")
6363 }
6464
6565
6666 func mainOnly (i) = if (contains(getStringValue(configAddress, "main"), toString(i.caller)))
6767 then true
6868 else throw("only main can do")
6969
7070
7171 let maybeOracleAddress = match getString(configAddress, oracleStore) {
7272 case s: String =>
7373 addressFromString(s)
7474 case _ =>
7575 unit
7676 }
7777
7878 func oraclePrice (assetId) = match invoke(valueOrErrorMessage(maybeOracleAddress, "no oracle"), "price", [assetId], nil) {
7979 case i: Int =>
8080 i
8181 case _ =>
8282 throw("bad oracle data")
8383 }
8484
8585
8686 let HEIGHT = height
8787
8888 let assets = valueOrElse(getString(configAddress, "protected_reserve_assets"), "")
8989
9090 let assetsArray = if ((assets == ""))
9191 then nil
9292 else split_4C(assets, "|")
9393
9494 func totalDepositStore (assetId) = ("totalSupply_" + assetId)
9595
9696
9797 func totalSharesStore (assetId) = ("totalShares_" + assetId)
9898
9999
100100 func userSharesStore (assetId,user) = ((("userShares_" + assetId) + "_") + user)
101101
102102
103103 func hasProtectedStore (user) = ("protected_collateral_" + user)
104104
105105
106106 func protectedAssetStore (user) = ("protected_asset_" + user)
107107
108108
109109 func totalDeposit (assetId) = valueOrElse(getInteger(totalDepositStore(assetId)), 0)
110110
111111
112112 func totalShares (assetId) = valueOrElse(getInteger(totalSharesStore(assetId)), 0)
113113
114114
115115 func userShares (assetId,user) = valueOrElse(getInteger(userSharesStore(assetId, user)), 0)
116116
117117
118118 func userDeposit (assetId,user) = {
119119 let ts = totalShares(assetId)
120120 let td = totalDeposit(assetId)
121121 let us = userShares(assetId, user)
122122 if ((ts == 0))
123123 then 0
124124 else fraction(td, us, ts)
125125 }
126126
127127
128128 func hasRegularDeposit (user) = {
129129 let reserves = split_4C(valueOrErrorMessage(getString(configAddress, "primary_reserves"), "protected: no reserves found in main"), "|")
130130 func asUserBalanceData (value) = match value {
131131 case x: (Int, Int, Int, Int, Int, Boolean) =>
132132 x
133133 case t =>
134134 throw("wrong type, expected: Int5&Boolean")
135135 }
136136
137137 func fold (acc,reserve) = {
138138 let ubd = asUserBalanceData(invoke(addressFromStringValue(reserve), "userBalance", [user], nil))
139139 if ((ubd._1 > 0))
140140 then throw("can't have protected when regular exists")
141141 else false
142142 }
143143
144144 let $l = reserves
145145 let $s = size($l)
146146 let $acc0 = false
147147 func $f0_1 ($a,$i) = if (($i >= $s))
148148 then $a
149149 else fold($a, $l[$i])
150150
151151 func $f0_2 ($a,$i) = if (($i >= $s))
152152 then $a
153153 else throw("List size exceeds 20")
154154
155155 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20)
156156 }
157157
158158
159159 func userState (user) = {
160160 func fold (acc,assetId) = (acc ++ [$Tuple2(assetId, userDeposit(assetId, user))])
161161
162162 let $l = assetsArray
163163 let $s = size($l)
164164 let $acc0 = nil
165165 func $f0_1 ($a,$i) = if (($i >= $s))
166166 then $a
167167 else fold($a, $l[$i])
168168
169169 func $f0_2 ($a,$i) = if (($i >= $s))
170170 then $a
171171 else throw("List size exceeds 20")
172172
173173 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20)
174174 }
175175
176176
177177 func bp (user) = {
178178 let factorsBase = 1000
179179 func collateralFactor (assetId) = valueOrErrorMessage(getInteger(configAddress, (assetId + "_CollateralFactor")), "no CollateralFactor in config")
180180
181181 func pow10 (n) = if ((n == 6))
182182 then 1000000
183183 else if ((n == 8))
184184 then 100000000
185185 else throw(("bad decimals: " + toString(n)))
186186
187187 func assetDecimals (assetId) = if ((assetId == "WAVES"))
188188 then 8
189189 else valueOrErrorMessage(assetInfo(fromBase58String(assetId)), "bad asset").decimals
190190
191191 func assetToUsd (assetId,amount) = fraction(amount, oraclePrice(assetId), pow10(assetDecimals(assetId)))
192192
193193 func fold (acc,data) = (acc + {
194194 let $t050635088 = data
195195 let assetId = $t050635088._1
196196 let amt = $t050635088._2
197197 fraction(assetToUsd(assetId, amt), collateralFactor(assetId), factorsBase)
198198 })
199199
200200 let $l = userState(user)
201201 let $s = size($l)
202202 let $acc0 = 0
203203 func $f0_1 ($a,$i) = if (($i >= $s))
204204 then $a
205205 else fold($a, $l[$i])
206206
207207 func $f0_2 ($a,$i) = if (($i >= $s))
208208 then $a
209209 else throw("List size exceeds 20")
210210
211211 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20)
212212 }
213213
214214
215215 func adviseUser (user) = {
216216 let borrowPower = bp(user)
217217 (("borrowPower = " + toString(borrowPower)) + {
218218 func fold (acc,pair) = ((((acc + ", ") + pair._1) + " = ") + toString(pair._2))
219219
220220 let $l = userState(user)
221221 let $s = size($l)
222222 let $acc0 = ""
223223 func $f0_1 ($a,$i) = if (($i >= $s))
224224 then $a
225225 else fold($a, $l[$i])
226226
227227 func $f0_2 ($a,$i) = if (($i >= $s))
228228 then $a
229229 else throw("List size exceeds 20")
230230
231231 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20)
232232 })
233233 }
234234
235235
236236 func sharesToAmount (assetId,shares) = {
237237 let ts = totalShares(assetId)
238238 let td = totalDeposit(assetId)
239239 if (if ((ts == 0))
240240 then true
241241 else (td == 0))
242242 then shares
243243 else fraction(shares, td, ts)
244244 }
245245
246246
247247 func amountToShares (assetId,amt,ceil) = {
248248 let ts = totalShares(assetId)
249249 let td = totalDeposit(assetId)
250250 if (if ((ts == 0))
251251 then true
252252 else (td == 0))
253253 then amt
254254 else if (ceil)
255255 then fractionCeil(amt, ts, td)
256256 else fraction(amt, ts, td)
257257 }
258258
259259
260260 func validateAssetId (assetId) = throwIf(!(contains(assets, assetId)), "assetId not permitted")
261261
262262
263263 func assetIdStr (aid) = match aid {
264264 case bv: ByteVector =>
265265 toBase58String(bv)
266266 case u: Unit =>
267267 "WAVES"
268268 case _ =>
269269 throw("Match error")
270270 }
271271
272272
273273 func assetStrToId (assetId) = if ((assetId == "WAVES"))
274274 then unit
275275 else fromBase58String(assetId)
276276
277277
278+func stakingEnabled (assetId) = valueOrElse(getBoolean(configAddress, ("protected_staking_enabled_" + assetId)), false)
279+
280+
281+func stakingAddress (assetId) = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(configAddress, ("protected_staking_config_" + assetId)), ("no staking address for " + assetId))), ("protectedReserve: bad staking address for " + assetId))
282+
283+
278284 func stakingAction (assetId,keepAtBalance) = {
279285 let actualBalance = if ((assetId == "WAVES"))
280286 then wavesBalance(this).available
281287 else assetBalance(this, fromBase58String(assetId))
282288 if ((actualBalance == keepAtBalance))
283289 then unit
284- else {
285- let stakingEnabled = valueOrElse(getBoolean(configAddress, ("protected_staking_enabled_" + assetId)), false)
286- if (!(stakingEnabled))
287- then unit
288- else {
289- let stakingAddress = {
290- let addr = valueOrErrorMessage(getString(configAddress, ("protected_staking_config_" + assetId)), ("no staking address for " + assetId))
291- valueOrErrorMessage(addressFromString(addr), ((("protectedReserve: bad staking address for " + assetId) + ": ") + addr))
292- }
293- if ((actualBalance > keepAtBalance))
294- then invoke(stakingAddress, "put", nil, [AttachedPayment(assetStrToId(assetId), (actualBalance - keepAtBalance))])
295- else invoke(stakingAddress, "get", [(keepAtBalance - actualBalance)], nil)
296- }
297- }
290+ else if (!(stakingEnabled(assetId)))
291+ then unit
292+ else {
293+ let sa = stakingAddress(assetId)
294+ if ((actualBalance > keepAtBalance))
295+ then invoke(sa, "put", nil, [AttachedPayment(assetStrToId(assetId), (actualBalance - keepAtBalance))])
296+ else invoke(sa, "get", [(keepAtBalance - actualBalance)], nil)
297+ }
298298 }
299299
300300
301301 func withdrawInternal (from,to,assetId,amount) = {
302302 let checks = validateAssetId(assetId)
303303 if ((checks == checks))
304304 then {
305305 let realShares = userShares(assetId, from)
306- let $t074677751 = if ((amount == -1))
306+ let $t074277711 = if ((amount == -1))
307307 then {
308308 let realAmount = sharesToAmount(assetId, realShares)
309309 $Tuple2(realShares, realAmount)
310310 }
311311 else if ((0 >= amount))
312312 then throw("protected-reserve: non-positive amount")
313313 else $Tuple2(amountToShares(assetId, amount, true), amount)
314- let wdShares = $t074677751._1
315- let wdAmount = $t074677751._2
314+ let wdShares = $t074277711._1
315+ let wdAmount = $t074277711._2
316316 let maybeCleanUp = if ((realShares == wdShares))
317317 then [BooleanEntry(hasProtectedStore(from), false), DeleteEntry(protectedAssetStore(from))]
318318 else nil
319319 let staking = stakingAction(assetId, wdAmount)
320320 if ((staking == staking))
321321 then $Tuple2((maybeCleanUp ++ [changeBy(totalDepositStore(assetId), -(wdAmount)), changeBy(totalSharesStore(assetId), -(wdShares)), changeBy(userSharesStore(assetId, from), -(wdShares)), ScriptTransfer(addressFromStringValue(to), wdAmount, assetStrToId(assetId))]), wdAmount)
322322 else throw("Strict value is not equal to itself.")
323323 }
324324 else throw("Strict value is not equal to itself.")
325325 }
326326
327327
328328 func supplyInternal (user,i) = if (hasRegularDeposit(user))
329329 then throw("protected-reserve: can't have protected when regular exists")
330330 else if ((size(i.payments) != 1))
331331 then throw("protected-reserve: single payment required")
332332 else {
333333 let assetId = assetIdStr(i.payments[0].assetId)
334334 let amount = i.payments[0].amount
335335 if ((amount == 0))
336336 then nil
337337 else {
338338 let checks = if (validateAssetId(assetId))
339339 then opAllowed(assetId, "supply_protected_collateral")
340340 else false
341341 if ((checks == checks))
342342 then {
343343 let protectedFlag = valueOrElse(getBoolean(this, hasProtectedStore(user)), false)
344344 let protectedAsset = getString(this, protectedAssetStore(user))
345345 let consistency = if (protectedFlag)
346346 then match protectedAsset {
347347 case s: String =>
348348 if ((s == assetId))
349349 then true
350350 else throw("protected-reserve: can't have more than one asset protected")
351351 case _ =>
352352 throw("protected-reserve:clean up first")
353353 }
354354 else match protectedAsset {
355355 case s: String =>
356356 throw("protected-reserve: misconfiguration")
357357 case _ =>
358358 true
359359 }
360360 let consistencyCheck = throwIf(!(consistency), "inconsistency")
361361 if ((consistencyCheck == consistencyCheck))
362362 then {
363363 let newShares = amountToShares(assetId, amount, false)
364364 let staking = stakingAction(assetId, 0)
365365 if ((staking == staking))
366366 then [changeBy(totalDepositStore(assetId), amount), changeBy(totalSharesStore(assetId), newShares), changeBy(userSharesStore(assetId, user), newShares), BooleanEntry(hasProtectedStore(user), true), StringEntry(protectedAssetStore(user), assetId)]
367367 else throw("Strict value is not equal to itself.")
368368 }
369369 else throw("Strict value is not equal to itself.")
370370 }
371371 else throw("Strict value is not equal to itself.")
372372 }
373373 }
374374
375375
376376 @Callable(i)
377377 func initialize (configAddress) = [writeConstString(configAddressStore, configAddress)]
378+
379+
380+
381+@Callable(i)
382+func unstake (assetId) = {
383+ func asInt (value) = match value {
384+ case int: Int =>
385+ int
386+ case _ =>
387+ throw("_pr:1")
388+ }
389+
390+ if (stakingEnabled(assetId))
391+ then throw(("protected-reserve: staking is enabled for " + assetId))
392+ else {
393+ let sa = stakingAddress(assetId)
394+ let staked = asInt(invoke(sa, "info", nil, nil))
395+ if ((staked == staked))
396+ then {
397+ let unstaking = invoke(sa, "get", [staked], nil)
398+ if ((unstaking == unstaking))
399+ then $Tuple2(nil, staked)
400+ else throw("Strict value is not equal to itself.")
401+ }
402+ else throw("Strict value is not equal to itself.")
403+ }
404+ }
378405
379406
380407
381408 @Callable(i)
382409 func addInterest () = {
383410 let assetId = assetIdStr(i.payments[0].assetId)
384411 let checks = validateAssetId(assetId)
385412 if ((checks == checks))
386413 then {
387414 let staking = stakingAction(assetId, 0)
388415 if ((staking == staking))
389416 then {
390417 let amount = i.payments[0].amount
391418 [changeBy(totalDepositStore(assetId), amount)]
392419 }
393420 else throw("Strict value is not equal to itself.")
394421 }
395422 else throw("Strict value is not equal to itself.")
396423 }
397424
398425
399426
400427 @Callable(i)
401428 func borrowPower (user) = $Tuple2(nil, bp(user))
402429
403430
404431
405432 @Callable(i)
406433 func supply () = supplyInternal(toString(i.caller), i)
407434
408435
409436
410437 @Callable(i)
411438 func supplyFor (user) = {
412439 let checks = mainOnly(i)
413440 if ((checks == checks))
414441 then supplyInternal(user, i)
415442 else throw("Strict value is not equal to itself.")
416443 }
417444
418445
419446
420447 @Callable(i)
421448 func withdrawFor (user,assetId,amount) = {
422449 let checks = if (mainOnly(i))
423450 then opAllowed(assetId, "withdraw_protected_collateral")
424451 else false
425452 if ((checks == checks))
426453 then withdrawInternal(user, user, assetId, amount)
427454 else throw("Strict value is not equal to itself.")
428455 }
429456
430457
431458
432459 @Callable(i)
433460 func withdrawToMain (user,assetId) = {
434461 let checks = if (mainOnly(i))
435462 then opAllowed(assetId, "collapse_protected_collateral")
436463 else false
437464 if ((checks == checks))
438465 then withdrawInternal(user, toString(i.caller), assetId, -1)
439466 else throw("Strict value is not equal to itself.")
440467 }
441468
442469
443470
444471 @Callable(i)
445472 func withdrawToMain2 (user,assetId,amt) = {
446473 let checks = if (mainOnly(i))
447474 then opAllowed(assetId, "withdrawProtectedToMain2")
448475 else false
449476 if ((checks == checks))
450477 then withdrawInternal(user, toString(i.caller), assetId, amt)
451478 else throw("Strict value is not equal to itself.")
452479 }
453480
454481

github/deemru/w8io/786bc32 
55.79 ms