tx · EnPoZD1ZfUJVB8aPQ8xjQw7zyCXpVvUkrx2wPo73Nxxi

3P86ne9inVG1Cf4smrEGSdcXyBuEApPcMAc:  -0.00600000 Waves

2023.03.30 17:48 [3578402] smart account 3P86ne9inVG1Cf4smrEGSdcXyBuEApPcMAc > SELF 0.00000000 Waves

{ "type": 13, "id": "EnPoZD1ZfUJVB8aPQ8xjQw7zyCXpVvUkrx2wPo73Nxxi", "fee": 600000, "feeAssetId": null, "timestamp": 1680187756085, "version": 1, "sender": "3P86ne9inVG1Cf4smrEGSdcXyBuEApPcMAc", "senderPublicKey": "6hjWe2YQdsZKtjcACiKTUMEGGnow19LjCF763eE2Tt91", "proofs": [ "4iqibgX8MCkYbtgXi9pEMsemcqEKFwWXRVZTdyWFrYDbyFYtinBLuLBqJFFHk4rsa6MRYCQMshhJxXxx2NMSqAwt" ], "script": "base64:BgInCAISABIDCgEIEgMKAQESBAoCCAESAwoBCBIDCgEIEgASABIDCgEIJAEQd3JpdGVDb25zdFN0cmluZwIDa2V5BXZhbHVlAwkBASEBCQEJaXNEZWZpbmVkAQkAnQgCBQR0aGlzBQNrZXkJAQtTdHJpbmdFbnRyeQIFA2tleQUFdmFsdWUJAAIBCQCsAgICFWFscmVhZHkgaW5pdGlhbGl6ZWQ6IAUDa2V5AQh3cml0ZUludAIDa2V5BXZhbHVlAwkAZgIAAAUFdmFsdWUJAAIBCQCsAgIJAKwCAgkArAICAhd3cml0aW5nIG5lZ2F0aXZlIHZhbHVlIAkApAMBBQV2YWx1ZQIJIGZvciBrZXkgBQNrZXkJAQxJbnRlZ2VyRW50cnkCBQNrZXkFBXZhbHVlAQhjaGFuZ2VCeQIDa2V5BXZhbHVlCQEId3JpdGVJbnQCBQNrZXkJAGQCCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFA2tleQAABQV2YWx1ZQASY29uZmlnQWRkcmVzc1N0b3JlAgZjb25maWcADWNvbmZpZ0FkZHJlc3MJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUEdGhpcwUSY29uZmlnQWRkcmVzc1N0b3JlAhhjb25maWcgYWRkcmVzcyBub3QgZm91bmQCFmludmFsaWQgY29uZmlnIGFkZHJlc3MBB2FsbG93ZWQBAm9wCQD8BwQFDWNvbmZpZ0FkZHJlc3MCCW9wQWxsb3dlZAkAzAgCBQJvcAUDbmlsBQNuaWwADXB3ckFzc2V0SWRTdHIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ1jb25maWdBZGRyZXNzAgxwb3dlckFzc2V0SWQCFnB3ciBhc3NldCBpZCBub3QgZm91bmQACnB3ckFzc2V0SWQJANkEAQUNcHdyQXNzZXRJZFN0cgAObWludGVyQ29udHJhY3QJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUNY29uZmlnQWRkcmVzcwIPY29udHJhY3RfbWludGVyAhJubyBjb250cmFjdF9taW50ZXICF2ludmFsaWQgbWludGVyIGNvbnRyYWN0AA1tYWluQWRkcmVzc2VzCQELdmFsdWVPckVsc2UCCQCdCAIFDWNvbmZpZ0FkZHJlc3MCDm1haW5fYWRkcmVzc2VzAgAAC21pbkxvY2tUaW1lCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUNY29uZmlnQWRkcmVzcwkArAICCQClCAEFBHRoaXMCDl9taW5fbG9ja190aW1lAhVtaW5fbG9ja190aW1lIG5vdCBzZXQBD3VzZXJTaGFyZXNTdG9yZQEEdXNlcgkArAICBQR1c2VyAgdfc2hhcmVzAQtzdG9yZUhlaWdodAEFc3RvcmUJAKwCAgUFc3RvcmUCB19oZWlnaHQBC3N0YWtlSGVpZ2h0AQdhZGRyZXNzCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUEdGhpcwkBC3N0b3JlSGVpZ2h0AQkBD3VzZXJTaGFyZXNTdG9yZQEFB2FkZHJlc3MCD25vIHN0YWtlIGhlaWdodAENdW5zdGFrZUhlaWdodAEHYWRkcmVzcwkAZAIJAQtzdGFrZUhlaWdodAEFB2FkZHJlc3MFC21pbkxvY2tUaW1lAAhzbGFzaGVycwkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ1jb25maWdBZGRyZXNzCQCsAgIJAKUIAQUEdGhpcwIJX3NsYXNoZXJzAgAABkhFSUdIVAUGaGVpZ2h0ABFzdGFrZWRIZWlnaHRTdG9yZQIMc3Rha2VkSGVpZ2h0ABB0b3RhbFNoYXJlc1N0b3JlAgt0b3RhbFNoYXJlcwALc3Rha2VkU3RvcmUCBnN0YWtlZAAFUkJhc2UAgICE/qbe4REAA2FwcgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFDWNvbmZpZ0FkZHJlc3MJAKwCAgkApQgBBQR0aGlzAgtfc3Rha2VyX2FwcgINbm8gc3Rha2VyX2FwcgANYmxvY2tzUGVyWWVhcgkAaAIJAGgCAO0CABgAPAAJUlBlckJsb2NrCQBrAwUDYXByBQVSQmFzZQkAaAIA6AcFDWJsb2Nrc1BlclllYXIAC3RvdGFsU3Rha2VkCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFC3N0YWtlZFN0b3JlAAAADWN1cnJlbnRTdGFrZWQEDHN0YWtlZEhlaWdodAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBRFzdGFrZWRIZWlnaHRTdG9yZQAABAFkCQBlAgUGSEVJR0hUBQxzdGFrZWRIZWlnaHQEAXIJAGQCBQVSQmFzZQkAaAIFAWQFCVJQZXJCbG9jawkAawMFC3RvdGFsU3Rha2VkBQFyBQVSQmFzZQELcHdyVG9TaGFyZXMBCXB3ckFtb3VudAQLdG90YWxTaGFyZXMJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUQdG90YWxTaGFyZXNTdG9yZQAAAwkAAAIFC3RvdGFsU2hhcmVzAAAFCXB3ckFtb3VudAkAawMFCXB3ckFtb3VudAULdG90YWxTaGFyZXMFDWN1cnJlbnRTdGFrZWQBC3NoYXJlc1RvUHdyAQxzaGFyZXNBbW91bnQEC3RvdGFsU2hhcmVzCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFEHRvdGFsU2hhcmVzU3RvcmUAAAMJAAACBQt0b3RhbFNoYXJlcwAABQxzaGFyZXNBbW91bnQJAGsDBQxzaGFyZXNBbW91bnQFDWN1cnJlbnRTdGFrZWQFC3RvdGFsU2hhcmVzARBlbnN1cmVQd3JCYWxhbmNlAQZhbW91bnQECnB3ckJhbGFuY2UJAPAHAgUEdGhpcwUKcHdyQXNzZXRJZAMJAGYCBQZhbW91bnQFCnB3ckJhbGFuY2UEBG1pbnQJAPwHBAUObWludGVyQ29udHJhY3QCBG1pbnQJAMwIAgkAZQIFBmFtb3VudAUKcHdyQmFsYW5jZQUDbmlsBQNuaWwDCQAAAgUEbWludAUEbWludAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBQNuaWwBBnBheW91dAIEdXNlcgZhbW91bnQEBmVuc3VyZQkBEGVuc3VyZVB3ckJhbGFuY2UBBQZhbW91bnQDCQAAAgUGZW5zdXJlBQZlbnN1cmUJAQ5TY3JpcHRUcmFuc2ZlcgMJARFAZXh0ck5hdGl2ZSgxMDYyKQEFBHVzZXIFBmFtb3VudAUKcHdyQXNzZXRJZAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgEGc2hhcmVzAQdhZGRyZXNzCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQ91c2VyU2hhcmVzU3RvcmUBBQdhZGRyZXNzAAABBnN0YWtlZAEHYWRkcmVzcwkBC3NoYXJlc1RvUHdyAQkBBnNoYXJlcwEFB2FkZHJlc3MBBmFkdmlzZQAEC3RvdGFsU2hhcmVzCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFEHRvdGFsU2hhcmVzU3RvcmUAAAQMdG90YWxTdGFrZWQxCQELc2hhcmVzVG9Qd3IBBQt0b3RhbFNoYXJlcwkArAICCQCsAgIJAKwCAgIIaGVpZ2h0OiAJAKQDAQUGSEVJR0hUAg8sIHRvdGFsU3Rha2VkOiAJAKQDAQUMdG90YWxTdGFrZWQxAQphZHZpc2VVc2VyAQR1c2VyBAdzaGFyZXMxCQEGc2hhcmVzAQUEdXNlcgQJYXZhaWxhYmxlCQELc2hhcmVzVG9Qd3IBBQdzaGFyZXMxBAxoZWlnaHRBbmRBY2MJAKwCAgkArAICCQCsAgICCGhlaWdodDogCQCkAwEFBkhFSUdIVAILLCBhY2NvdW50OiAFBHVzZXIDCQAAAgUHc2hhcmVzMQAACQCsAgIJAKwCAgkArAICBQxoZWlnaHRBbmRBY2MCCywgc3Rha2VkOiAwAhIsIHN0YWtlX2hlaWdodDogLTECFCwgdW5zdGFrZV9oZWlnaHQ6IC0xCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICBQxoZWlnaHRBbmRBY2MCCiwgc3Rha2VkOiAJAKQDAQUJYXZhaWxhYmxlAhAsIHN0YWtlX2hlaWdodDogCQCkAwEJAQtzdGFrZUhlaWdodAEFBHVzZXICEiwgdW5zdGFrZV9oZWlnaHQ6IAkApAMBCQENdW5zdGFrZUhlaWdodAEFBHVzZXIBC3N0YWtlRm9ySW50AgdhZGRyZXNzAXADCQECIT0CCAUBcAdhc3NldElkBQpwd3JBc3NldElkCQACAQIQaW52YWxpZCBhc3NldCBpZAQKYWRkaXRpb25hbAgFAXAGYW1vdW50BAxzaGFyZXNBbW91bnQJAQtwd3JUb1NoYXJlcwEFCmFkZGl0aW9uYWwJAMwIAgkBCHdyaXRlSW50AgULc3Rha2VkU3RvcmUJAGQCBQ1jdXJyZW50U3Rha2VkBQphZGRpdGlvbmFsCQDMCAIJAQh3cml0ZUludAIFEXN0YWtlZEhlaWdodFN0b3JlBQZIRUlHSFQJAMwIAgkBCGNoYW5nZUJ5AgUQdG90YWxTaGFyZXNTdG9yZQUMc2hhcmVzQW1vdW50CQDMCAIJAQhjaGFuZ2VCeQIJAQ91c2VyU2hhcmVzU3RvcmUBBQdhZGRyZXNzBQxzaGFyZXNBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAQtzdG9yZUhlaWdodAEJAQ91c2VyU2hhcmVzU3RvcmUBBQdhZGRyZXNzBQZIRUlHSFQFA25pbAEOdW5zdGFrZUZyb21JbnQDB2FkZHJlc3MNcGF5b3V0QWRkcmVzcwlwd3JBbW91bnQEB3NoYXJlczEJAQZzaGFyZXMBBQdhZGRyZXNzAwkAAAIFB3NoYXJlczEAAAkAAgECEm5vdGhpbmcgdG8gdW5zdGFrZQQMbWF4QXZhaWxhYmxlCQELc2hhcmVzVG9Qd3IBBQdzaGFyZXMxBAZhbW91bnQDCQAAAgUJcHdyQW1vdW50AP///////////wEFDG1heEF2YWlsYWJsZQUJcHdyQW1vdW50AwkAZgIAAAUGYW1vdW50CQACAQIeY2Fubm90IHVuc3Rha2UgbmVnYXRpdmUgYW1vdW50AwkAZgIFBmFtb3VudAUMbWF4QXZhaWxhYmxlCQACAQIhY2Fubm90IHVuc3Rha2UgbW9yZSB0aGFuIHlvdSBoYXZlBAxzaGFyZXNBbW91bnQJAJcDAQkAzAgCCQELcHdyVG9TaGFyZXMBBQZhbW91bnQJAMwIAgUHc2hhcmVzMQUDbmlsAwkAAAIFDHNoYXJlc0Ftb3VudAAACQACAQIXY2Fubm90IHVuc3Rha2UgMCBzaGFyZXMJAMwIAgkBCHdyaXRlSW50AgULc3Rha2VkU3RvcmUJAGUCBQ1jdXJyZW50U3Rha2VkBQZhbW91bnQJAMwIAgkBCHdyaXRlSW50AgURc3Rha2VkSGVpZ2h0U3RvcmUFBkhFSUdIVAkAzAgCCQEIY2hhbmdlQnkCBRB0b3RhbFNoYXJlc1N0b3JlCQEBLQEFDHNoYXJlc0Ftb3VudAkAzAgCCQEIY2hhbmdlQnkCCQEPdXNlclNoYXJlc1N0b3JlAQUHYWRkcmVzcwkBAS0BBQxzaGFyZXNBbW91bnQJAMwIAgkBBnBheW91dAIFDXBheW91dEFkZHJlc3MFBmFtb3VudAUDbmlsCQFpAQVzdGFrZQAEAWEJAQdhbGxvd2VkAQIFc3Rha2UDCQAAAgUBYQUBYQkBC3N0YWtlRm9ySW50AgkApQgBCAUBaQZjYWxsZXIJAJEDAggFAWkIcGF5bWVudHMAAAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQhzdGFrZUZvcgEHYWRkcmVzcwQBYQkBB2FsbG93ZWQBAghzdGFrZUZvcgMJAAACBQFhBQFhAwMJAQIhPQIFB2FkZHJlc3MJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyCQEBIQEJAQhjb250YWlucwIFDW1haW5BZGRyZXNzZXMJAKUIAQgFAWkGY2FsbGVyBwkAAgECBmRlbmllZAkBC3N0YWtlRm9ySW50AgUHYWRkcmVzcwkAkQMCCAUBaQhwYXltZW50cwAACQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBB3Vuc3Rha2UBCXB3ckFtb3VudAQBYQkBB2FsbG93ZWQBAgd1bnN0YWtlAwkAAAIFAWEFAWEEB2FjY291bnQJAKUIAQgFAWkGY2FsbGVyAwkAZgIJAQ11bnN0YWtlSGVpZ2h0AQUHYWNjb3VudAUGSEVJR0hUCQACAQIMc3RpbGwgbG9ja2VkCQEOdW5zdGFrZUZyb21JbnQDBQdhY2NvdW50BQdhY2NvdW50BQlwd3JBbW91bnQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQELdW5zdGFrZUZyb20CB2FkZHJlc3MJcHdyQW1vdW50BAFhCQEHYWxsb3dlZAECC3Vuc3Rha2VGcm9tAwkAAAIFAWEFAWEECXBheW91dEFkcgkApQgBCAUBaQZjYWxsZXIDCQEBIQEJAQhjb250YWlucwIFDW1haW5BZGRyZXNzZXMFCXBheW91dEFkcgkAAgECBmRlbmllZAkBDnVuc3Rha2VGcm9tSW50AwUHYWRkcmVzcwUJcGF5b3V0QWRyBQlwd3JBbW91bnQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEKdXNlclNoYXJlcwEHYWRkcmVzcwkAlAoCBQNuaWwJAQZzaGFyZXMBBQdhZGRyZXNzAWkBCXVzZXJQb3dlcgEHYWRkcmVzcwkAlAoCBQNuaWwJAQZzdGFrZWQBBQdhZGRyZXNzAWkBCnRvdGFsUG93ZXIACQCUCgIFA25pbAUNY3VycmVudFN0YWtlZAFpAQt0b3RhbFNoYXJlcwAJAJQKAgUDbmlsCQELdmFsdWVPckVsc2UCCQCfCAEFEHRvdGFsU2hhcmVzU3RvcmUAAAFpAQRpbml0AQRjb25mCQDMCAIJARB3cml0ZUNvbnN0U3RyaW5nAgUSY29uZmlnQWRkcmVzc1N0b3JlBQRjb25mBQNuaWwAtCObQQ==", "chainId": 87, "height": 3578402, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 3UUptsikgKCj112zBsATb7bVuSv6R9vYwAs52jZwe8Q8 Next: CmDFvYjc4t2eKh83pJWUoLYRLMbZJa6rGU93pXjSrTMp Diff:
OldNewDifferences
2727
2828 let minterContract = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(configAddress, "contract_minter"), "no contract_minter")), "invalid minter contract")
2929
30-let stakingAddresses = valueOrElse(getString(configAddress, (toString(this) + "_stakers")), "")
30+let mainAddresses = valueOrElse(getString(configAddress, "main_addresses"), "")
3131
3232 let minLockTime = valueOrErrorMessage(getInteger(configAddress, (toString(this) + "_min_lock_time")), "min_lock_time not set")
3333
107107 }
108108
109109
110-func userShares (address) = valueOrElse(getInteger(this, userSharesStore(address)), 0)
110+func shares (address) = valueOrElse(getInteger(this, userSharesStore(address)), 0)
111111
112112
113-func staked (address) = sharesToPwr(userShares(address))
113+func staked (address) = sharesToPwr(shares(address))
114114
115115
116116 func advise () = {
121121
122122
123123 func adviseUser (user) = {
124- let shares = userShares(user)
125- let available = sharesToPwr(shares)
124+ let shares1 = shares(user)
125+ let available = sharesToPwr(shares1)
126126 let heightAndAcc = ((("height: " + toString(HEIGHT)) + ", account: ") + user)
127- if ((shares == 0))
127+ if ((shares1 == 0))
128128 then (((heightAndAcc + ", staked: 0") + ", stake_height: -1") + ", unstake_height: -1")
129129 else ((((((heightAndAcc + ", staked: ") + toString(available)) + ", stake_height: ") + toString(stakeHeight(user))) + ", unstake_height: ") + toString(unstakeHeight(user)))
130130 }
137137 let sharesAmount = pwrToShares(additional)
138138 [writeInt(stakedStore, (currentStaked + additional)), writeInt(stakedHeightStore, HEIGHT), changeBy(totalSharesStore, sharesAmount), changeBy(userSharesStore(address), sharesAmount), IntegerEntry(storeHeight(userSharesStore(address)), HEIGHT)]
139139 }
140+
141+
142+func unstakeFromInt (address,payoutAddress,pwrAmount) = {
143+ let shares1 = shares(address)
144+ if ((shares1 == 0))
145+ then throw("nothing to unstake")
146+ else {
147+ let maxAvailable = sharesToPwr(shares1)
148+ let amount = if ((pwrAmount == -1))
149+ then maxAvailable
150+ else pwrAmount
151+ if ((0 > amount))
152+ then throw("cannot unstake negative amount")
153+ else if ((amount > maxAvailable))
154+ then throw("cannot unstake more than you have")
155+ else {
156+ let sharesAmount = min([pwrToShares(amount), shares1])
157+ if ((sharesAmount == 0))
158+ then throw("cannot unstake 0 shares")
159+ else [writeInt(stakedStore, (currentStaked - amount)), writeInt(stakedHeightStore, HEIGHT), changeBy(totalSharesStore, -(sharesAmount)), changeBy(userSharesStore(address), -(sharesAmount)), payout(payoutAddress, amount)]
160+ }
161+ }
162+ }
140163
141164
142165 @Callable(i)
154177 let a = allowed("stakeFor")
155178 if ((a == a))
156179 then if (if ((address != toString(i.originCaller)))
157- then !(contains(stakingAddresses, toString(i.caller)))
180+ then !(contains(mainAddresses, toString(i.caller)))
158181 else false)
159182 then throw("denied")
160183 else stakeForInt(address, i.payments[0])
171194 let account = toString(i.caller)
172195 if ((unstakeHeight(account) > HEIGHT))
173196 then throw("still locked")
174- else {
175- let shares = userShares(account)
176- if ((shares == 0))
177- then throw("nothing to unstake")
178- else {
179- let maxAvailable = sharesToPwr(shares)
180- let amount = if ((pwrAmount == -1))
181- then maxAvailable
182- else pwrAmount
183- if ((0 > amount))
184- then throw("cannot unstake negative amount")
185- else if ((amount > maxAvailable))
186- then throw("cannot unstake more than you have")
187- else {
188- let sharesAmount = min([pwrToShares(amount), shares])
189- if ((sharesAmount == 0))
190- then throw("cannot unstake 0 shares")
191- else [writeInt(stakedStore, (currentStaked - amount)), writeInt(stakedHeightStore, HEIGHT), changeBy(totalSharesStore, -(sharesAmount)), changeBy(userSharesStore(account), -(sharesAmount)), payout(account, amount)]
192- }
193- }
194- }
197+ else unstakeFromInt(account, account, pwrAmount)
195198 }
196199 else throw("Strict value is not equal to itself.")
197200 }
199202
200203
201204 @Callable(i)
202-func userPower (address) = $Tuple2(nil, userShares(address))
205+func unstakeFrom (address,pwrAmount) = {
206+ let a = allowed("unstakeFrom")
207+ if ((a == a))
208+ then {
209+ let payoutAdr = toString(i.caller)
210+ if (!(contains(mainAddresses, payoutAdr)))
211+ then throw("denied")
212+ else unstakeFromInt(address, payoutAdr, pwrAmount)
213+ }
214+ else throw("Strict value is not equal to itself.")
215+ }
203216
204217
205218
206219 @Callable(i)
207-func totalPower () = $Tuple2(nil, totalStaked)
220+func userShares (address) = $Tuple2(nil, shares(address))
221+
222+
223+
224+@Callable(i)
225+func userPower (address) = $Tuple2(nil, staked(address))
226+
227+
228+
229+@Callable(i)
230+func totalPower () = $Tuple2(nil, currentStaked)
231+
232+
233+
234+@Callable(i)
235+func totalShares () = $Tuple2(nil, valueOrElse(getInteger(totalSharesStore), 0))
208236
209237
210238
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 func writeConstString (key,value) = if (!(isDefined(getString(this, key))))
55 then StringEntry(key, value)
66 else throw(("already initialized: " + key))
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 let configAddressStore = "config"
1818
1919 let configAddress = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(this, configAddressStore), "config address not found")), "invalid config address")
2020
2121 func allowed (op) = invoke(configAddress, "opAllowed", [op], nil)
2222
2323
2424 let pwrAssetIdStr = valueOrErrorMessage(getString(configAddress, "powerAssetId"), "pwr asset id not found")
2525
2626 let pwrAssetId = fromBase58String(pwrAssetIdStr)
2727
2828 let minterContract = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(configAddress, "contract_minter"), "no contract_minter")), "invalid minter contract")
2929
30-let stakingAddresses = valueOrElse(getString(configAddress, (toString(this) + "_stakers")), "")
30+let mainAddresses = valueOrElse(getString(configAddress, "main_addresses"), "")
3131
3232 let minLockTime = valueOrErrorMessage(getInteger(configAddress, (toString(this) + "_min_lock_time")), "min_lock_time not set")
3333
3434 func userSharesStore (user) = (user + "_shares")
3535
3636
3737 func storeHeight (store) = (store + "_height")
3838
3939
4040 func stakeHeight (address) = valueOrErrorMessage(getInteger(this, storeHeight(userSharesStore(address))), "no stake height")
4141
4242
4343 func unstakeHeight (address) = (stakeHeight(address) + minLockTime)
4444
4545
4646 let slashers = valueOrElse(getString(configAddress, (toString(this) + "_slashers")), "")
4747
4848 let HEIGHT = height
4949
5050 let stakedHeightStore = "stakedHeight"
5151
5252 let totalSharesStore = "totalShares"
5353
5454 let stakedStore = "staked"
5555
5656 let RBase = 10000000000000000
5757
5858 let apr = valueOrErrorMessage(getInteger(configAddress, (toString(this) + "_staker_apr")), "no staker_apr")
5959
6060 let blocksPerYear = ((365 * 24) * 60)
6161
6262 let RPerBlock = fraction(apr, RBase, (1000 * blocksPerYear))
6363
6464 let totalStaked = valueOrElse(getInteger(this, stakedStore), 0)
6565
6666 let currentStaked = {
6767 let stakedHeight = valueOrElse(getInteger(this, stakedHeightStore), 0)
6868 let d = (HEIGHT - stakedHeight)
6969 let r = (RBase + (d * RPerBlock))
7070 fraction(totalStaked, r, RBase)
7171 }
7272
7373 func pwrToShares (pwrAmount) = {
7474 let totalShares = valueOrElse(getInteger(this, totalSharesStore), 0)
7575 if ((totalShares == 0))
7676 then pwrAmount
7777 else fraction(pwrAmount, totalShares, currentStaked)
7878 }
7979
8080
8181 func sharesToPwr (sharesAmount) = {
8282 let totalShares = valueOrElse(getInteger(this, totalSharesStore), 0)
8383 if ((totalShares == 0))
8484 then sharesAmount
8585 else fraction(sharesAmount, currentStaked, totalShares)
8686 }
8787
8888
8989 func ensurePwrBalance (amount) = {
9090 let pwrBalance = assetBalance(this, pwrAssetId)
9191 if ((amount > pwrBalance))
9292 then {
9393 let mint = invoke(minterContract, "mint", [(amount - pwrBalance)], nil)
9494 if ((mint == mint))
9595 then nil
9696 else throw("Strict value is not equal to itself.")
9797 }
9898 else nil
9999 }
100100
101101
102102 func payout (user,amount) = {
103103 let ensure = ensurePwrBalance(amount)
104104 if ((ensure == ensure))
105105 then ScriptTransfer(addressFromStringValue(user), amount, pwrAssetId)
106106 else throw("Strict value is not equal to itself.")
107107 }
108108
109109
110-func userShares (address) = valueOrElse(getInteger(this, userSharesStore(address)), 0)
110+func shares (address) = valueOrElse(getInteger(this, userSharesStore(address)), 0)
111111
112112
113-func staked (address) = sharesToPwr(userShares(address))
113+func staked (address) = sharesToPwr(shares(address))
114114
115115
116116 func advise () = {
117117 let totalShares = valueOrElse(getInteger(this, totalSharesStore), 0)
118118 let totalStaked1 = sharesToPwr(totalShares)
119119 ((("height: " + toString(HEIGHT)) + ", totalStaked: ") + toString(totalStaked1))
120120 }
121121
122122
123123 func adviseUser (user) = {
124- let shares = userShares(user)
125- let available = sharesToPwr(shares)
124+ let shares1 = shares(user)
125+ let available = sharesToPwr(shares1)
126126 let heightAndAcc = ((("height: " + toString(HEIGHT)) + ", account: ") + user)
127- if ((shares == 0))
127+ if ((shares1 == 0))
128128 then (((heightAndAcc + ", staked: 0") + ", stake_height: -1") + ", unstake_height: -1")
129129 else ((((((heightAndAcc + ", staked: ") + toString(available)) + ", stake_height: ") + toString(stakeHeight(user))) + ", unstake_height: ") + toString(unstakeHeight(user)))
130130 }
131131
132132
133133 func stakeForInt (address,p) = if ((p.assetId != pwrAssetId))
134134 then throw("invalid asset id")
135135 else {
136136 let additional = p.amount
137137 let sharesAmount = pwrToShares(additional)
138138 [writeInt(stakedStore, (currentStaked + additional)), writeInt(stakedHeightStore, HEIGHT), changeBy(totalSharesStore, sharesAmount), changeBy(userSharesStore(address), sharesAmount), IntegerEntry(storeHeight(userSharesStore(address)), HEIGHT)]
139139 }
140+
141+
142+func unstakeFromInt (address,payoutAddress,pwrAmount) = {
143+ let shares1 = shares(address)
144+ if ((shares1 == 0))
145+ then throw("nothing to unstake")
146+ else {
147+ let maxAvailable = sharesToPwr(shares1)
148+ let amount = if ((pwrAmount == -1))
149+ then maxAvailable
150+ else pwrAmount
151+ if ((0 > amount))
152+ then throw("cannot unstake negative amount")
153+ else if ((amount > maxAvailable))
154+ then throw("cannot unstake more than you have")
155+ else {
156+ let sharesAmount = min([pwrToShares(amount), shares1])
157+ if ((sharesAmount == 0))
158+ then throw("cannot unstake 0 shares")
159+ else [writeInt(stakedStore, (currentStaked - amount)), writeInt(stakedHeightStore, HEIGHT), changeBy(totalSharesStore, -(sharesAmount)), changeBy(userSharesStore(address), -(sharesAmount)), payout(payoutAddress, amount)]
160+ }
161+ }
162+ }
140163
141164
142165 @Callable(i)
143166 func stake () = {
144167 let a = allowed("stake")
145168 if ((a == a))
146169 then stakeForInt(toString(i.caller), i.payments[0])
147170 else throw("Strict value is not equal to itself.")
148171 }
149172
150173
151174
152175 @Callable(i)
153176 func stakeFor (address) = {
154177 let a = allowed("stakeFor")
155178 if ((a == a))
156179 then if (if ((address != toString(i.originCaller)))
157- then !(contains(stakingAddresses, toString(i.caller)))
180+ then !(contains(mainAddresses, toString(i.caller)))
158181 else false)
159182 then throw("denied")
160183 else stakeForInt(address, i.payments[0])
161184 else throw("Strict value is not equal to itself.")
162185 }
163186
164187
165188
166189 @Callable(i)
167190 func unstake (pwrAmount) = {
168191 let a = allowed("unstake")
169192 if ((a == a))
170193 then {
171194 let account = toString(i.caller)
172195 if ((unstakeHeight(account) > HEIGHT))
173196 then throw("still locked")
174- else {
175- let shares = userShares(account)
176- if ((shares == 0))
177- then throw("nothing to unstake")
178- else {
179- let maxAvailable = sharesToPwr(shares)
180- let amount = if ((pwrAmount == -1))
181- then maxAvailable
182- else pwrAmount
183- if ((0 > amount))
184- then throw("cannot unstake negative amount")
185- else if ((amount > maxAvailable))
186- then throw("cannot unstake more than you have")
187- else {
188- let sharesAmount = min([pwrToShares(amount), shares])
189- if ((sharesAmount == 0))
190- then throw("cannot unstake 0 shares")
191- else [writeInt(stakedStore, (currentStaked - amount)), writeInt(stakedHeightStore, HEIGHT), changeBy(totalSharesStore, -(sharesAmount)), changeBy(userSharesStore(account), -(sharesAmount)), payout(account, amount)]
192- }
193- }
194- }
197+ else unstakeFromInt(account, account, pwrAmount)
195198 }
196199 else throw("Strict value is not equal to itself.")
197200 }
198201
199202
200203
201204 @Callable(i)
202-func userPower (address) = $Tuple2(nil, userShares(address))
205+func unstakeFrom (address,pwrAmount) = {
206+ let a = allowed("unstakeFrom")
207+ if ((a == a))
208+ then {
209+ let payoutAdr = toString(i.caller)
210+ if (!(contains(mainAddresses, payoutAdr)))
211+ then throw("denied")
212+ else unstakeFromInt(address, payoutAdr, pwrAmount)
213+ }
214+ else throw("Strict value is not equal to itself.")
215+ }
203216
204217
205218
206219 @Callable(i)
207-func totalPower () = $Tuple2(nil, totalStaked)
220+func userShares (address) = $Tuple2(nil, shares(address))
221+
222+
223+
224+@Callable(i)
225+func userPower (address) = $Tuple2(nil, staked(address))
226+
227+
228+
229+@Callable(i)
230+func totalPower () = $Tuple2(nil, currentStaked)
231+
232+
233+
234+@Callable(i)
235+func totalShares () = $Tuple2(nil, valueOrElse(getInteger(totalSharesStore), 0))
208236
209237
210238
211239 @Callable(i)
212240 func init (conf) = [writeConstString(configAddressStore, conf)]
213241
214242

github/deemru/w8io/6500d08 
58.40 ms