2023.05.16 12:49 [3645793] smart account 3PGmuH4HHaiGivvM1sPJy2igSYPsxCRCdjE > SELF 0.00000000 Waves

{ "type": 13, "id": "A2FTodt2LVJL5m9pcTvHKEPaQkRewxDwV6V7y1Gn66Vn", "fee": 5000000, "feeAssetId": null, "timestamp": 1684230555062, "version": 2, "chainId": 87, "sender": "3PGmuH4HHaiGivvM1sPJy2igSYPsxCRCdjE", "senderPublicKey": "G4sJED6Hzjrae57QsWCCcMuF6aT3jeiJ8EfvTVUCxSfC", "proofs": [ "5qWfKPLr1HcUYS1iiwwkFbdKLNwDsZ6oLVQ3VbVB7EHZgVZT7cNM6aLXQjzL7NCUhMGdPcr1ZuHtMvxtyET5mVqH" ], "script": "base64:BgLdDwgCEggKBggIAQEICBIECgIBARIDCgEIEgMKAQESAwoBCBIDCgEIEgMKAQgSBAoCCAESBQoDCAgBEgASAwoBCCIDU0VQIgVFTVBUWSIJUFJFQ0lTSU9OIhVNQVhfUkFURV9IRUlHSFRfREVMVEEiD09SQUNMRV9ERUNJTUFMUyIRTElRVUlEQVRJT05fQk9OVVMiGExJUVVJREFUSU9OX1BST1RPQ09MX0ZFRSISSWR4VmF1bHRBc3NldENvdW50IhNJZHhWYXVsdEFzc2V0QW1vdW50IhFJZHhWYXVsdEFzc2V0UmF0ZSIEZGl2cCICX3giAl95IgRtdWxwIgRqb2luIgJhciIOa2V5SW5pdGlhbGl6ZWQiFWtleUNvb3JkaW5hdG9yQWRkcmVzcyISa2V5VmVyaWZpZXJBZGRyZXNzIhJrZXlGcm9udGVuZEFkZHJlc3MiEmtleVRyZWFzdXJ5QWRkcmVzcyIQa2V5T3JhY2xlQWRkcmVzcyINa2V5VmF1bHRBc3NldCIHYWRkcmVzcyIFYXNzZXQiD2tleUJhY2tpbmdSYXRpbyITa2V5TGlxdWlkYXRpb25SYXRpbyIZa2V5TGlxdWlkYXRpb25Qcm90b2NvbEZlZSIJa2V5VGlja2VyIhVrZXlNYXhSYXRlSGVpZ2h0RGVsdGEiEmtleUNvbnRyYWN0QXNzZXRJZCIUa2V5T3JhY2xlVGlja2VyUHJpY2UiBnRpY2tlciIaa2V5T3JhY2xlVGlja2VyUHJpY2VIZWlnaHQiCWtleVNpZ25lZCIIX2FkZHJlc3MiBV90eElkIhFrZXlQcm90b2NvbEFjdGl2ZSINaXNJbml0aWFsaXplZCIPbXVzdEluaXRpYWxpemVkIhJtdXN0Tm90SW5pdGlhbGl6ZWQiCG11c3RTZWxmIgFpIgtjb29yZGluYXRvciIGb3JhY2xlIgh2ZXJpZmllciIHJG1hdGNoMCIBcyIKZ2V0QWRkcmVzcyIDa2V5IgNlcnIiEmdldEZyb250ZW5kQWRkcmVzcyISZ2V0VHJlYXN1cnlBZGRyZXNzIhVnZXRNYXhSYXRlSGVpZ2h0RGVsdGEiGWdldExpcXVpZGF0aW9uUHJvdG9jb2xGZWUiCmdldEFzc2V0SWQiCGlzQWN0aXZlIgptdXN0QWN0aXZlIgxtdXN0RnJvbnRlbmQiEm11c3RIYXZlT25lUGF5bWVudCIKaXNQb3NpdGl2ZSIGbnVtYmVyIg1pc05vdE5lZ2F0aXZlIhRnZXRBc3NldElkRnJvbVN0cmluZyIHYXNzZXRJZCIHaXNBc3NldCIBcCINY2hlY2tpbmdBc3NldCICYnYiBG5hbWUiByRtYXRjaDEiDHBheW1lbnRBc3NldCIPZ2V0QmFja2luZ1JhdGlvIhNnZXRMaXF1aWRhdGlvblJhdGlvIgxjaGVja0FkZHJlc3MiFWtleVRvdGFsQXNzZXRBY2NlcHRlZCISa2V5VG90YWxFYXN0TWludGVkIhJrZXlFYXN0TWludGVkTGltaXQiEGtleVN0YWtlckFkZHJlc3MiFWdldFRvdGFsQXNzZXRBY2NlcHRlZCISZ2V0VG90YWxFYXN0TWludGVkIhJnZXRFYXN0TWludGVkTGltaXQiEGdldFN0YWtlckFkZHJlc3MiBnN0YWtlciIIaXNTdGFrZWQiEmNoZWNrQmFja2luZ1JhdGlvcyIDX2JyIgNfbHIiDGdldFZhdWx0RGF0YSIIZnJvbnRlbmQiBXZhdWx0IgF2IgVjb3VudCILYXNzZXRBbW91bnQiBHJhdGUiEGNoZWNrSGVpZ2h0RGVsdGEiC3ByaWNlSGVpZ2h0Ig5tYXhIZWlnaHREZWx0YSILY3VycmVudERpZmYiEGdldEFzc2V0VXNkUHJpY2UiC2NoZWNrSGVpZ2h0IgVwcmljZSILdXBkYXRlVmF1bHQiB19hbW91bnQiDSR0MDExNjA3MTE2NTYiCG5ld0NvdW50Ig5uZXdBc3NldEFtb3VudCIJYXNzZXRSYXRlIg9jb3VudEVxdWl2YWxlbnQiDGJhY2tpbmdSYXRpbyIFdXNkRXEiBmVhc3RFcSITX2Nvb3JkaW5hdG9yQWRkcmVzcyIOX29yYWNsZUFkZHJlc3MiDV9iYWNraW5nUmF0aW8iEV9saXF1aWRhdGlvblJhdGlvIghfYXNzZXRJZCIHX3RpY2tlciIGY2hlY2tzIgVjaGVjayIQX2Vhc3RNaW50ZWRMaW1pdCIHcGF5bWVudCIKdmF1bHRBc3NldCINJHQwMTQyNjAxNDMxMyIVbmV3VG90YWxBc3NldEFjY2VwdGVkIhJuZXdUb3RhbEVhc3RNaW50ZWQiD2Vhc3RNaW50ZWRMaW1pdCIIZG9BY3Rpb24iDHVwZGF0ZWRWYXVsdCINJHQwMTU5ODcxNjAzMyISX2xpcXVpZGF0b3JBZGRyZXNzIgZfcmF0aW8iDmFzc2V0UmVxdWVzdGVkIg0kdDAxNzEyMzE3MTc2IgNmZWUiCmxpcXVpZGF0ZWQiD3RyZWFzdXJ5QWRkcmVzcyIRbGlxdWlkYXRvckFkZHJlc3MiDSR0MDE4MTYzMTgyMTMiEGxpcXVpZGF0aW9uUmF0aW8iCXRocmVzaG9sZCICdHgiBnZlcmlmeUYAAWECAl9fAAFiAgAAAWMAgKCUpY0dAAFkAAUAAWUAwIQ9AAFmCQBoAgkAaQIFAWMAZAAFAAFnCQBoAgkAaQIFAWMAZAACAAFoAAEAAWkAAgABagADAQFrAgFsAW0JAG4EBQFsBQFjBQFtBQhIQUxGRVZFTgEBbgIBbAFtCQBuBAUBbAUBbQUBYwUISEFMRkVWRU4BAW8BAXAJALkJAgUBcAUBYQEBcQAJAQFvAQkAzAgCAgIlcwkAzAgCAgtpbml0aWFsaXplZAUDbmlsAQFyAAkBAW8BCQDMCAICAiVzCQDMCAICEmNvb3JkaW5hdG9yQWRkcmVzcwUDbmlsAQFzAAkBAW8BCQDMCAICAiVzCQDMCAICD3ZlcmlmaWVyQWRkcmVzcwUDbmlsAQF0AAkBAW8BCQDMCAICAiVzCQDMCAICD2Zyb250ZW5kQWRkcmVzcwUDbmlsAQF1AAkBAW8BCQDMCAICAiVzCQDMCAICD3RyZWFzdXJ5QWRkcmVzcwUDbmlsAQF2AAkBAW8BCQDMCAICAiVzCQDMCAICDW9yYWNsZUFkZHJlc3MFA25pbAEBdwIBeAF5CQEBbwEJAMwIAgIGJXMlcyVzCQDMCAICBXZhdWx0CQDMCAIFAXgJAMwIAgUBeQUDbmlsAQF6AAkBAW8BCQDMCAICAiVzCQDMCAICDGJhY2tpbmdSYXRpbwUDbmlsAQFBAAkBAW8BCQDMCAICAiVzCQDMCAICEGxpcXVpZGF0aW9uUmF0aW8FA25pbAEBQgAJAQFvAQkAzAgCAgIlcwkAzAgCAhZsaXF1aWRhdGlvblByb3RvY29sRmVlBQNuaWwBAUMACQEBbwEJAMwIAgICJXMJAMwIAgIGdGlja2VyBQNuaWwBAUQACQEBbwEJAMwIAgICJXMJAMwIAgISbWF4UmF0ZUhlaWdodERlbHRhBQNuaWwBAUUACQEBbwEJAMwIAgICJXMJAMwIAgIPY29udHJhY3RBc3NldElkBQNuaWwBAUYBAUcJAQFvAQkAzAgCAgQlcyVzCQDMCAICBXByaWNlCQDMCAIFAUcFA25pbAEBSAEBRwkBAW8BCQDMCAICBCVzJXMJAMwIAgIKbGFzdEhlaWdodAkAzAgCBQFHBQNuaWwBAUkCAUoBSwkBAW8BCQDMCAICBiVzJXMlcwkAzAgCAgZzaWduZWQJAMwIAgUBSgkAzAgCBQFLBQNuaWwBAUwACQEBbwEJAMwIAgICJXMJAMwIAgIOcHJvdG9jb2xBY3RpdmUFA25pbAEBTQAJAQt2YWx1ZU9yRWxzZQIJAJsIAgUEdGhpcwkBAXEABwEBTgADCQEBIQEJAQFNAAkAAgECD05vdCBpbml0aWFsaXplZAUEdW5pdAEBTwADCQEBTQAJAAIBAhNBbHJlYWR5IGluaXRpYWxpemVkBQR1bml0AQFQAQFRAwkBAiE9AggFAVEGY2FsbGVyBQR0aGlzCQACAQIdT25seSBzZWxmIGludm9jYXRpb24gYWxsb3dlZC4FBHVuaXQBAVIACQERQGV4dHJOYXRpdmUoMTA2MikBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBAXIAAhZDb29yZGluYXRvciBpcyBub3Qgc2V0AQFTAAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJAQF2AAIRT3JhY2xlIGlzIG5vdCBzZXQBAVQABAFVCQCiCAEJAQFyAAMJAAECBQFVAgZTdHJpbmcEAVYFAVUJAJ0IAgkBEUBleHRyTmF0aXZlKDEwNjIpAQUBVgkBAXMAAwkAAQIFAVUCBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgEBVwIBWAFZCQERQGV4dHJOYXRpdmUoMTA2MikBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgkBAVIABQFYBQFZAQFaAAkBAVcCCQEBdAACE0Zyb250ZW5kIGlzIG5vdCBzZXQBAmFhAAkBAVcCCQEBdQACE1RyZWFzdXJ5IGlzIG5vdCBzZXQBAmFiAAkBC3ZhbHVlT3JFbHNlAgkAmggCCQEBUgAJAQFEAAUBZAECYWMACQELdmFsdWVPckVsc2UCCQCaCAIJAQFSAAkBAUIABQFnAQJhZAAJARFAZXh0ck5hdGl2ZSgxMDU4KQEJAQFFAAECYWUACQELdmFsdWVPckVsc2UCCQCbCAIJAQFSAAkBAUwABwECYWYAAwMJAQEhAQkBAmFlAAYJAQEhAQkBAU0ACQACAQItUHJvdG9jb2wgaXMgZGlzYWJsZWQuIFBsZWFzZSBjb250YWN0IHN1cHBvcnQuBQR1bml0AQJhZwEBUQMJAQIhPQIIBQFRBmNhbGxlcgkBAVoACQACAQILTm90IGFsbG93ZWQFBHVuaXQBAmFoAQFRAwkBAiE9AgkAkAMBCAUBUQhwYXltZW50cwABCQACAQIWTXVzdCBoYXZlIG9uZSBwYXltZW50LgUEdW5pdAECYWkBAmFqAwkAZwIAAAUCYWoJAAIBAh1BdHRyaWJ1dGUgc2hvdWxkIGJlIHBvc2l0aXZlLgUEdW5pdAECYWsBAmFqAwkAZgIAAAUCYWoJAAIBAiVBdHRyaWJ1dGUgc2hvdWxkIGJlIHBvc2l0aXZlIG9yIHplcm8uBQR1bml0AQJhbAECYW0DCQAAAgUCYW0CBVdBVkVTBQR1bml0CQDZBAEFAmFtAQJhbgICYW8CYXAEAmFtBAFVBQJhcAMJAAECBQFVAgpCeXRlVmVjdG9yBAJhcQUBVQUCYXEDCQABAgUBVQIGU3RyaW5nBAFWBQFVCQECYWwBBQFWAwkAAQIFAVUCBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgQBVQUCYW0DCQABAgUBVQIKQnl0ZVZlY3RvcgQCYXEFAVUEAmFyBAJhcwkA7AcBBQJhcQMJAAECBQJhcwIFQXNzZXQEAXkFAmFzCAUBeQRuYW1lAwkAAQIFAmFzAgRVbml0CQACAQkArAICAhFDYW4ndCBmaW5kIGFzc2V0IAkA2AQBBQJhcQkAAgECC01hdGNoIGVycm9yBAFZCQACAQkArAICAh5BdHRhY2hlZCBwYXltZW50IGFzc2V0IGlzIG5vdCAFAmFyBAJhcwgFAmFvB2Fzc2V0SWQDCQABAgUCYXMCCkJ5dGVWZWN0b3IEAmF0BQJhcwMJAQIhPQIFAmF0BQJhbQUBWQUEdW5pdAMJAAECBQJhcwIEVW5pdAUBWQkAAgECC01hdGNoIGVycm9yAwkAAQIFAVUCBFVuaXQDCQECIT0CCAUCYW8HYXNzZXRJZAUEdW5pdAkAAgECI0F0dGFjaGVkIHBheW1lbnQgYXNzZXQgaXMgbm90IFdBVkVTBQR1bml0CQACAQILTWF0Y2ggZXJyb3IBAmF1AAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEJAQF6AAIYQmFja2luZyByYXRpbyBpcyBub3Qgc2V0AQJhdgAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBCQEBQQACHExpcXVpZGF0aW9uIHJhdGlvIGlzIG5vdCBzZXQBAmF3AQFKBAFVCQCmCAEFAUoDCQABAgUBVQIHQWRkcmVzcwQBeAUBVQYDCQABAgUBVQIEVW5pdAkAAgECD0ludmFsaWQgYWRkcmVzcwkAAgECC01hdGNoIGVycm9yAQJheAAJAQFvAQkAzAgCAgIlcwkAzAgCAhJ0b3RhbEFzc2V0QWNjZXB0ZWQFA25pbAECYXkACQEBbwEJAMwIAgICJXMJAMwIAgIPdG90YWxFYXN0TWludGVkBQNuaWwBAmF6AAkBAW8BCQDMCAICAiVzCQDMCAICD2Vhc3RNaW50ZWRMaW1pdAUDbmlsAQJhQQAJAQFvAQkAzAgCAgIlcwkAzAgCAg1zdGFrZXJBZGRyZXNzBQNuaWwBAmFCAAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQECYXgAAAABAmFDAAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQECYXkAAAABAmFEAAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQECYXoAAAABAmFFAAkBC3ZhbHVlT3JFbHNlAgkAoggBCQECYUEABQFiAQJhRgAJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQJhRQABAmFHAAkBAiE9AgkBAmFFAAUBYgECYUgCAmFJAmFKAwMJAGYCAAAFAmFKBgkAZgIAAAUCYUkJAAIBAh5CYWNraW5nIHJhdGlvIG11c3QgYmUgcG9zaXRpdmUDCQBmAgkAZAIFAWMFAWYFAmFKCQACAQIqTGlxdWlkYXRpb24gcmF0aW8gbXVzdCBiZSBoaWdoZXIgdGhhbiAxMDUlAwkAZwIFAmFKBQJhSQkAAgECM0JhY2tpbmcgcmF0aW8gbXVzdCBiZSBoaWdoZXIgdGhhbiBsaXF1aWRhdGlvbiByYXRpbwUEdW5pdAECYUsBAUoEAXkJAQJhZAAEAmFMCQEBWgAEAmFNCQCdCAIFAmFMCQEBdwIFAUoFAXkEAmFOBAFVBQJhTQMJAAECBQFVAgRVbml0CQDMCAICBiVkJWQlZAkAzAgCAgEwCQDMCAICATAJAMwIAgIBMAUDbmlsAwkAAQIFAVUCBlN0cmluZwQBVgUBVQkAtQkCBQFWBQFhCQACAQILTWF0Y2ggZXJyb3IEAmFPCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYU4FAWgEAmFQCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYU4FAWkEAmFRCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYU4FAWoJAJUKAwUCYVAFAmFPBQJhUQECYVIBAmFTBAJhVAkBAmFiAAQCYVUJAGUCCAUJbGFzdEJsb2NrBmhlaWdodAUCYVMDCQBnAgUCYVQFAmFVBQR1bml0CQACAQISTGFyZ2UgcHJpY2UgZGVsdGEuAQJhVgAEAUcJARFAZXh0ck5hdGl2ZSgxMDU4KQEJAQFDAAQCYVMJARFAZXh0ck5hdGl2ZSgxMDUwKQIJAQFTAAkBAUgBBQFHBAJhVwkBAmFSAQUCYVMDCQAAAgUCYVcFAmFXBAJhWAkBEUBleHRyTmF0aXZlKDEwNTApAgkBAVMACQEBRgEFAUcJAGsDBQJhWAUBYwUBZQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECYVkCAUoCYVoEAmJhCQECYUsBBQFKBAJhUAgFAmJhAl8xBAJhTwgFAmJhAl8yBAJiYgkAZAIFAmFPAAEEAmJjCQBkAgUCYVAFAmFaAwkAZgIAAAUCYmMJAAIBAiZTb21ldGhpbmcgd2VudCB3cm9uZy4gQ29udGFjdCBzdXBwb3J0LgQCYmQJAQJhVgAJALkJAgkAzAgCAgYlZCVkJWQJAMwIAgkApAMBBQJiYgkAzAgCCQCkAwEFAmJjCQDMCAIJAKQDAQUCYmQFA25pbAUBYQECYmUBAmFaBAJiZgkBAmF1AAQCYmQJAQJhVgAEAmJnCQEBbgIFAmFaBQJiZAQCYmgJAQFrAgUCYmcFAmJmCQCUCgIFAmJnBQJiaAsBUQEKaW5pdGlhbGl6ZQYCYmkCYmoCYmsCYmwCYm0CYm4EAmJvCQDMCAIJAQFPAAkAzAgCCQECYXcBBQJiaQkAzAgCCQECYXcBBQJiagkAzAgCCQECYUgCBQJiawUCYmwFA25pbAMJAAACBQJibwUCYm8JAMwIAgkBDEludGVnZXJFbnRyeQIJAQF6AAUCYmsJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFBAAUCYmwJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAXIABQJiaQkAzAgCCQELU3RyaW5nRW50cnkCCQEBdgAFAmJqCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQFDAAUCYm4JAMwIAgkBC1N0cmluZ0VudHJ5AgkBAUUABQJibQkAzAgCCQEMQm9vbGVhbkVudHJ5AgkBAXEABgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAVEBCXNldFJhdGlvcwICYmsCYmwEAmJvCQDMCAIJAQFOAAkAzAgCCQEBUAEFAVEJAMwIAgkBAmFIAgUCYmsFAmJsBQNuaWwDCQAAAgUCYm8FAmJvCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBegAFAmJrCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBQQAFAmJsBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BUQEJc2V0T3JhY2xlAQFKBAJicAkAzAgCCQEBUAEFAVEJAMwIAgkBAmF3AQUBSgUDbmlsAwkAAAIFAmJwBQJicAkAzAgCCQELU3RyaW5nRW50cnkCCQEBdgAFAUoFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFRARJzZXRFYXN0TWludGVkTGltaXQBAmJxBAJibwkAzAgCCQEBTgAJAMwIAgkBAVABBQFRCQDMCAIJAQJhawEFAmJxBQNuaWwDCQAAAgUCYm8FAmJvCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYXoABQJicQUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAVEBCXNldFN0YWtlcgEBSgQCYm8JAMwIAgkBAU4ACQDMCAIJAQFQAQUBUQkAzAgCCQECYXcBBQFKBQNuaWwDCQAAAgUCYm8FAmJvAwkBAmFHAAkAAgECKVVuYWJsZSB0byBwcm9jZWVkLiBTdGFrZXIgaXMgYWxyZWFkeSBzZXQuCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhQQAFAUoFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFRAQRtaW50AQFKBAJicgkAkQMCCAUBUQhwYXltZW50cwAABAJicwkBAmFkAAQCYnAJAMwIAgkBAmFmAAkAzAgCCQECYWcBBQFRCQDMCAIJAQJhaAEFAVEJAMwIAgkBAmFuAgUCYnIFAmJzBQNuaWwDCQAAAgUCYnAFAmJwBAJidAkBAmJlAQgFAmJyBmFtb3VudAQCYmcIBQJidAJfMQQCYmgIBQJidAJfMgQCYU0JAQJhWQIFAUoIBQJicgZhbW91bnQEAmJ1CQBkAgkBAmFCAAgFAmJyBmFtb3VudAQCYnYJAGQCCQECYUMACQBpAgUCYmgAZAQCYncJAQJhRAADAwkAZgIFAmJ3AAAJAGYCBQJidgUCYncHCQACAQI4VW5hYmxlIHRvIHByb2NlZWQuIFRvbyBtdWNoIEVBU1QgbWludGVkIHdpdGggdGhpcyBhc3NldC4EAmJ4AwkBAmFHAAkA/AcECQECYUYAAgVzdGFrZQUDbmlsCQDMCAIFAmJyBQNuaWwFBHVuaXQDCQAAAgUCYngFAmJ4CQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJheAAFAmJ1CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYXkABQJidgUDbmlsCQCUCgIFAmFNBQJiaAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFRAQZzdXBwbHkBAUoEAmJyCQCRAwIIBQFRCHBheW1lbnRzAAAEAmJzCQECYWQABAJicAkAzAgCCQECYWYACQDMCAIJAQJhZwEFAVEJAMwIAgkBAmFoAQUBUQkAzAgCCQECYW4CBQJicgUCYnMFA25pbAMJAAACBQJicAUCYnAEAmFNCQECYVkCBQFKCAUCYnIGYW1vdW50BAJidQkAZAIJAQJhQgAIBQJicgZhbW91bnQEAmJ4AwkBAmFHAAkA/AcECQECYUYAAgVzdGFrZQUDbmlsCQDMCAIFAmJyBQNuaWwFBHVuaXQDCQAAAgUCYngFAmJ4CQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJheAAFAmJ1BQNuaWwFAmFNCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAVEBBWNsb3NlAgFKAmFaBAJicAkAzAgCCQECYWYACQDMCAIJAQJhZwEFAVEJAMwIAgkBAmF3AQUBSgkAzAgCCQECYWkBBQJhWgUDbmlsAwkAAAIFAmJwBQJicAQCYVAICQECYUsBBQFKAl8xAwkAZgIFAmFaBQJhUAkAAgECLVVuYWJsZSB0byBwcm9jZWVkLiBOb3QgZW5vdWdoIGFzc2V0IGluIHZhdWx0LgMJAGYCBQJhWgkBAmFCAAkAAgECMFVuYWJsZSB0byBwcm9jZWVkLiBOb3QgZW5vdWdoIGFzc2V0IGluIHRyZWFzdXJ5LgQCYnkJAQJhWQIFAUoJAQEtAQUCYVoEAmJ6CQECYmUBBQJhWgQCYmcIBQJiegJfMQQCYmgIBQJiegJfMgQCYngDCQECYUcACQD8BwQJAQJhRgACB3Vuc3Rha2UJAMwIAgUCYVoFA25pbAUDbmlsBQR1bml0AwkAAAIFAmJ4BQJieAQCYW0JAQJhbAEJAQJhZAAEAXgJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAUoEAmJ1CQBlAgkBAmFCAAUCYVoEAmJ2CQBlAgkBAmFDAAkAaQIFAmJoAGQJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmF4AAUCYnUJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJheQAFAmJ2CQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAXgFAmFaBQJhbQUDbmlsCQCVCgMFAmJ5BQJiaAUCYmcJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BUQEJbGlxdWlkYXRlAwJiQQFKAmJCBAJicAkAzAgCCQECYWYACQDMCAIJAQJhZwEFAVEFA25pbAMJAAACBQJicAUCYnAEAmFQCAkBAmFLAQUBSgJfMQQCYkMJAQFuAgUCYVAFAmJCAwkAZgIFAmJDBQJhUAkAAgECLVVuYWJsZSB0byBwcm9jZWVkLiBOb3QgZW5vdWdoIGFzc2V0IGluIHZhdWx0LgMJAGYCBQJiQwkBAmFCAAkAAgECJFVuYWJsZSB0byBwcm9jZWVkLiBOb3QgZW5vdWdoIGFzc2V0LgQCYnkJAQJhWQIFAUoJAQEtAQUCYkMEAmJECQECYmUBBQJiQwQCYmcIBQJiRAJfMQQCYmgIBQJiRAJfMgQCYngDCQECYUcACQD8BwQJAQJhRgACB3Vuc3Rha2UJAMwIAgUCYkMFA25pbAUDbmlsBQR1bml0AwkAAAIFAmJ4BQJieAQCYkUJAQFuAgUCYkMJAQJhYwAEAmJGCQBlAgUCYkMFAmJFBAJidQkAZQIJAQJhQgAFAmJDBAJidgkAZQIJAQJhQwAJAGkCBQJiaABkBAJiRwkBAmFhAAQCYkgJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAmJBBAJhbQkBAmFsAQkBAmFkAAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYXgABQJidQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmF5AAUCYnYJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYkgFAmJGBQJhbQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJiRwUCYkUFAmFtBQNuaWwJAJQKAgUCYnkFAmJoCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAVEBEmdldEN1cnJlbnRVc2RQcmljZQAJAJQKAgUDbmlsCQECYVYAAVEBD2dldFN1YnZhdWx0SW5mbwEBSgQCYVAICQECYUsBBQFKAl8xBAJiSQkBAmJlAQUCYVAEAmJnCAUCYkkCXzEEAmJoCAUCYkkCXzIEAmJKCQECYXYABAJiSwkBAW4CBQJiZwUCYkoJAJQKAgUDbmlsCQCVCgMFAmJnBQJiaAUCYksBAmJMAQJiTQAEAVUJAQFUAAMJAAECBQFVAgZTdHJpbmcEAXgFAVUJAQt2YWx1ZU9yRWxzZQIJAJsIAgkBEUBleHRyTmF0aXZlKDEwNjIpAQUBeAkBAUkCCQClCAEFBHRoaXMJANgEAQgFAmJMAmlkBwkA9AMDCAUCYkwJYm9keUJ5dGVzCQCRAwIIBQJiTAZwcm9vZnMAAAgFAmJMD3NlbmRlclB1YmxpY0tleZRo5VE=", "height": 3645793, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: none Next: none Full:
OldNewDifferences
1-# no script
1+{-# STDLIB_VERSION 6 #-}
2+{-# SCRIPT_TYPE ACCOUNT #-}
3+{-# CONTENT_TYPE DAPP #-}
4+let SEP = "__"
5+
6+let EMPTY = ""
7+
8+let PRECISION = 1000000000000
9+
10+let MAX_RATE_HEIGHT_DELTA = 5
11+
12+let ORACLE_DECIMALS = 1000000
13+
14+let LIQUIDATION_BONUS = ((PRECISION / 100) * 5)
15+
16+let LIQUIDATION_PROTOCOL_FEE = ((PRECISION / 100) * 2)
17+
18+let IdxVaultAssetCount = 1
19+
20+let IdxVaultAssetAmount = 2
21+
22+let IdxVaultAssetRate = 3
23+
24+func divp (_x,_y) = fraction(_x, PRECISION, _y, HALFEVEN)
25+
26+
27+func mulp (_x,_y) = fraction(_x, _y, PRECISION, HALFEVEN)
28+
29+
30+func join (ar) = makeString(ar, SEP)
31+
32+
33+func keyInitialized () = join(["%s", "initialized"])
34+
35+
36+func keyCoordinatorAddress () = join(["%s", "coordinatorAddress"])
37+
38+
39+func keyVerifierAddress () = join(["%s", "verifierAddress"])
40+
41+
42+func keyFrontendAddress () = join(["%s", "frontendAddress"])
43+
44+
45+func keyTreasuryAddress () = join(["%s", "treasuryAddress"])
46+
47+
48+func keyOracleAddress () = join(["%s", "oracleAddress"])
49+
50+
51+func keyVaultAsset (address,asset) = join(["%s%s%s", "vault", address, asset])
52+
53+
54+func keyBackingRatio () = join(["%s", "backingRatio"])
55+
56+
57+func keyLiquidationRatio () = join(["%s", "liquidationRatio"])
58+
59+
60+func keyLiquidationProtocolFee () = join(["%s", "liquidationProtocolFee"])
61+
62+
63+func keyTicker () = join(["%s", "ticker"])
64+
65+
66+func keyMaxRateHeightDelta () = join(["%s", "maxRateHeightDelta"])
67+
68+
69+func keyContractAssetId () = join(["%s", "contractAssetId"])
70+
71+
72+func keyOracleTickerPrice (ticker) = join(["%s%s", "price", ticker])
73+
74+
75+func keyOracleTickerPriceHeight (ticker) = join(["%s%s", "lastHeight", ticker])
76+
77+
78+func keySigned (_address,_txId) = join(["%s%s%s", "signed", _address, _txId])
79+
80+
81+func keyProtocolActive () = join(["%s", "protocolActive"])
82+
83+
84+func isInitialized () = valueOrElse(getBoolean(this, keyInitialized()), false)
85+
86+
87+func mustInitialized () = if (!(isInitialized()))
88+ then throw("Not initialized")
89+ else unit
90+
91+
92+func mustNotInitialized () = if (isInitialized())
93+ then throw("Already initialized")
94+ else unit
95+
96+
97+func mustSelf (i) = if ((i.caller != this))
98+ then throw("Only self invocation allowed.")
99+ else unit
100+
101+
102+func coordinator () = addressFromStringValue(valueOrErrorMessage(getString(keyCoordinatorAddress()), "Coordinator is not set"))
103+
104+
105+func oracle () = addressFromStringValue(valueOrErrorMessage(getString(keyOracleAddress()), "Oracle is not set"))
106+
107+
108+func verifier () = match getString(keyCoordinatorAddress()) {
109+ case s: String =>
110+ getString(addressFromStringValue(s), keyVerifierAddress())
111+ case _: Unit =>
112+ unit
113+ case _ =>
114+ throw("Match error")
115+}
116+
117+
118+func getAddress (key,err) = addressFromStringValue(valueOrErrorMessage(getString(coordinator(), key), err))
119+
120+
121+func getFrontendAddress () = getAddress(keyFrontendAddress(), "Frontend is not set")
122+
123+
124+func getTreasuryAddress () = getAddress(keyTreasuryAddress(), "Treasury is not set")
125+
126+
127+func getMaxRateHeightDelta () = valueOrElse(getInteger(coordinator(), keyMaxRateHeightDelta()), MAX_RATE_HEIGHT_DELTA)
128+
129+
130+func getLiquidationProtocolFee () = valueOrElse(getInteger(coordinator(), keyLiquidationProtocolFee()), LIQUIDATION_PROTOCOL_FEE)
131+
132+
133+func getAssetId () = getStringValue(keyContractAssetId())
134+
135+
136+func isActive () = valueOrElse(getBoolean(coordinator(), keyProtocolActive()), false)
137+
138+
139+func mustActive () = if (if (!(isActive()))
140+ then true
141+ else !(isInitialized()))
142+ then throw("Protocol is disabled. Please contact support.")
143+ else unit
144+
145+
146+func mustFrontend (i) = if ((i.caller != getFrontendAddress()))
147+ then throw("Not allowed")
148+ else unit
149+
150+
151+func mustHaveOnePayment (i) = if ((size(i.payments) != 1))
152+ then throw("Must have one payment.")
153+ else unit
154+
155+
156+func isPositive (number) = if ((0 >= number))
157+ then throw("Attribute should be positive.")
158+ else unit
159+
160+
161+func isNotNegative (number) = if ((0 > number))
162+ then throw("Attribute should be positive or zero.")
163+ else unit
164+
165+
166+func getAssetIdFromString (assetId) = if ((assetId == "WAVES"))
167+ then unit
168+ else fromBase58String(assetId)
169+
170+
171+func isAsset (p,checkingAsset) = {
172+ let assetId = match checkingAsset {
173+ case bv: ByteVector =>
174+ bv
175+ case s: String =>
176+ getAssetIdFromString(s)
177+ case _: Unit =>
178+ unit
179+ case _ =>
180+ throw("Match error")
181+ }
182+ match assetId {
183+ case bv: ByteVector =>
184+ let name = match assetInfo(bv) {
185+ case asset: Asset =>
186+ asset.name
187+ case _: Unit =>
188+ throw(("Can't find asset " + toBase58String(bv)))
189+ case _ =>
190+ throw("Match error")
191+ }
192+ let err = throw(("Attached payment asset is not " + name))
193+ match p.assetId {
194+ case paymentAsset: ByteVector =>
195+ if ((paymentAsset != assetId))
196+ then err
197+ else unit
198+ case _: Unit =>
199+ err
200+ case _ =>
201+ throw("Match error")
202+ }
203+ case _: Unit =>
204+ if ((p.assetId != unit))
205+ then throw("Attached payment asset is not WAVES")
206+ else unit
207+ case _ =>
208+ throw("Match error")
209+ }
210+ }
211+
212+
213+func getBackingRatio () = valueOrErrorMessage(getInteger(keyBackingRatio()), "Backing ratio is not set")
214+
215+
216+func getLiquidationRatio () = valueOrErrorMessage(getInteger(keyLiquidationRatio()), "Liquidation ratio is not set")
217+
218+
219+func checkAddress (_address) = match addressFromString(_address) {
220+ case address: Address =>
221+ true
222+ case _: Unit =>
223+ throw("Invalid address")
224+ case _ =>
225+ throw("Match error")
226+}
227+
228+
229+func keyTotalAssetAccepted () = join(["%s", "totalAssetAccepted"])
230+
231+
232+func keyTotalEastMinted () = join(["%s", "totalEastMinted"])
233+
234+
235+func keyEastMintedLimit () = join(["%s", "eastMintedLimit"])
236+
237+
238+func keyStakerAddress () = join(["%s", "stakerAddress"])
239+
240+
241+func getTotalAssetAccepted () = valueOrElse(getInteger(keyTotalAssetAccepted()), 0)
242+
243+
244+func getTotalEastMinted () = valueOrElse(getInteger(keyTotalEastMinted()), 0)
245+
246+
247+func getEastMintedLimit () = valueOrElse(getInteger(keyEastMintedLimit()), 0)
248+
249+
250+func getStakerAddress () = valueOrElse(getString(keyStakerAddress()), EMPTY)
251+
252+
253+func staker () = addressFromStringValue(getStakerAddress())
254+
255+
256+func isStaked () = (getStakerAddress() != EMPTY)
257+
258+
259+func checkBackingRatios (_br,_lr) = if (if ((0 > _lr))
260+ then true
261+ else (0 > _br))
262+ then throw("Backing ratio must be positive")
263+ else if (((PRECISION + LIQUIDATION_BONUS) > _lr))
264+ then throw("Liquidation ratio must be higher than 105%")
265+ else if ((_lr >= _br))
266+ then throw("Backing ratio must be higher than liquidation ratio")
267+ else unit
268+
269+
270+func getVaultData (_address) = {
271+ let asset = getAssetId()
272+ let frontend = getFrontendAddress()
273+ let vault = getString(frontend, keyVaultAsset(_address, asset))
274+ let v = match vault {
275+ case _: Unit =>
276+["%d%d%d", "0", "0", "0"]
277+ case s: String =>
278+ split(s, SEP)
279+ case _ =>
280+ throw("Match error")
281+ }
282+ let count = parseIntValue(v[IdxVaultAssetCount])
283+ let assetAmount = parseIntValue(v[IdxVaultAssetAmount])
284+ let rate = parseIntValue(v[IdxVaultAssetRate])
285+ $Tuple3(assetAmount, count, rate)
286+ }
287+
288+
289+func checkHeightDelta (priceHeight) = {
290+ let maxHeightDelta = getMaxRateHeightDelta()
291+ let currentDiff = (lastBlock.height - priceHeight)
292+ if ((maxHeightDelta >= currentDiff))
293+ then unit
294+ else throw("Large price delta.")
295+ }
296+
297+
298+func getAssetUsdPrice () = {
299+ let ticker = getStringValue(keyTicker())
300+ let priceHeight = getIntegerValue(oracle(), keyOracleTickerPriceHeight(ticker))
301+ let checkHeight = checkHeightDelta(priceHeight)
302+ if ((checkHeight == checkHeight))
303+ then {
304+ let price = getIntegerValue(oracle(), keyOracleTickerPrice(ticker))
305+ fraction(price, PRECISION, ORACLE_DECIMALS)
306+ }
307+ else throw("Strict value is not equal to itself.")
308+ }
309+
310+
311+func updateVault (_address,_amount) = {
312+ let $t01160711656 = getVaultData(_address)
313+ let assetAmount = $t01160711656._1
314+ let count = $t01160711656._2
315+ let newCount = (count + 1)
316+ let newAssetAmount = (assetAmount + _amount)
317+ if ((0 > newAssetAmount))
318+ then throw("Something went wrong. Contact support.")
319+ else {
320+ let assetRate = getAssetUsdPrice()
321+ makeString(["%d%d%d", toString(newCount), toString(newAssetAmount), toString(assetRate)], SEP)
322+ }
323+ }
324+
325+
326+func countEquivalent (_amount) = {
327+ let backingRatio = getBackingRatio()
328+ let assetRate = getAssetUsdPrice()
329+ let usdEq = mulp(_amount, assetRate)
330+ let eastEq = divp(usdEq, backingRatio)
331+ $Tuple2(usdEq, eastEq)
332+ }
333+
334+
335+@Callable(i)
336+func initialize (_coordinatorAddress,_oracleAddress,_backingRatio,_liquidationRatio,_assetId,_ticker) = {
337+ let checks = [mustNotInitialized(), checkAddress(_coordinatorAddress), checkAddress(_oracleAddress), checkBackingRatios(_backingRatio, _liquidationRatio)]
338+ if ((checks == checks))
339+ then [IntegerEntry(keyBackingRatio(), _backingRatio), IntegerEntry(keyLiquidationRatio(), _liquidationRatio), StringEntry(keyCoordinatorAddress(), _coordinatorAddress), StringEntry(keyOracleAddress(), _oracleAddress), StringEntry(keyTicker(), _ticker), StringEntry(keyContractAssetId(), _assetId), BooleanEntry(keyInitialized(), true)]
340+ else throw("Strict value is not equal to itself.")
341+ }
342+
343+
344+
345+@Callable(i)
346+func setRatios (_backingRatio,_liquidationRatio) = {
347+ let checks = [mustInitialized(), mustSelf(i), checkBackingRatios(_backingRatio, _liquidationRatio)]
348+ if ((checks == checks))
349+ then [IntegerEntry(keyBackingRatio(), _backingRatio), IntegerEntry(keyLiquidationRatio(), _liquidationRatio)]
350+ else throw("Strict value is not equal to itself.")
351+ }
352+
353+
354+
355+@Callable(i)
356+func setOracle (_address) = {
357+ let check = [mustSelf(i), checkAddress(_address)]
358+ if ((check == check))
359+ then [StringEntry(keyOracleAddress(), _address)]
360+ else throw("Strict value is not equal to itself.")
361+ }
362+
363+
364+
365+@Callable(i)
366+func setEastMintedLimit (_eastMintedLimit) = {
367+ let checks = [mustInitialized(), mustSelf(i), isNotNegative(_eastMintedLimit)]
368+ if ((checks == checks))
369+ then [IntegerEntry(keyEastMintedLimit(), _eastMintedLimit)]
370+ else throw("Strict value is not equal to itself.")
371+ }
372+
373+
374+
375+@Callable(i)
376+func setStaker (_address) = {
377+ let checks = [mustInitialized(), mustSelf(i), checkAddress(_address)]
378+ if ((checks == checks))
379+ then if (isStaked())
380+ then throw("Unable to proceed. Staker is already set.")
381+ else [StringEntry(keyStakerAddress(), _address)]
382+ else throw("Strict value is not equal to itself.")
383+ }
384+
385+
386+
387+@Callable(i)
388+func mint (_address) = {
389+ let payment = i.payments[0]
390+ let vaultAsset = getAssetId()
391+ let check = [mustActive(), mustFrontend(i), mustHaveOnePayment(i), isAsset(payment, vaultAsset)]
392+ if ((check == check))
393+ then {
394+ let $t01426014313 = countEquivalent(payment.amount)
395+ let usdEq = $t01426014313._1
396+ let eastEq = $t01426014313._2
397+ let vault = updateVault(_address, payment.amount)
398+ let newTotalAssetAccepted = (getTotalAssetAccepted() + payment.amount)
399+ let newTotalEastMinted = (getTotalEastMinted() + (eastEq / 100))
400+ let eastMintedLimit = getEastMintedLimit()
401+ if (if ((eastMintedLimit > 0))
402+ then (newTotalEastMinted > eastMintedLimit)
403+ else false)
404+ then throw("Unable to proceed. Too much EAST minted with this asset.")
405+ else {
406+ let doAction = if (isStaked())
407+ then invoke(staker(), "stake", nil, [payment])
408+ else unit
409+ if ((doAction == doAction))
410+ then $Tuple2([IntegerEntry(keyTotalAssetAccepted(), newTotalAssetAccepted), IntegerEntry(keyTotalEastMinted(), newTotalEastMinted)], $Tuple2(vault, eastEq))
411+ else throw("Strict value is not equal to itself.")
412+ }
413+ }
414+ else throw("Strict value is not equal to itself.")
415+ }
416+
417+
418+
419+@Callable(i)
420+func supply (_address) = {
421+ let payment = i.payments[0]
422+ let vaultAsset = getAssetId()
423+ let check = [mustActive(), mustFrontend(i), mustHaveOnePayment(i), isAsset(payment, vaultAsset)]
424+ if ((check == check))
425+ then {
426+ let vault = updateVault(_address, payment.amount)
427+ let newTotalAssetAccepted = (getTotalAssetAccepted() + payment.amount)
428+ let doAction = if (isStaked())
429+ then invoke(staker(), "stake", nil, [payment])
430+ else unit
431+ if ((doAction == doAction))
432+ then $Tuple2([IntegerEntry(keyTotalAssetAccepted(), newTotalAssetAccepted)], vault)
433+ else throw("Strict value is not equal to itself.")
434+ }
435+ else throw("Strict value is not equal to itself.")
436+ }
437+
438+
439+
440+@Callable(i)
441+func close (_address,_amount) = {
442+ let check = [mustActive(), mustFrontend(i), checkAddress(_address), isPositive(_amount)]
443+ if ((check == check))
444+ then {
445+ let assetAmount = getVaultData(_address)._1
446+ if ((_amount > assetAmount))
447+ then throw("Unable to proceed. Not enough asset in vault.")
448+ else if ((_amount > getTotalAssetAccepted()))
449+ then throw("Unable to proceed. Not enough asset in treasury.")
450+ else {
451+ let updatedVault = updateVault(_address, -(_amount))
452+ let $t01598716033 = countEquivalent(_amount)
453+ let usdEq = $t01598716033._1
454+ let eastEq = $t01598716033._2
455+ let doAction = if (isStaked())
456+ then invoke(staker(), "unstake", [_amount], nil)
457+ else unit
458+ if ((doAction == doAction))
459+ then {
460+ let assetId = getAssetIdFromString(getAssetId())
461+ let address = addressFromStringValue(_address)
462+ let newTotalAssetAccepted = (getTotalAssetAccepted() - _amount)
463+ let newTotalEastMinted = (getTotalEastMinted() - (eastEq / 100))
464+ $Tuple2([IntegerEntry(keyTotalAssetAccepted(), newTotalAssetAccepted), IntegerEntry(keyTotalEastMinted(), newTotalEastMinted), ScriptTransfer(address, _amount, assetId)], $Tuple3(updatedVault, eastEq, usdEq))
465+ }
466+ else throw("Strict value is not equal to itself.")
467+ }
468+ }
469+ else throw("Strict value is not equal to itself.")
470+ }
471+
472+
473+
474+@Callable(i)
475+func liquidate (_liquidatorAddress,_address,_ratio) = {
476+ let check = [mustActive(), mustFrontend(i)]
477+ if ((check == check))
478+ then {
479+ let assetAmount = getVaultData(_address)._1
480+ let assetRequested = mulp(assetAmount, _ratio)
481+ if ((assetRequested > assetAmount))
482+ then throw("Unable to proceed. Not enough asset in vault.")
483+ else if ((assetRequested > getTotalAssetAccepted()))
484+ then throw("Unable to proceed. Not enough asset.")
485+ else {
486+ let updatedVault = updateVault(_address, -(assetRequested))
487+ let $t01712317176 = countEquivalent(assetRequested)
488+ let usdEq = $t01712317176._1
489+ let eastEq = $t01712317176._2
490+ let doAction = if (isStaked())
491+ then invoke(staker(), "unstake", [assetRequested], nil)
492+ else unit
493+ if ((doAction == doAction))
494+ then {
495+ let fee = mulp(assetRequested, getLiquidationProtocolFee())
496+ let liquidated = (assetRequested - fee)
497+ let newTotalAssetAccepted = (getTotalAssetAccepted() - assetRequested)
498+ let newTotalEastMinted = (getTotalEastMinted() - (eastEq / 100))
499+ let treasuryAddress = getTreasuryAddress()
500+ let liquidatorAddress = addressFromStringValue(_liquidatorAddress)
501+ let assetId = getAssetIdFromString(getAssetId())
502+ $Tuple2([IntegerEntry(keyTotalAssetAccepted(), newTotalAssetAccepted), IntegerEntry(keyTotalEastMinted(), newTotalEastMinted), ScriptTransfer(liquidatorAddress, liquidated, assetId), ScriptTransfer(treasuryAddress, fee, assetId)], $Tuple2(updatedVault, eastEq))
503+ }
504+ else throw("Strict value is not equal to itself.")
505+ }
506+ }
507+ else throw("Strict value is not equal to itself.")
508+ }
509+
510+
511+
512+@Callable(i)
513+func getCurrentUsdPrice () = $Tuple2(nil, getAssetUsdPrice())
514+
515+
516+
517+@Callable(i)
518+func getSubvaultInfo (_address) = {
519+ let assetAmount = getVaultData(_address)._1
520+ let $t01816318213 = countEquivalent(assetAmount)
521+ let usdEq = $t01816318213._1
522+ let eastEq = $t01816318213._2
523+ let liquidationRatio = getLiquidationRatio()
524+ let threshold = mulp(usdEq, liquidationRatio)
525+ $Tuple2(nil, $Tuple3(usdEq, eastEq, threshold))
526+ }
527+
528+
529+@Verifier(tx)
530+func verify () = match verifier() {
531+ case address: String =>
532+ valueOrElse(getBoolean(addressFromStringValue(address), keySigned(toString(this), toBase58String(tx.id))), false)
533+ case _ =>
534+ sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
535+}
536+

github/deemru/w8io/786bc32 
29.74 ms