tx · Ho8NaFeBXJDYPonGysPxBESR4yNTeygT8ZG5ecMCe9Tn

3MuFfcccPDaPFLFRZJoUocV868STc8wjRoE:  -0.05000000 Waves

2023.10.06 13:29 [2786640] smart account 3MuFfcccPDaPFLFRZJoUocV868STc8wjRoE > SELF 0.00000000 Waves

{ "type": 13, "id": "Ho8NaFeBXJDYPonGysPxBESR4yNTeygT8ZG5ecMCe9Tn", "fee": 5000000, "feeAssetId": null, "timestamp": 1696588240560, "version": 1, "sender": "3MuFfcccPDaPFLFRZJoUocV868STc8wjRoE", "senderPublicKey": "55j69b38Jc11a44VEKMFifbzFPc9gqpS2dzVMY6rbHyt", "proofs": [ "5rbudP4AoGgCFHNserMgZ38izS559nnj5i1VqqZoC8bUuxSMU6hDsvC8HVuJedKAY1eCH9xxh9VtPAGqayixY74X" ], "script": "base64:BgIsCAISABIDCgEIEgMKAQgSAwoBARIECgIIARIDCgEIEgMKAQgSABIAEgMKAQgnARB3cml0ZUNvbnN0U3RyaW5nAgNrZXkFdmFsdWUDCQEBIQEJAQlpc0RlZmluZWQBCQCdCAIFBHRoaXMFA2tleQkBC1N0cmluZ0VudHJ5AgUDa2V5BQV2YWx1ZQkAAgEJAKwCAgIVYWxyZWFkeSBpbml0aWFsaXplZDogBQNrZXkBCHdyaXRlSW50AgNrZXkFdmFsdWUDCQBmAgAABQV2YWx1ZQkAAgEJAKwCAgkArAICCQCsAgICF3dyaXRpbmcgbmVnYXRpdmUgdmFsdWUgCQCkAwEFBXZhbHVlAgkgZm9yIGtleSAFA2tleQkBDEludGVnZXJFbnRyeQIFA2tleQUFdmFsdWUBCGNoYW5nZUJ5AgNrZXkFdmFsdWUJAQh3cml0ZUludAIFA2tleQkAZAIJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUDa2V5AAAFBXZhbHVlABJjb25maWdBZGRyZXNzU3RvcmUCBmNvbmZpZwANY29uZmlnQWRkcmVzcwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQR0aGlzBRJjb25maWdBZGRyZXNzU3RvcmUCIXN0YWtpbmc6IGNvbmZpZyBhZGRyZXNzIG5vdCBmb3VuZAIWaW52YWxpZCBjb25maWcgYWRkcmVzcwEHYWxsb3dlZAECb3AJAPwHBAUNY29uZmlnQWRkcmVzcwIJb3BBbGxvd2VkCQDMCAIFAm9wBQNuaWwFA25pbAANcHdyQXNzZXRJZFN0cgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFDWNvbmZpZ0FkZHJlc3MCDHBvd2VyQXNzZXRJZAIWcHdyIGFzc2V0IGlkIG5vdCBmb3VuZAAKcHdyQXNzZXRJZAkA2QQBBQ1wd3JBc3NldElkU3RyAA5taW50ZXJDb250cmFjdAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ1jb25maWdBZGRyZXNzAg9jb250cmFjdF9taW50ZXICEm5vIGNvbnRyYWN0X21pbnRlcgIXaW52YWxpZCBtaW50ZXIgY29udHJhY3QADW1haW5BZGRyZXNzZXMJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUNY29uZmlnQWRkcmVzcwIObWFpbl9hZGRyZXNzZXMCAAALbWluTG9ja1RpbWUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQ1jb25maWdBZGRyZXNzCQCsAgIJAKUIAQUEdGhpcwIOX21pbl9sb2NrX3RpbWUCFW1pbl9sb2NrX3RpbWUgbm90IHNldAEPdXNlclNoYXJlc1N0b3JlAQR1c2VyCQCsAgIFBHVzZXICB19zaGFyZXMBC3N0b3JlSGVpZ2h0AQVzdG9yZQkArAICBQVzdG9yZQIHX2hlaWdodAEJc3RvcmVMb2NrAQVzdG9yZQkArAICBQVzdG9yZQIFX2xvY2sBC3N0YWtlSGVpZ2h0AQdhZGRyZXNzCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUEdGhpcwkBC3N0b3JlSGVpZ2h0AQkBD3VzZXJTaGFyZXNTdG9yZQEFB2FkZHJlc3MCD25vIHN0YWtlIGhlaWdodAEKbG9ja0hlaWdodAEHYWRkcmVzcwkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEJc3RvcmVMb2NrAQkBD3VzZXJTaGFyZXNTdG9yZQEFB2FkZHJlc3MAAAEMdW5sb2NrSGVpZ2h0AQdhZGRyZXNzCQBkAgkBCmxvY2tIZWlnaHQBBQdhZGRyZXNzBQttaW5Mb2NrVGltZQENdW5zdGFrZUhlaWdodAEHYWRkcmVzcwkAZAIJAQtzdGFrZUhlaWdodAEFB2FkZHJlc3MFC21pbkxvY2tUaW1lAAhzbGFzaGVycwkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ1jb25maWdBZGRyZXNzCQCsAgIJAKUIAQUEdGhpcwIJX3NsYXNoZXJzAgAABkhFSUdIVAUGaGVpZ2h0ABFzdGFrZWRIZWlnaHRTdG9yZQIMc3Rha2VkSGVpZ2h0ABB0b3RhbFNoYXJlc1N0b3JlAgt0b3RhbFNoYXJlcwALc3Rha2VkU3RvcmUCBnN0YWtlZAAFUkJhc2UAgICE/qbe4REAA2FwcgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFDWNvbmZpZ0FkZHJlc3MJAKwCAgkApQgBBQR0aGlzAgtfc3Rha2VyX2FwcgINbm8gc3Rha2VyX2FwcgANYmxvY2tzUGVyWWVhcgkAaAIJAGgCAO0CABgAPAAJUlBlckJsb2NrCQBrAwUDYXByBQVSQmFzZQkAaAIA6AcFDWJsb2Nrc1BlclllYXIAC3RvdGFsU3Rha2VkCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFC3N0YWtlZFN0b3JlAAAADWN1cnJlbnRTdGFrZWQEDHN0YWtlZEhlaWdodAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBRFzdGFrZWRIZWlnaHRTdG9yZQAABAFkCQBlAgUGSEVJR0hUBQxzdGFrZWRIZWlnaHQEAXIJAGQCBQVSQmFzZQkAaAIFAWQFCVJQZXJCbG9jawkAawMFC3RvdGFsU3Rha2VkBQFyBQVSQmFzZQELcHdyVG9TaGFyZXMBCXB3ckFtb3VudAQLdG90YWxTaGFyZXMJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUQdG90YWxTaGFyZXNTdG9yZQAAAwkAAAIFC3RvdGFsU2hhcmVzAAAFCXB3ckFtb3VudAkAawMFCXB3ckFtb3VudAULdG90YWxTaGFyZXMFDWN1cnJlbnRTdGFrZWQBC3NoYXJlc1RvUHdyAQxzaGFyZXNBbW91bnQEC3RvdGFsU2hhcmVzCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFEHRvdGFsU2hhcmVzU3RvcmUAAAMJAAACBQt0b3RhbFNoYXJlcwAABQxzaGFyZXNBbW91bnQJAGsDBQxzaGFyZXNBbW91bnQFDWN1cnJlbnRTdGFrZWQFC3RvdGFsU2hhcmVzARBlbnN1cmVQd3JCYWxhbmNlAQZhbW91bnQECnB3ckJhbGFuY2UJAPAHAgUEdGhpcwUKcHdyQXNzZXRJZAMJAGYCBQZhbW91bnQFCnB3ckJhbGFuY2UEBG1pbnQJAPwHBAUObWludGVyQ29udHJhY3QCBG1pbnQJAMwIAgkAZQIFBmFtb3VudAUKcHdyQmFsYW5jZQUDbmlsBQNuaWwDCQAAAgUEbWludAUEbWludAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBQNuaWwBBnBheW91dAIEdXNlcgZhbW91bnQEBmVuc3VyZQkBEGVuc3VyZVB3ckJhbGFuY2UBBQZhbW91bnQDCQAAAgUGZW5zdXJlBQZlbnN1cmUJAQ5TY3JpcHRUcmFuc2ZlcgMJARFAZXh0ck5hdGl2ZSgxMDYyKQEFBHVzZXIFBmFtb3VudAUKcHdyQXNzZXRJZAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgEGc2hhcmVzAQdhZGRyZXNzCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQ91c2VyU2hhcmVzU3RvcmUBBQdhZGRyZXNzAAABBnN0YWtlZAEHYWRkcmVzcwkBC3NoYXJlc1RvUHdyAQkBBnNoYXJlcwEFB2FkZHJlc3MBBmFkdmlzZQAEC3RvdGFsU2hhcmVzCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFEHRvdGFsU2hhcmVzU3RvcmUAAAQMdG90YWxTdGFrZWQxCQELc2hhcmVzVG9Qd3IBBQt0b3RhbFNoYXJlcwkArAICCQCsAgIJAKwCAgkArAICCQCsAgICCGhlaWdodDogCQCkAwEFBkhFSUdIVAIPLCB0b3RhbFN0YWtlZDogCQCkAwEFDHRvdGFsU3Rha2VkMQIPLCB0b3RhbFNoYXJlczogCQCkAwEFC3RvdGFsU2hhcmVzAQphZHZpc2VVc2VyAQR1c2VyBAdzaGFyZXMxCQEGc2hhcmVzAQUEdXNlcgQJYXZhaWxhYmxlCQELc2hhcmVzVG9Qd3IBBQdzaGFyZXMxBAxoZWlnaHRBbmRBY2MJAKwCAgkArAICCQCsAgICCGhlaWdodDogCQCkAwEFBkhFSUdIVAILLCBhY2NvdW50OiAFBHVzZXIDCQAAAgUHc2hhcmVzMQAACQCsAgIJAKwCAgkArAICCQCsAgIFDGhlaWdodEFuZEFjYwILLCBzdGFrZWQ6IDACESwgdm90aW5nX3Bvd2VyOiAwAhIsIHN0YWtlX2hlaWdodDogLTECFCwgdW5zdGFrZV9oZWlnaHQ6IC0xCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgUMaGVpZ2h0QW5kQWNjAgosIHN0YWtlZDogCQCkAwEFCWF2YWlsYWJsZQIQLCB2b3RpbmdfcG93ZXI6IAkApAMBBQdzaGFyZXMxAhAsIHN0YWtlX2hlaWdodDogCQCkAwEJAQtzdGFrZUhlaWdodAEFBHVzZXICEiwgdW5zdGFrZV9oZWlnaHQ6IAkApAMBCQCWAwEJAMwIAgkBDXVuc3Rha2VIZWlnaHQBBQR1c2VyCQDMCAIJAQx1bmxvY2tIZWlnaHQBBQR1c2VyBQNuaWwBC3N0YWtlRm9ySW50AgdhZGRyZXNzAXADCQECIT0CCAUBcAdhc3NldElkBQpwd3JBc3NldElkCQACAQIQaW52YWxpZCBhc3NldCBpZAQKYWRkaXRpb25hbAgFAXAGYW1vdW50BAxzaGFyZXNBbW91bnQJAQtwd3JUb1NoYXJlcwEFCmFkZGl0aW9uYWwJAMwIAgkBCHdyaXRlSW50AgULc3Rha2VkU3RvcmUJAGQCBQ1jdXJyZW50U3Rha2VkBQphZGRpdGlvbmFsCQDMCAIJAQh3cml0ZUludAIFEXN0YWtlZEhlaWdodFN0b3JlBQZIRUlHSFQJAMwIAgkBCGNoYW5nZUJ5AgUQdG90YWxTaGFyZXNTdG9yZQUMc2hhcmVzQW1vdW50CQDMCAIJAQhjaGFuZ2VCeQIJAQ91c2VyU2hhcmVzU3RvcmUBBQdhZGRyZXNzBQxzaGFyZXNBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAQtzdG9yZUhlaWdodAEJAQ91c2VyU2hhcmVzU3RvcmUBBQdhZGRyZXNzBQZIRUlHSFQFA25pbAEOdW5zdGFrZUZyb21JbnQDB2FkZHJlc3MNcGF5b3V0QWRkcmVzcwlwd3JBbW91bnQEB3NoYXJlczEJAQZzaGFyZXMBBQdhZGRyZXNzAwkAAAIFB3NoYXJlczEAAAkAAgECEm5vdGhpbmcgdG8gdW5zdGFrZQQMbWF4QXZhaWxhYmxlCQELc2hhcmVzVG9Qd3IBBQdzaGFyZXMxBAZhbW91bnQDCQAAAgUJcHdyQW1vdW50AP///////////wEFDG1heEF2YWlsYWJsZQUJcHdyQW1vdW50AwkAZgIAAAUGYW1vdW50CQACAQIeY2Fubm90IHVuc3Rha2UgbmVnYXRpdmUgYW1vdW50AwkAZgIFBmFtb3VudAUMbWF4QXZhaWxhYmxlCQACAQIhY2Fubm90IHVuc3Rha2UgbW9yZSB0aGFuIHlvdSBoYXZlBAxzaGFyZXNBbW91bnQJAJcDAQkAzAgCCQELcHdyVG9TaGFyZXMBBQZhbW91bnQJAMwIAgUHc2hhcmVzMQUDbmlsAwkAAAIFDHNoYXJlc0Ftb3VudAAACQACAQIXY2Fubm90IHVuc3Rha2UgMCBzaGFyZXMJAMwIAgkBCHdyaXRlSW50AgULc3Rha2VkU3RvcmUJAGUCBQ1jdXJyZW50U3Rha2VkBQZhbW91bnQJAMwIAgkBCHdyaXRlSW50AgURc3Rha2VkSGVpZ2h0U3RvcmUFBkhFSUdIVAkAzAgCCQEIY2hhbmdlQnkCBRB0b3RhbFNoYXJlc1N0b3JlCQEBLQEFDHNoYXJlc0Ftb3VudAkAzAgCCQEIY2hhbmdlQnkCCQEPdXNlclNoYXJlc1N0b3JlAQUHYWRkcmVzcwkBAS0BBQxzaGFyZXNBbW91bnQJAMwIAgkBBnBheW91dAIFDXBheW91dEFkZHJlc3MFBmFtb3VudAUDbmlsCgFpAQVzdGFrZQAEAWEJAQdhbGxvd2VkAQIFc3Rha2UDCQAAAgUBYQUBYQkBC3N0YWtlRm9ySW50AgkApQgBCAUBaQZjYWxsZXIJAJEDAggFAWkIcGF5bWVudHMAAAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQhzdGFrZUZvcgEHYWRkcmVzcwQBYQkBB2FsbG93ZWQBAghzdGFrZUZvcgMJAAACBQFhBQFhAwMJAQIhPQIFB2FkZHJlc3MJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyCQEBIQEJAQhjb250YWlucwIFDW1haW5BZGRyZXNzZXMJAKUIAQgFAWkGY2FsbGVyBwkAAgECBmRlbmllZAkBC3N0YWtlRm9ySW50AgUHYWRkcmVzcwkAkQMCCAUBaQhwYXltZW50cwAACQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCnJlc3Rha2VGb3IBB2FkZHJlc3MEAWEJAQdhbGxvd2VkAQIKcmVzdGFrZUZvcgMJAAACBQFhBQFhAwkBASEBCQEIY29udGFpbnMCBQ1tYWluQWRkcmVzc2VzCQClCAEIBQFpBmNhbGxlcgkAAgECBmRlbmllZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBCXN0b3JlTG9jawEJAQ91c2VyU2hhcmVzU3RvcmUBBQdhZGRyZXNzBQZIRUlHSFQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQd1bnN0YWtlAQlwd3JBbW91bnQEAWEJAQdhbGxvd2VkAQIHdW5zdGFrZQMJAAACBQFhBQFhBAdhY2NvdW50CQClCAEIBQFpBmNhbGxlcgMJAGYCCQENdW5zdGFrZUhlaWdodAEFB2FjY291bnQFBkhFSUdIVAkAAgECF3N0aWxsIGxvY2tlZCBpbiBzdGFraW5nAwkAZgIJAQx1bmxvY2tIZWlnaHQBBQdhY2NvdW50BQZIRUlHSFQJAAIBAhZzdGlsbCBsb2NrZWQgaW4gdm90aW5nCQEOdW5zdGFrZUZyb21JbnQDBQdhY2NvdW50BQdhY2NvdW50BQlwd3JBbW91bnQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQELdW5zdGFrZUZyb20CB2FkZHJlc3MJcHdyQW1vdW50BAFhCQEHYWxsb3dlZAECC3Vuc3Rha2VGcm9tAwkAAAIFAWEFAWEECXBheW91dEFkcgkApQgBCAUBaQZjYWxsZXIDCQEBIQEJAQhjb250YWlucwIFDW1haW5BZGRyZXNzZXMFCXBheW91dEFkcgkAAgECBmRlbmllZAkBDnVuc3Rha2VGcm9tSW50AwUHYWRkcmVzcwUJcGF5b3V0QWRyBQlwd3JBbW91bnQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEKdXNlclNoYXJlcwEHYWRkcmVzcwkAlAoCBQNuaWwJAQZzaGFyZXMBBQdhZGRyZXNzAWkBCXVzZXJQb3dlcgEHYWRkcmVzcwkAlAoCBQNuaWwJAQZzdGFrZWQBBQdhZGRyZXNzAWkBCnRvdGFsUG93ZXIACQCUCgIFA25pbAUNY3VycmVudFN0YWtlZAFpAQt0b3RhbFNoYXJlcwAJAJQKAgUDbmlsCQELdmFsdWVPckVsc2UCCQCfCAEFEHRvdGFsU2hhcmVzU3RvcmUAAAFpAQRpbml0AQRjb25mCQDMCAIJARB3cml0ZUNvbnN0U3RyaW5nAgUSY29uZmlnQWRkcmVzc1N0b3JlBQRjb25mBQNuaWwA1homdQ==", "chainId": 84, "height": 2786640, "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+func writeConstString (key,value) = if (!(isDefined(getString(this, key))))
5+ then StringEntry(key, value)
6+ else throw(("already initialized: " + key))
7+
8+
9+func writeInt (key,value) = if ((0 > value))
10+ then throw(((("writing negative value " + toString(value)) + " for key ") + key))
11+ else IntegerEntry(key, value)
12+
13+
14+func changeBy (key,value) = writeInt(key, (valueOrElse(getInteger(this, key), 0) + value))
15+
16+
17+let configAddressStore = "config"
18+
19+let configAddress = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(this, configAddressStore), "staking: config address not found")), "invalid config address")
20+
21+func allowed (op) = invoke(configAddress, "opAllowed", [op], nil)
22+
23+
24+let pwrAssetIdStr = valueOrErrorMessage(getString(configAddress, "powerAssetId"), "pwr asset id not found")
25+
26+let pwrAssetId = fromBase58String(pwrAssetIdStr)
27+
28+let minterContract = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(configAddress, "contract_minter"), "no contract_minter")), "invalid minter contract")
29+
30+let mainAddresses = valueOrElse(getString(configAddress, "main_addresses"), "")
31+
32+let minLockTime = valueOrErrorMessage(getInteger(configAddress, (toString(this) + "_min_lock_time")), "min_lock_time not set")
33+
34+func userSharesStore (user) = (user + "_shares")
35+
36+
37+func storeHeight (store) = (store + "_height")
38+
39+
40+func storeLock (store) = (store + "_lock")
41+
42+
43+func stakeHeight (address) = valueOrErrorMessage(getInteger(this, storeHeight(userSharesStore(address))), "no stake height")
44+
45+
46+func lockHeight (address) = valueOrElse(getInteger(this, storeLock(userSharesStore(address))), 0)
47+
48+
49+func unlockHeight (address) = (lockHeight(address) + minLockTime)
50+
51+
52+func unstakeHeight (address) = (stakeHeight(address) + minLockTime)
53+
54+
55+let slashers = valueOrElse(getString(configAddress, (toString(this) + "_slashers")), "")
56+
57+let HEIGHT = height
58+
59+let stakedHeightStore = "stakedHeight"
60+
61+let totalSharesStore = "totalShares"
62+
63+let stakedStore = "staked"
64+
65+let RBase = 10000000000000000
66+
67+let apr = valueOrErrorMessage(getInteger(configAddress, (toString(this) + "_staker_apr")), "no staker_apr")
68+
69+let blocksPerYear = ((365 * 24) * 60)
70+
71+let RPerBlock = fraction(apr, RBase, (1000 * blocksPerYear))
72+
73+let totalStaked = valueOrElse(getInteger(this, stakedStore), 0)
74+
75+let currentStaked = {
76+ let stakedHeight = valueOrElse(getInteger(this, stakedHeightStore), 0)
77+ let d = (HEIGHT - stakedHeight)
78+ let r = (RBase + (d * RPerBlock))
79+ fraction(totalStaked, r, RBase)
80+ }
81+
82+func pwrToShares (pwrAmount) = {
83+ let totalShares = valueOrElse(getInteger(this, totalSharesStore), 0)
84+ if ((totalShares == 0))
85+ then pwrAmount
86+ else fraction(pwrAmount, totalShares, currentStaked)
87+ }
88+
89+
90+func sharesToPwr (sharesAmount) = {
91+ let totalShares = valueOrElse(getInteger(this, totalSharesStore), 0)
92+ if ((totalShares == 0))
93+ then sharesAmount
94+ else fraction(sharesAmount, currentStaked, totalShares)
95+ }
96+
97+
98+func ensurePwrBalance (amount) = {
99+ let pwrBalance = assetBalance(this, pwrAssetId)
100+ if ((amount > pwrBalance))
101+ then {
102+ let mint = invoke(minterContract, "mint", [(amount - pwrBalance)], nil)
103+ if ((mint == mint))
104+ then nil
105+ else throw("Strict value is not equal to itself.")
106+ }
107+ else nil
108+ }
109+
110+
111+func payout (user,amount) = {
112+ let ensure = ensurePwrBalance(amount)
113+ if ((ensure == ensure))
114+ then ScriptTransfer(addressFromStringValue(user), amount, pwrAssetId)
115+ else throw("Strict value is not equal to itself.")
116+ }
117+
118+
119+func shares (address) = valueOrElse(getInteger(this, userSharesStore(address)), 0)
120+
121+
122+func staked (address) = sharesToPwr(shares(address))
123+
124+
125+func advise () = {
126+ let totalShares = valueOrElse(getInteger(this, totalSharesStore), 0)
127+ let totalStaked1 = sharesToPwr(totalShares)
128+ ((((("height: " + toString(HEIGHT)) + ", totalStaked: ") + toString(totalStaked1)) + ", totalShares: ") + toString(totalShares))
129+ }
130+
131+
132+func adviseUser (user) = {
133+ let shares1 = shares(user)
134+ let available = sharesToPwr(shares1)
135+ let heightAndAcc = ((("height: " + toString(HEIGHT)) + ", account: ") + user)
136+ if ((shares1 == 0))
137+ then ((((heightAndAcc + ", staked: 0") + ", voting_power: 0") + ", stake_height: -1") + ", unstake_height: -1")
138+ else ((((((((heightAndAcc + ", staked: ") + toString(available)) + ", voting_power: ") + toString(shares1)) + ", stake_height: ") + toString(stakeHeight(user))) + ", unstake_height: ") + toString(max([unstakeHeight(user), unlockHeight(user)])))
139+ }
140+
141+
142+func stakeForInt (address,p) = if ((p.assetId != pwrAssetId))
143+ then throw("invalid asset id")
144+ else {
145+ let additional = p.amount
146+ let sharesAmount = pwrToShares(additional)
147+[writeInt(stakedStore, (currentStaked + additional)), writeInt(stakedHeightStore, HEIGHT), changeBy(totalSharesStore, sharesAmount), changeBy(userSharesStore(address), sharesAmount), IntegerEntry(storeHeight(userSharesStore(address)), HEIGHT)]
148+ }
149+
150+
151+func unstakeFromInt (address,payoutAddress,pwrAmount) = {
152+ let shares1 = shares(address)
153+ if ((shares1 == 0))
154+ then throw("nothing to unstake")
155+ else {
156+ let maxAvailable = sharesToPwr(shares1)
157+ let amount = if ((pwrAmount == -1))
158+ then maxAvailable
159+ else pwrAmount
160+ if ((0 > amount))
161+ then throw("cannot unstake negative amount")
162+ else if ((amount > maxAvailable))
163+ then throw("cannot unstake more than you have")
164+ else {
165+ let sharesAmount = min([pwrToShares(amount), shares1])
166+ if ((sharesAmount == 0))
167+ then throw("cannot unstake 0 shares")
168+ else [writeInt(stakedStore, (currentStaked - amount)), writeInt(stakedHeightStore, HEIGHT), changeBy(totalSharesStore, -(sharesAmount)), changeBy(userSharesStore(address), -(sharesAmount)), payout(payoutAddress, amount)]
169+ }
170+ }
171+ }
172+
173+
174+@Callable(i)
175+func stake () = {
176+ let a = allowed("stake")
177+ if ((a == a))
178+ then stakeForInt(toString(i.caller), i.payments[0])
179+ else throw("Strict value is not equal to itself.")
180+ }
181+
182+
183+
184+@Callable(i)
185+func stakeFor (address) = {
186+ let a = allowed("stakeFor")
187+ if ((a == a))
188+ then if (if ((address != toString(i.originCaller)))
189+ then !(contains(mainAddresses, toString(i.caller)))
190+ else false)
191+ then throw("denied")
192+ else stakeForInt(address, i.payments[0])
193+ else throw("Strict value is not equal to itself.")
194+ }
195+
196+
197+
198+@Callable(i)
199+func restakeFor (address) = {
200+ let a = allowed("restakeFor")
201+ if ((a == a))
202+ then if (!(contains(mainAddresses, toString(i.caller))))
203+ then throw("denied")
204+ else [IntegerEntry(storeLock(userSharesStore(address)), HEIGHT)]
205+ else throw("Strict value is not equal to itself.")
206+ }
207+
208+
209+
210+@Callable(i)
211+func unstake (pwrAmount) = {
212+ let a = allowed("unstake")
213+ if ((a == a))
214+ then {
215+ let account = toString(i.caller)
216+ if ((unstakeHeight(account) > HEIGHT))
217+ then throw("still locked in staking")
218+ else if ((unlockHeight(account) > HEIGHT))
219+ then throw("still locked in voting")
220+ else unstakeFromInt(account, account, pwrAmount)
221+ }
222+ else throw("Strict value is not equal to itself.")
223+ }
224+
225+
226+
227+@Callable(i)
228+func unstakeFrom (address,pwrAmount) = {
229+ let a = allowed("unstakeFrom")
230+ if ((a == a))
231+ then {
232+ let payoutAdr = toString(i.caller)
233+ if (!(contains(mainAddresses, payoutAdr)))
234+ then throw("denied")
235+ else unstakeFromInt(address, payoutAdr, pwrAmount)
236+ }
237+ else throw("Strict value is not equal to itself.")
238+ }
239+
240+
241+
242+@Callable(i)
243+func userShares (address) = $Tuple2(nil, shares(address))
244+
245+
246+
247+@Callable(i)
248+func userPower (address) = $Tuple2(nil, staked(address))
249+
250+
251+
252+@Callable(i)
253+func totalPower () = $Tuple2(nil, currentStaked)
254+
255+
256+
257+@Callable(i)
258+func totalShares () = $Tuple2(nil, valueOrElse(getInteger(totalSharesStore), 0))
259+
260+
261+
262+@Callable(i)
263+func init (conf) = [writeConstString(configAddressStore, conf)]
264+
265+

github/deemru/w8io/03bedc9 
41.54 ms