tx · 5rLA6NLHwVoD8RAXZzAhbsLQ68pPq6hxGZzYBmmcDUDH

3PAi1ePLQrYrY3jj9omBtT6isMkZsapbmks:  -0.01400000 Waves

2022.04.05 13:57 [3060454] smart account 3PAi1ePLQrYrY3jj9omBtT6isMkZsapbmks > SELF 0.00000000 Waves

{ "type": 13, "id": "5rLA6NLHwVoD8RAXZzAhbsLQ68pPq6hxGZzYBmmcDUDH", "fee": 1400000, "feeAssetId": null, "timestamp": 1649156233553, "version": 2, "chainId": 87, "sender": "3PAi1ePLQrYrY3jj9omBtT6isMkZsapbmks", "senderPublicKey": "XrNmTusDFaLSz3wAjmdfcyC5h6uYyVbpdh18758UpFv", "proofs": [ "4i7UwqGt1UZ781jqgeUCZyzU7fBE7TNdJyfYfNqPLPwyBrSy4tNBquCR6oX98ppnqBQPahUGkz4iW78MExGxng2w" ], "script": "base64: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ZXIAAAACAAAAB2FkZHJlc3MAAAAHYXNzZXRJZAkBAAAADXRyeUdldEludGVnZXIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAACGFkZHJlc3NfBQAAAAdhZGRyZXNzAgAAAAdfYXNzZXRfBQAAAAdhc3NldElkAgAAAA1fZmFybWluZ1Bvd2VyAQAAAA5nZXRBc3NldHNCeUdlbgAAAAEAAAADZ2VuBAAAAAFzCQEAAAAMdHJ5R2V0U3RyaW5nAAAAAQkAASwAAAACAgAAAAdhc3NldHNfBQAAAANnZW4DCQAAAAAAAAIFAAAAAXMCAAAAAAUAAAADbmlsCQAEtQAAAAIFAAAAAXMCAAAAASwBAAAADGNhbGNJbnRlcmVzdAAAAAMAAAAQcHJldmlvdXNJbnRlcmVzdAAAABZwcmV2aW91c0ludGVyZXN0SGVpZ2h0AAAAEXRvdGFsRmFybWluZ1Bvd2VyCQAAZAAAAAIFAAAAEHByZXZpb3VzSW50ZXJlc3QJAABpAAAAAgkAAGgAAAACCQAAaAAAAAIFAAAABXNjYWxlCQEAAAARZ2V0UmV3YXJkUGVyQmxvY2sAAAAACQAAZQAAAAIFAAAABmhlaWdodAUAAAAWcHJldmlvdXNJbnRlcmVzdEhlaWdodAUAAAARdG90YWxGYXJtaW5nUG93ZXIBAAAAEmdldEN1cnJlbnRJbnRlcmVzdAAAAAADCQAAZgAAAAIJAQAAAA10cnlHZXRJbnRlZ2VyAAAAAQIAAAASdG90YWxfZmFybWluZ1Bvd2VyAAAAAAAAAAAABAAAABBwcmV2aW91c0ludGVyZXN0CQEAAAANdHJ5R2V0SW50ZWdlcgAAAAECAAAAF3RvdGFsX2xhc3RDaGVja0ludGVyZXN0BAAAABZwcmV2aW91c0ludGVyZXN0SGVpZ2h0CQEAAAANdHJ5R2V0SW50ZWdlcgAAAAECAAAAHXRvdGFsX2xhc3RDaGVja0ludGVyZXN0SGVpZ2h0BAAAABF0b3RhbEZhcm1pbmdQb3dlcgkBAAAADXRyeUdldEludGVnZXIAAAABAgAAABJ0b3RhbF9mYXJtaW5nUG93ZXIJAQAAAAxjYWxjSW50ZXJlc3QAAAADBQAAABBwcmV2aW91c0ludGVyZXN0BQAAABZwcmV2aW91c0ludGVyZXN0SGVpZ2h0BQAAABF0b3RhbEZhcm1pbmdQb3dlcgMJAQAAAAIhPQAAAAIJAQAAAA10cnlHZXRJbnRlZ2VyAAAAAQIAAAARdG90YWxfc3RhcnRIZWlnaHQAAAAAAAAAAAAJAQAAAA10cnlHZXRJbnRlZ2VyAAAAAQIAAAAXdG90YWxfbGFzdENoZWNrSW50ZXJlc3QJAAACAAAAAQIAAAAcZmFybWluZyBpcyBub3QgbGF1bmNoZWQsIHlldAEAAAAUY2FsY0Fzc2V0UmV3YXJkRGVsdGEAAAADAAAAB2FkZHJlc3MAAAAHYXNzZXRJZAAAABFhc3NldEZhcm1pbmdQb3dlcgQAAAAWbGFzdENoZWNrQXNzZXRJbnRlcmVzdAkBAAAADXRyeUdldEludGVnZXIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAACGFkZHJlc3NfBQAAAAdhZGRyZXNzAgAAAAdfYXNzZXRfBQAAAAdhc3NldElkAgAAABJfbGFzdENoZWNrSW50ZXJlc3QEAAAAD2N1cnJlbnRJbnRlcmVzdAkBAAAAEmdldEN1cnJlbnRJbnRlcmVzdAAAAAAJAABoAAAAAgUAAAARYXNzZXRGYXJtaW5nUG93ZXIJAABlAAAAAgUAAAAPY3VycmVudEludGVyZXN0BQAAABZsYXN0Q2hlY2tBc3NldEludGVyZXN0AQAAABRhZGRBc3NldElkVG9HZW5FbnRyeQAAAAIAAAAHYXNzZXRJZAAAAAhhc3NldEdlbgQAAAAMY3VycmVudFZhbHVlCQEAAAAMdHJ5R2V0U3RyaW5nAAAAAQkAASwAAAACCQABLAAAAAICAAAAB2Fzc2V0c18FAAAACGFzc2V0R2VuAgAAAAdfbG9ja2VkAwkAAAAAAAACBQAAAAxjdXJyZW50VmFsdWUCAAAAAAUAAAAHYXNzZXRJZAkAASwAAAACCQABLAAAAAIFAAAADGN1cnJlbnRWYWx1ZQIAAAABLAUAAAAHYXNzZXRJZAEAAAAOZ2V0U3Rha2VSZXN1bHQAAAADAAAAB2FkZHJlc3MAAAAHYXNzZXRJZAAAABFhc3NldEZhcm1pbmdQb3dlcgQAAAAFYXNzZXQJAAJYAAAAAQUAAAAHYXNzZXRJZAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgIAAAASdG90YWxfZmFybWluZ1Bvd2VyCQAAZAAAAAIJAQAAAA10cnlHZXRJbnRlZ2VyAAAAAQIAAAASdG90YWxfZmFybWluZ1Bvd2VyBQAAABFhc3NldEZhcm1pbmdQb3dlcgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgIAAAAXdG90YWxfbGFzdENoZWNrSW50ZXJlc3QJAQAAABJnZXRDdXJyZW50SW50ZXJlc3QAAAAACQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACAgAAAB10b3RhbF9sYXN0Q2hlY2tJbnRlcmVzdEhlaWdodAUAAAAGaGVpZ2h0CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAACGFkZHJlc3NfBQAAAAdhZGRyZXNzAgAAAAdfYXNzZXRfBQAAAAVhc3NldAIAAAANX2Zhcm1pbmdQb3dlcgUAAAARYXNzZXRGYXJtaW5nUG93ZXIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAIYWRkcmVzc18FAAAAB2FkZHJlc3MCAAAAB19hc3NldF8FAAAABWFzc2V0AgAAABJfbGFzdENoZWNrSW50ZXJlc3QJAQAAABJnZXRDdXJyZW50SW50ZXJlc3QAAAAABQAAAANuaWwBAAAAEGdldFVuc3Rha2VSZXN1bHQAAAAFAAAAB2FkZHJlc3MAAAAHYXNzZXRJZAAAAAtyZXdhcmREZWx0YQAAAA93aXRoZHJhd25BbW91bnQAAAARYXNzZXRGYXJtaW5nUG93ZXIEAAAABWFzc2V0CQACWAAAAAEFAAAAB2Fzc2V0SWQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAICAAAAEnRvdGFsX2Zhcm1pbmdQb3dlcgkAAGUAAAACCQEAAAANdHJ5R2V0SW50ZWdlcgAAAAECAAAAEnRvdGFsX2Zhcm1pbmdQb3dlcgUAAAARYXNzZXRGYXJtaW5nUG93ZXIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAICAAAAF3RvdGFsX2xh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ZGRyZXNzBQAAAAVhc3NldAQAAAAQYXNzZXRSZXdhcmREZWx0YQkBAAAAFGNhbGNBc3NldFJld2FyZERlbHRhAAAAAwUAAAAHYWRkcmVzcwUAAAAFYXNzZXQFAAAAEWFzc2V0RmFybWluZ1Bvd2VyBAAAAAxmYXJtZWRBbW91bnQJAABkAAAAAgUAAAAQYXNzZXRSZXdhcmREZWx0YQkBAAAADXRyeUdldEludGVnZXIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAACGFkZHJlc3NfBQAAAAdhZGRyZXNzAgAAAAdfYXNzZXRfBQAAAAVhc3NldAIAAAAWX2xhc3RDaGVja0Zhcm1lZEFtb3VudAQAAAAPd2l0aGRyYXduQW1vdW50CQEAAAANdHJ5R2V0SW50ZWdlcgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAIYWRkcmVzc18FAAAAB2FkZHJlc3MCAAAAB19hc3NldF8FAAAABWFzc2V0AgAAABBfd2l0aGRyYXduQW1vdW50BAAAAAZyZXdhcmQJAABpAAAAAgkAAGUAAAACBQAAAAxmYXJtZWRBbW91bnQFAAAAD3dpdGhkcmF3bkFtb3VudAkAAGgAAAACBQAAAAVzY2FsZQAAAAAAAAAAZAQAAAAFY29sb3IJAQAAAAl0YWtlUmlnaHQAAAACCAkBAAAABXZhbHVlAAAAAQkAA+wAAAABBQAAAAdhc3NldElkAAAABG5hbWUAAAAAAAAAAAEDCQAAZwAAAAIAAAAAAAAAAAAFAAAAEWFzc2V0RmFybWluZ1Bvd2VyCQAAAgAAAAECAAAAE2Fzc2V0IG5vdCBhdmFpbGFibGUDCQAAAAAAAAIFAAAABWNvbG9yAgAAAAFVCQAAAgAAAAECAAAAK3VzZSBhbm90aGVyIGZ1bmN0aW9uIHRvIHVuc3Rha2UgSmFja3BvdCBORlQEAAAABnJlc3VsdAkBAAAAEGdldFVuc3Rha2VSZXN1bHQAAAAFBQAAAAdhZGRyZXNzBQAAAAdhc3NldElkBQAAABBhc3NldFJld2FyZERlbHRhBQAAAAZyZXdhcmQFAAAAEWFzc2V0RmFybWluZ1Bvd2VyCQAFFAAAAAIJAAROAAAAAgUAAAAGcmVzdWx0CQAE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YXNzZXQDCQEAAAARaXNVc2VyQmxhY2tsaXN0ZWQAAAABCQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgkAAAIAAAABAgAAANNPb29wcywgbG9va3MgbGlrZSB5b3UgbG9zdCBpbiBvbmUgb2YgdGhlIER1Y2tzcXVpZCBnYW1lcyEgQXMgeW91IGFscmVhZHkga25vdywgYW55IGxvc3MgaGFzIGl0cyBjb25zZXF1ZW5jZXMsIHNvIHlvdSB3aWxsIGJlIG5vdCBhYmxlIHRvIGNsYWltIHlvdXIgZmFybWluZyByZXdhcmRzIHRpbGwgdGhlIGVuZCBvZiBEdWNrU3F1aWQgZ2FtZS4gUXVhY2sgaW4gcGVhY2UhAwkAAGYAAAACCQEAAAAIaXNMb2NrZWQAAAAAAAAAAAAAAAAACQAAAgAAAAECAAAAJUVHRyBvcGVyYXRpb25zIGFyZSB0ZW1wb3JhcmlseSBsb2NrZWQEAAAAB2Fzc2V0SWQJAAJZAAAAAQUAAAAFYXNzZXQEAAAAB2FkZHJlc3MJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyBAAAAAVjb2xvcgkBAAAADHRyeUdldFN0cmluZwAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAIYWRkcmVzc18FAAAAB2FkZHJlc3MCAAAAB19hc3NldF8FAAAABWFzc2V0AgAAAAtfcGVyY2hDb2xvcgQAAAARYXNzZXRGYXJtaW5nUG93ZXIJAQAAAB1nZXRMYXN0S25vd25Bc3NldEZhcm1pbmdQb3dlcgAAAAIFAAAAB2FkZHJlc3MFAAAABWFzc2V0BAAAABBhc3NldFJld2FyZERlbHRhCQEAAAAUY2FsY0Fzc2V0UmV3YXJkRGVsdGEAAAADBQAAAAdhZGRyZXNzBQAAAAVhc3NldAUAAAARYXNzZXRGYXJtaW5nUG93ZXIEAAAADGZhcm1lZEFtb3VudAkAAGQAAAACBQAAABBhc3NldFJld2FyZERlbHRhCQEAAAANdHJ5R2V0SW50ZWdlcgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAIYWRkcmVzc18FAAAAB2FkZHJlc3MCAAAAB19hc3NldF8FAAAABWFzc2V0AgAAABZfbGFzdENo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", "height": 3060454, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: HWVRBXmVzjmCTYkptvNcpRMf8ig6Pydir5Fe6Fgi5z9x Next: 9C71e3yn4YfrUEd2rSiq4v1SoZv7wLftWAv47c8cHwrN Diff:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-func keyArtefactOwner (artefactName,owner) = (((artefactName + "_") + owner) + "_owner")
4+let perchPrice = (100 * 1000000)
55
6+let scale = 10000
67
7-func keyUnstakeHeight (artefactName,artefactId) = (((artefactName + "_") + artefactId) + "_unstake_height")
8-
9-
10-func getProcessFinishHeightKey (address,txId) = (((address + "_") + toBase58String(txId)) + "_fh")
11-
12-
13-let devAddress = base58'3P44yqcpfhPF2iC1nptm2ZJCTaN7VYhz9og'
14-
15-let eggsNeeded = (3 * 100000000)
16-
17-let artefactsLimit = (301 + 600)
18-
19-let freeGenes = ["A", "B", "C", "D", "E"]
20-
21-let oldArtefacts = ["ART-LAKE", "ART-HOUSE", "ART-BIGHOUSE", "ART-FIXGENE", "ART-FREEGENE", "ART-MIRROR", "ART-POMP", "ART-CAPE", "ART-HAT", "ART-CUSTOMDUCK"]
22-
23-let artefacts = ["ART-XMISTL", "ART-XHAT", "ART-XSCARF", "ART-XSWEATER", "ART-XSOCK", "ART-XTREE"]
24-
25-let stakeableWithLock = ["ART-LAKE", "ART-XTREE"]
26-
27-let stakeableWithoutLock = ["ART-XMISTL"]
28-
29-let allStakeable = (stakeableWithoutLock ++ stakeableWithLock)
30-
31-let allArtefact = (artefacts ++ oldArtefacts)
32-
33-func tryGetString (key) = match getString(this, key) {
34- case a: String =>
35- a
36- case _ =>
37- ""
38-}
39-
40-
41-func tryGetInteger (key) = match getInteger(this, key) {
42- case a: Int =>
43- a
44- case _ =>
45- 0
46-}
47-
48-
49-func getRandomNumber (variants,txId,finishHeight,offset) = {
50- let randomSeedBlock = value(blockInfoByHeight((finishHeight - 1)))
51- let randomHash = sha256(((base58'items' + txId) + value(randomSeedBlock.vrf)))
52- (toInt(randomHash, offset) % variants)
53- }
54-
55-
56-func getRandomArtefact (boxId,h) = {
57- let randomNumber = getRandomNumber(6, boxId, h, 1)
58-artefacts[randomNumber]
59- }
60-
61-
62-func getRandomGenes (txId,h) = {
63- let randomNumber = getRandomNumber(6, txId, h, 2)
64-freeGenes[randomNumber]
65- }
66-
67-
68-func checkArtefactDetails (assetId) = {
69- let asset = value(assetInfo(assetId))
70- let assetName = value(asset.name)
71- if (if (containsElement(allArtefact, assetName))
72- then (asset.issuer == this)
73- else false)
74- then assetName
75- else throw("Invalid artefact")
76- }
77-
8+let scale2 = 1000000
789
7910 func tryGetStringExternal (address,key) = match getString(address, key) {
8011 case a: String =>
8415 }
8516
8617
18+func tryGetString (key) = tryGetStringExternal(this, key)
19+
20+
8721 func getOracle () = Address(fromBase58String(tryGetString("static_oracleAddress")))
22+
23+
24+func getEggAssetId () = fromBase58String(tryGetStringExternal(getOracle(), "static_eggAssetId"))
25+
26+
27+func getIncubatorAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), "static_incubatorAddress")))
28+
29+
30+func getRebirthAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), "static_rebirthAddress")))
31+
32+
33+func getSwopPromoAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), "static_swopPromoAddress")))
8834
8935
9036 func getBreederAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), "static_breederAddress")))
9137
9238
93-func getEggAssetId () = fromBase58String(tryGetStringExternal(getOracle(), "static_eggAssetId"))
39+func getRefContractAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), "static_refContractAddress")))
40+
41+
42+func getItemsAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), "static_itemsAddress")))
43+
44+
45+let RefererReward = 5
46+
47+func getRewardPerBlock () = 684
48+
49+
50+func isLocked () = {
51+ let masterAddress = Address(base58'3PEPftf2kWZDmAaWBjs6BUJa9957kiA2PkU')
52+ match getInteger(masterAddress, "egglock") {
53+ case b: Int =>
54+ b
55+ case _ =>
56+ 0
57+ }
58+ }
59+
60+
61+func tryGetInteger (key) = match getInteger(this, key) {
62+ case b: Int =>
63+ b
64+ case _ =>
65+ 0
66+}
67+
68+
69+func isUserBlacklisted (address) = false
70+
71+
72+func getAssetOrigin (generation) = if ((generation == "G"))
73+ then getIncubatorAddress()
74+ else getBreederAddress()
75+
76+
77+func getAssetRarity (genotype,generation) = {
78+ let quantity = valueOrErrorMessage(getInteger(getAssetOrigin(generation), (("stats_" + genotype) + "_quantity")), (("stats_" + genotype) + "_quantity not found"))
79+ let power = pow((10000 / quantity), 4, 5, 1, 2, FLOOR)
80+ if ((power > 0))
81+ then power
82+ else 2
83+ }
9484
9585
9686 func asString (value) = match value {
10999 }
110100
111101
112-func manipulateName (assetName,position,char) = ((take(assetName, (position - 1)) + char) + takeRight(assetName, (16 - position)))
102+func getAssetFarmingPower (assetId,address) = if (if ((value(assetInfo(assetId)).issuer == getBreederAddress()))
103+ then true
104+ else (value(assetInfo(assetId)).issuer == getIncubatorAddress()))
105+ then {
106+ let assetName = value(assetInfo(assetId)).name
107+ let generation = take(takeRight(assetName, 2), 1)
108+ let farmGen = asString(invoke(getBreederAddress(), "getGenFromName", [assetName], nil))
109+ if ((farmGen == farmGen))
110+ then {
111+ let farmBoost = asInt(invoke(getItemsAddress(), "calculateFarmingPowerBoost", [toBase58String(assetId), address], nil))
112+ if ((farmBoost == farmBoost))
113+ then {
114+ let rarity = getAssetRarity(farmGen, generation)
115+ let totalFarmingPower = (rarity + fraction(rarity, farmBoost, 100))
116+ $Tuple2(farmGen, totalFarmingPower)
117+ }
118+ else throw("Strict value is not equal to itself.")
119+ }
120+ else throw("Strict value is not equal to itself.")
121+ }
122+ else throw("not valid NFT")
113123
114124
115-func itemIsInCoolDown (artefactName,artefactId) = {
116- let unstakeHeightLast = tryGetInteger(keyUnstakeHeight(artefactName, artefactId))
117- let cooldownPeriod = 240
118- if ((height > (unstakeHeightLast + cooldownPeriod)))
119- then false
120- else true
125+func getLastKnownAssetFarmingPower (address,assetId) = tryGetInteger((((("address_" + address) + "_asset_") + assetId) + "_farmingPower"))
126+
127+
128+func getAssetsByGen (gen) = {
129+ let s = tryGetString(("assets_" + gen))
130+ if ((s == ""))
131+ then nil
132+ else split(s, ",")
133+ }
134+
135+
136+func calcInterest (previousInterest,previousInterestHeight,totalFarmingPower) = (previousInterest + (((scale * getRewardPerBlock()) * (height - previousInterestHeight)) / totalFarmingPower))
137+
138+
139+func getCurrentInterest () = if ((tryGetInteger("total_farmingPower") > 0))
140+ then {
141+ let previousInterest = tryGetInteger("total_lastCheckInterest")
142+ let previousInterestHeight = tryGetInteger("total_lastCheckInterestHeight")
143+ let totalFarmingPower = tryGetInteger("total_farmingPower")
144+ calcInterest(previousInterest, previousInterestHeight, totalFarmingPower)
145+ }
146+ else if ((tryGetInteger("total_startHeight") != 0))
147+ then tryGetInteger("total_lastCheckInterest")
148+ else throw("farming is not launched, yet")
149+
150+
151+func calcAssetRewardDelta (address,assetId,assetFarmingPower) = {
152+ let lastCheckAssetInterest = tryGetInteger((((("address_" + address) + "_asset_") + assetId) + "_lastCheckInterest"))
153+ let currentInterest = getCurrentInterest()
154+ (assetFarmingPower * (currentInterest - lastCheckAssetInterest))
155+ }
156+
157+
158+func addAssetIdToGenEntry (assetId,assetGen) = {
159+ let currentValue = tryGetString((("assets_" + assetGen) + "_locked"))
160+ if ((currentValue == ""))
161+ then assetId
162+ else ((currentValue + ",") + assetId)
163+ }
164+
165+
166+func getStakeResult (address,assetId,assetFarmingPower) = {
167+ let asset = toBase58String(assetId)
168+[IntegerEntry("total_farmingPower", (tryGetInteger("total_farmingPower") + assetFarmingPower)), IntegerEntry("total_lastCheckInterest", getCurrentInterest()), IntegerEntry("total_lastCheckInterestHeight", height), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_farmingPower"), assetFarmingPower), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_lastCheckInterest"), getCurrentInterest())]
169+ }
170+
171+
172+func getUnstakeResult (address,assetId,rewardDelta,withdrawnAmount,assetFarmingPower) = {
173+ let asset = toBase58String(assetId)
174+[IntegerEntry("total_farmingPower", (tryGetInteger("total_farmingPower") - assetFarmingPower)), IntegerEntry("total_lastCheckInterest", getCurrentInterest()), IntegerEntry("total_lastCheckInterestHeight", height), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_farmingPower"), 0), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_lastCheckInterest"), getCurrentInterest()), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"), (tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount")) + (withdrawnAmount * scale2))), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount"), (tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount")) + rewardDelta))]
175+ }
176+
177+
178+func calculatePerchPrice (address) = {
179+ let hasArtefactStaked = tryGetStringExternal(getItemsAddress(), (("ART-XMISTL_" + address) + "_owner"))
180+ if ((hasArtefactStaked == ""))
181+ then perchPrice
182+ else ((perchPrice / 10) * 9)
121183 }
122184
123185
129191
130192
131193 @Callable(i)
132-func calculateFarmingPowerBoost (duckId,address) = {
133- let lakeBoost = if ((tryGetString(keyArtefactOwner("ART-LAKE", address)) != ""))
134- then 2
135- else 0
136- let xmasTreeBoost = if ((tryGetString(keyArtefactOwner("ART-XTREE", address)) != ""))
137- then 3
138- else 0
139- let totalBoost = (lakeBoost + xmasTreeBoost)
140- $Tuple2(nil, totalBoost)
141- }
194+func init () = if ((i.caller != this))
195+ then throw("admin only")
196+ else [IntegerEntry("total_startHeight", height)]
142197
143198
144199
145200 @Callable(i)
146-func fixedGene (txIdStr,parentFixedGene,positionFixedGene) = {
147- let firstPayment = value(i.payments[0])
148- let firstAssetId = toBase58String(value(firstPayment.assetId))
149- if ((firstPayment.amount != 1))
150- then throw("NFT is not attached")
201+func buyPerch (color,refererAddress) = if ((isLocked() > 0))
202+ then throw("EGG operations are temporarily locked")
203+ else if ((0 > value(indexOf(["B", "R", "G", "Y"], color))))
204+ then throw("you need to set color properly")
151205 else {
152- let artefact = checkArtefactDetails(value(firstPayment.assetId))
153- if ((artefact != "ART-FIXGENE"))
154- then throw("You need to attach a ART-FIXGENE artefact")
155- else {
156- let txId = fromBase58String(txIdStr)
157- let finishHeightKey = getProcessFinishHeightKey(toString(i.caller), txId)
158- let processFinishHeight = getIntegerValue(getBreederAddress(), finishHeightKey)
159- let duckGenesString = asString(invoke(getBreederAddress(), "generateDuck", [txIdStr, processFinishHeight, parentFixedGene, positionFixedGene, "", 0], nil))
160- if ((duckGenesString == duckGenesString))
161- then {
162- let call = invoke(getBreederAddress(), "finishDuckHatchingItems", [txIdStr, duckGenesString], nil)
163- if ((call == call))
164- then [Burn(value(firstPayment.assetId), 1)]
165- else throw("Strict value is not equal to itself.")
166- }
167- else throw("Strict value is not equal to itself.")
168- }
206+ let firstPayment = value(i.payments[0])
207+ let exactPrice = calculatePerchPrice(toString(i.caller))
208+ if ((firstPayment.assetId != getEggAssetId()))
209+ then throw(("You can attach only EGG tokens with the following asset id: " + toBase58String(getEggAssetId())))
210+ else if ((firstPayment.amount != exactPrice))
211+ then throw(("To buy a perch you currently need the following amount of EGGlets: " + toString(exactPrice)))
212+ else {
213+ let refererRewardForPerch = fraction(firstPayment.amount, RefererReward, 100)
214+ let refCall = invoke(getRefContractAddress(), "refPayment", [refererAddress], [AttachedPayment(getEggAssetId(), refererRewardForPerch)])
215+ if ((refCall == refCall))
216+ then {
217+ let perchAmountKey = ((("address_" + toString(i.caller)) + "_perchesAvailable_") + color)
218+ let perchAmount = tryGetInteger(perchAmountKey)
219+[IntegerEntry(perchAmountKey, (perchAmount + 1))]
220+ }
221+ else throw("Strict value is not equal to itself.")
222+ }
169223 }
170- }
171224
172225
173226
174227 @Callable(i)
175-func freeGene (txIdStr) = {
176- let firstPayment = value(i.payments[0])
177- let firstAssetId = toBase58String(value(firstPayment.assetId))
178- if ((firstPayment.amount != 1))
179- then throw("NFT is not attached")
228+func addFreePerch (address,color) = if ((0 > value(indexOf(["B", "R", "G", "Y"], color))))
229+ then throw("you need to set color properly")
230+ else if (if (if ((i.caller != getRebirthAddress()))
231+ then (i.caller != this)
232+ else false)
233+ then (i.caller != getSwopPromoAddress())
234+ else false)
235+ then throw("rebirth and swop promo only")
180236 else {
181- let artefact = checkArtefactDetails(value(firstPayment.assetId))
182- if ((artefact != "ART-FREEGENE"))
183- then throw("You need to attach a ART-FREEGENE artefact")
184- else {
185- let txId = fromBase58String(txIdStr)
186- let finishHeightKey = getProcessFinishHeightKey(toString(i.caller), txId)
187- let processFinishHeight = getIntegerValue(getBreederAddress(), finishHeightKey)
188- let selectedGene = getRandomGenes(txId, processFinishHeight)
189- let randomPosition = getRandomNumber(7, txId, processFinishHeight, 3)
190- let duckGenesString = asString(invoke(getBreederAddress(), "generateDuck", [txIdStr, processFinishHeight, 0, 0, selectedGene, randomPosition], nil))
191- if ((duckGenesString == duckGenesString))
192- then {
193- let call = invoke(getBreederAddress(), "finishDuckHatchingItems", [txIdStr, duckGenesString], nil)
194- if ((call == call))
195- then [Burn(value(firstPayment.assetId), 1)]
196- else throw("Strict value is not equal to itself.")
197- }
198- else throw("Strict value is not equal to itself.")
199- }
237+ let perchAmountKey = ((("address_" + address) + "_perchesAvailable_") + color)
238+ let perchAmount = tryGetInteger(perchAmountKey)
239+ $Tuple2([IntegerEntry(perchAmountKey, (perchAmount + 1))], "")
200240 }
201- }
202241
203242
204243
205244 @Callable(i)
206-func copyDuck () = {
207- let firstPayment = value(i.payments[0])
208- let secondPayment = value(i.payments[1])
209- let firstAssetId = toBase58String(value(firstPayment.assetId))
210- let children = asInt(invoke(getBreederAddress(), "validateAndGetChildren", [firstAssetId], nil))
211- if ((children == children))
212- then if (if ((firstPayment.amount != 1))
213- then true
214- else (secondPayment.amount != 1))
245+func stakeNFT () = if ((isLocked() > 0))
246+ then throw("EGG operations are temporarily locked")
247+ else {
248+ let pmt = value(i.payments[0])
249+ let assetId = value(value(i.payments[0]).assetId)
250+ let address = toString(i.caller)
251+ let color = takeRight(value(assetInfo(assetId)).name, 1)
252+ let availablePerches = tryGetInteger(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color))
253+ if ((pmt.amount != 1))
215254 then throw("NFT is not attached")
216- else {
217- let artefact = checkArtefactDetails(value(secondPayment.assetId))
218- if ((artefact != "ART-MIRROR"))
219- then throw("You need to attach a ART-MIRROR artefact")
220- else {
221- let nftInfo = value(assetInfo(value(firstPayment.assetId)))
222- let asset1Gen = split(nftInfo.name, "")
223- if (if ((asset1Gen[14] == "G"))
224- then true
225- else (asset1Gen[14] == "J"))
226- then throw("You can't mirror this duck")
227- else {
228- let duckGen = nftInfo.name
229- let call = invoke(getBreederAddress(), "createDuckSpecialGenes", [i.caller.bytes, duckGen, children], nil)
230- if ((call == call))
231- then [ScriptTransfer(i.caller, 1, firstPayment.assetId), Burn(value(secondPayment.assetId), 1)]
232- else throw("Strict value is not equal to itself.")
233- }
234- }
235- }
236- else throw("Strict value is not equal to itself.")
237- }
255+ else if ((0 >= availablePerches))
256+ then throw(("no perches available for the color " + color))
257+ else {
258+ let $t096749747 = getAssetFarmingPower(assetId, address)
259+ let assetGen = $t096749747._1
260+ let assetFarmingPower = $t096749747._2
261+ let assetRewardDelta = calcAssetRewardDelta(address, toBase58String(assetId), assetFarmingPower)
262+ (getStakeResult(address, assetId, assetFarmingPower) ++ [IntegerEntry(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color), (availablePerches - 1))])
263+ }
264+ }
238265
239266
240267
241268 @Callable(i)
242-func addArteFactToDuck () = {
243- let firstPayment = value(i.payments[0])
244- let secondPayment = value(i.payments[1])
245- let firstAssetId = toBase58String(value(firstPayment.assetId))
246- if (if ((firstPayment.amount != 1))
247- then true
248- else (secondPayment.amount != 1))
249- then throw("NFT is not attached")
269+func unstakeNFT (asset) = if (isUserBlacklisted(toString(i.caller)))
270+ then throw("Ooops, looks like you lost in one of the Ducksquid games! As you already know, any loss has its consequences, so you will be not able to claim your farming rewards till the end of DuckSquid game. Quack in peace!")
271+ else if ((isLocked() > 0))
272+ then throw("EGG operations are temporarily locked")
250273 else {
251- let children = asInt(invoke(getBreederAddress(), "validateAndGetChildren", [firstAssetId], nil))
252- if ((children == children))
253- then if ((children == 0))
254- then throw("You can only pick a sterile NFT-duck")
274+ let assetId = fromBase58String(asset)
275+ let address = toString(i.caller)
276+ let assetFarmingPower = getLastKnownAssetFarmingPower(address, asset)
277+ let assetRewardDelta = calcAssetRewardDelta(address, asset, assetFarmingPower)
278+ let farmedAmount = (assetRewardDelta + tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount")))
279+ let withdrawnAmount = tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"))
280+ let reward = ((farmedAmount - withdrawnAmount) / (scale * 100))
281+ let color = takeRight(value(assetInfo(assetId)).name, 1)
282+ if ((0 >= assetFarmingPower))
283+ then throw("asset not available")
284+ else if ((color == "U"))
285+ then throw("use another function to unstake Jackpot NFT")
255286 else {
256- let artefact = checkArtefactDetails(value(secondPayment.assetId))
257- if (if ((artefact != "ART-XHAT"))
258- then (artefact != "ART-POMP")
259- else false)
260- then throw("You need to attach a ART-XHAT or ART-POMP artefact")
261- else {
262- let nftInfo = value(assetInfo(value(firstPayment.assetId)))
263- let asset1Gen = split(nftInfo.name, "")
264- if (if ((asset1Gen[14] == "G"))
265- then true
266- else (asset1Gen[14] == "J"))
267- then throw("You can't mirror this duck")
268- else if (if ((asset1Gen[5] == "S"))
269- then true
270- else (asset1Gen[5] == "T"))
271- then throw("you already attached a artefact")
272- else {
273- let char = if ((artefact == "ART-XHAT"))
274- then "T"
275- else if ((artefact == "ART-POMP"))
276- then "S"
277- else throw("No char defined")
278- let oldDuckGen = nftInfo.name
279- let oldFarmGen = asString(invoke(getBreederAddress(), "getGenFromName", [oldDuckGen], nil))
280- if ((oldFarmGen == oldFarmGen))
281- then {
282- let duckGen = manipulateName(oldDuckGen, 6, char)
283- let call = invoke(getBreederAddress(), "createDuckSpecialGenes", [i.caller.bytes, duckGen, children], nil)
284- if ((call == call))
285- then {
286- let callReduce = invoke(getBreederAddress(), "reduceRarity", [firstAssetId, oldFarmGen], nil)
287- if ((callReduce == callReduce))
288- then [Burn(value(firstPayment.assetId), 1), Burn(value(secondPayment.assetId), 1)]
289- else throw("Strict value is not equal to itself.")
290- }
291- else throw("Strict value is not equal to itself.")
292- }
293- else throw("Strict value is not equal to itself.")
294- }
295- }
287+ let result = getUnstakeResult(address, assetId, assetRewardDelta, reward, assetFarmingPower)
288+ $Tuple2((result ++ [IntegerEntry(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color), (tryGetInteger(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color)) + 1)), ScriptTransfer(i.caller, (reward * 1000000), getEggAssetId()), ScriptTransfer(i.caller, 1, assetId)]), (reward * 1000000))
296289 }
297- else throw("Strict value is not equal to itself.")
298290 }
299- }
300291
301292
302293
303294 @Callable(i)
304-func stakeItem () = if (if ((size(i.payments) == 1))
305- then (i.payments[0].amount == 1)
306- else false)
307- then {
308- let assetId = value(i.payments[0].assetId)
309- let artefactName = checkArtefactDetails(assetId)
310- if (containsElement(allStakeable, artefactName))
311- then if (if (containsElement(stakeableWithLock, artefactName))
312- then itemIsInCoolDown(artefactName, toBase58String(assetId))
313- else false)
314- then throw("Item can't be staked yet, it's in cooldown")
315- else {
316- let invoker = toString(i.caller)
317- let artefactId = tryGetString(keyArtefactOwner(artefactName, invoker))
318- if ((artefactId == ""))
319- then [StringEntry(keyArtefactOwner(artefactName, invoker), toBase58String(assetId))]
320- else throw(("You are already staking " + artefactName))
321- }
322- else throw("You can't stake this artafect")
295+func stakeJackpot (color) = if ((isLocked() > 0))
296+ then throw("EGG operations are temporarily locked")
297+ else {
298+ let pmt = value(i.payments[0])
299+ let assetId = value(pmt.assetId)
300+ let address = toString(i.caller)
301+ let availablePerches = tryGetInteger(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color))
302+ let assetIssuer = value(assetInfo(assetId)).issuer
303+ if ((pmt.amount != 1))
304+ then throw("NFT is not attached")
305+ else if (if ((assetIssuer == getIncubatorAddress()))
306+ then true
307+ else (assetIssuer == getBreederAddress()))
308+ then if ((takeRight(value(value(assetInfo(assetId)).name), 1) != "U"))
309+ then throw("jackpot only")
310+ else if ((0 >= availablePerches))
311+ then throw(("no perches available for the color " + color))
312+ else (getStakeResult(address, assetId, 100) ++ [IntegerEntry(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color), (availablePerches - 1)), StringEntry((((("address_" + toString(i.caller)) + "_asset_") + toBase58String(assetId)) + "_perchColor"), color)])
313+ else throw("asset is not valid")
323314 }
324- else throw("Invalid payment")
325315
326316
327317
328318 @Callable(i)
329-func unstakeItem (artefactName) = if (containsElement(allArtefact, artefactName))
330- then {
331- let invoker = toString(i.caller)
332- let artefactId = tryGetString(keyArtefactOwner(artefactName, invoker))
333- if ((artefactId == ""))
334- then throw(("You didnt stake " + artefactName))
335- else [IntegerEntry(keyUnstakeHeight(artefactName, artefactId), height), ScriptTransfer(i.caller, 1, fromBase58String(artefactId)), DeleteEntry(keyArtefactOwner(artefactName, invoker))]
336- }
337- else throw("This artefact doesn't exist")
319+func unstakeJackpot (asset) = if (isUserBlacklisted(toString(i.caller)))
320+ then throw("Ooops, looks like you lost in one of the Ducksquid games! As you already know, any loss has its consequences, so you will be not able to claim your farming rewards till the end of DuckSquid game. Quack in peace!")
321+ else if ((isLocked() > 0))
322+ then throw("EGG operations are temporarily locked")
323+ else {
324+ let assetId = fromBase58String(asset)
325+ let address = toString(i.caller)
326+ let color = tryGetString((((("address_" + address) + "_asset_") + asset) + "_perchColor"))
327+ let assetFarmingPower = getLastKnownAssetFarmingPower(address, asset)
328+ let assetRewardDelta = calcAssetRewardDelta(address, asset, assetFarmingPower)
329+ let farmedAmount = (assetRewardDelta + tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount")))
330+ let withdrawnAmount = tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"))
331+ let reward = ((farmedAmount - withdrawnAmount) / (scale * 100))
332+ if ((takeRight(value(value(assetInfo(assetId)).name), 1) != "U"))
333+ then throw("jackpot only")
334+ else if ((assetFarmingPower > 0))
335+ then {
336+ let result = getUnstakeResult(address, assetId, assetRewardDelta, reward, assetFarmingPower)
337+ $Tuple2((result ++ [IntegerEntry(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color), (tryGetInteger(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color)) + 1)), ScriptTransfer(i.caller, (reward * 1000000), getEggAssetId()), ScriptTransfer(i.caller, 1, assetId)]), (reward * 1000000))
338+ }
339+ else throw("")
340+ }
338341
339342
340343
341344 @Callable(i)
342-func preInit () = [IntegerEntry("static_ART-LAKE_farmingSlots", 200), IntegerEntry("static_ART-LAKE_farmingBoost", 2), IntegerEntry("static_ART-HOUSE_farmingSlots", 4), IntegerEntry("static_ART-HOUSE_farmingBoost", 30), IntegerEntry("static_ART-BIGHOUSE_farmingSlots", 10), IntegerEntry("static_ART-BIGHOUSE_farmingBoost", 15)]
345+func claimReward (asset) = if (isUserBlacklisted(toString(i.caller)))
346+ then throw("Ooops, looks like you lost in one of the Ducksquid games! As you already know, any loss has its consequences, so you will be not able to claim your farming rewards till the end of DuckSquid game. Quack in peace!")
347+ else if ((isLocked() > 0))
348+ then throw("EGG operations are temporarily locked")
349+ else {
350+ let address = toString(i.caller)
351+ let assetId = fromBase58String(asset)
352+ let assetFarmingPower = getLastKnownAssetFarmingPower(address, asset)
353+ let assetRewardDelta = calcAssetRewardDelta(address, asset, assetFarmingPower)
354+ let farmedAmount = (assetRewardDelta + tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount")))
355+ let withdrawnAmount = tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"))
356+ let reward = ((farmedAmount - withdrawnAmount) / (scale * 100))
357+ if ((0 >= reward))
358+ then throw("you have no EGGs to withdraw")
359+ else $Tuple2([IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"), (tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount")) + (reward * scale2))), ScriptTransfer(Address(fromBase58String(address)), (reward * 1000000), getEggAssetId())], (reward * 1000000))
360+ }
343361
344-
345-
346-@Callable(i)
347-func issueArtefact (type,receiver) = if ((i.caller == this))
348- then {
349- let txIdStr = toBase58String(i.transactionId)
350- let address = Address(fromBase58String(receiver))
351- let artefact = Issue(type, "NFT artefact of Waves Ducks game. Drop #2.", 1, 0, false, unit, 0)
352- let artefactId = calculateAssetId(artefact)
353-[artefact, StringEntry((("artefact_" + toBase58String(artefactId)) + "_type"), type), ScriptTransfer(address, 1, artefactId)]
354- }
355- else throw("admin only")
356-
357-
358-
359-@Callable(i)
360-func setLock (n) = if ((i.caller == this))
361- then [IntegerEntry("global_locked", n)]
362- else throw("admin only")
363-
364-
365-
366-@Callable(i)
367-func buyArtefact () = if ((lastBlock.timestamp > 1639742400000))
368- then throw("There are no active sales now... ")
369- else if ((tryGetInteger("global_locked") > 0))
370- then throw("contract is temporarily locked")
371- else if ((tryGetInteger("global_artAmount") >= artefactsLimit))
372- then throw("SOLDOUT!!! Hurray!")
373- else if (if ((1639605600000 > lastBlock.timestamp))
374- then (i.caller != Address(devAddress))
375- else false)
376- then throw("Too early...")
377- else {
378- let firstPayment = value(i.payments[0])
379- if ((firstPayment.assetId != getEggAssetId()))
380- then throw(("You can attach only EGG tokens with the following asset id: " + toBase58String(getEggAssetId())))
381- else if ((eggsNeeded > firstPayment.amount))
382- then throw(("To hatch a duck you currently need the following amount of EGGlets: " + toString(eggsNeeded)))
383- else [StringEntry((((toString(i.caller) + "_") + toBase58String(i.transactionId)) + "_status"), "started"), IntegerEntry((((toString(i.caller) + "_") + toBase58String(i.transactionId)) + "_finishHeight"), (height + 2)), IntegerEntry("global_artAmount", (tryGetInteger("global_artAmount") + 1))]
384- }
385-
386-
387-
388-@Callable(i)
389-func setGlobalArtAmount (newAmount) = if (if ((i.caller == this))
390- then true
391- else (i.caller == Address(devAddress)))
392- then [IntegerEntry("global_artAmount", newAmount)]
393- else throw("Permission denied")
394-
395-
396-
397-@Callable(i)
398-func claimArtefact (boxIdStr) = {
399- let txId = fromBase58String(boxIdStr)
400- let statusKey = (((toString(i.caller) + "_") + boxIdStr) + "_status")
401- let heightKey = (((toString(i.caller) + "_") + boxIdStr) + "_finishHeight")
402- if ((getStringValue(statusKey) != "started"))
403- then throw("claimed already")
404- else if ((getIntegerValue(heightKey) > height))
405- then throw("you cannot claim yet")
406- else {
407- let artType = getRandomArtefact(txId, getIntegerValue(heightKey))
408- let asset = Issue(artType, "Artefact of Waves Ducks metaverse.", 1, 0, false, unit, getIntegerValue(heightKey))
409- let assetId = calculateAssetId(asset)
410-[StringEntry(statusKey, artType), StringEntry((((toString(i.caller) + "_") + boxIdStr) + "_artefactId"), toBase58String(assetId)), StringEntry((toBase58String(assetId) + "_type"), artType), asset, ScriptTransfer(i.caller, 1, assetId)]
411- }
412- }
413-
414-
415-@Verifier(tx)
416-func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
417362
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-func keyArtefactOwner (artefactName,owner) = (((artefactName + "_") + owner) + "_owner")
4+let perchPrice = (100 * 1000000)
55
6+let scale = 10000
67
7-func keyUnstakeHeight (artefactName,artefactId) = (((artefactName + "_") + artefactId) + "_unstake_height")
8-
9-
10-func getProcessFinishHeightKey (address,txId) = (((address + "_") + toBase58String(txId)) + "_fh")
11-
12-
13-let devAddress = base58'3P44yqcpfhPF2iC1nptm2ZJCTaN7VYhz9og'
14-
15-let eggsNeeded = (3 * 100000000)
16-
17-let artefactsLimit = (301 + 600)
18-
19-let freeGenes = ["A", "B", "C", "D", "E"]
20-
21-let oldArtefacts = ["ART-LAKE", "ART-HOUSE", "ART-BIGHOUSE", "ART-FIXGENE", "ART-FREEGENE", "ART-MIRROR", "ART-POMP", "ART-CAPE", "ART-HAT", "ART-CUSTOMDUCK"]
22-
23-let artefacts = ["ART-XMISTL", "ART-XHAT", "ART-XSCARF", "ART-XSWEATER", "ART-XSOCK", "ART-XTREE"]
24-
25-let stakeableWithLock = ["ART-LAKE", "ART-XTREE"]
26-
27-let stakeableWithoutLock = ["ART-XMISTL"]
28-
29-let allStakeable = (stakeableWithoutLock ++ stakeableWithLock)
30-
31-let allArtefact = (artefacts ++ oldArtefacts)
32-
33-func tryGetString (key) = match getString(this, key) {
34- case a: String =>
35- a
36- case _ =>
37- ""
38-}
39-
40-
41-func tryGetInteger (key) = match getInteger(this, key) {
42- case a: Int =>
43- a
44- case _ =>
45- 0
46-}
47-
48-
49-func getRandomNumber (variants,txId,finishHeight,offset) = {
50- let randomSeedBlock = value(blockInfoByHeight((finishHeight - 1)))
51- let randomHash = sha256(((base58'items' + txId) + value(randomSeedBlock.vrf)))
52- (toInt(randomHash, offset) % variants)
53- }
54-
55-
56-func getRandomArtefact (boxId,h) = {
57- let randomNumber = getRandomNumber(6, boxId, h, 1)
58-artefacts[randomNumber]
59- }
60-
61-
62-func getRandomGenes (txId,h) = {
63- let randomNumber = getRandomNumber(6, txId, h, 2)
64-freeGenes[randomNumber]
65- }
66-
67-
68-func checkArtefactDetails (assetId) = {
69- let asset = value(assetInfo(assetId))
70- let assetName = value(asset.name)
71- if (if (containsElement(allArtefact, assetName))
72- then (asset.issuer == this)
73- else false)
74- then assetName
75- else throw("Invalid artefact")
76- }
77-
8+let scale2 = 1000000
789
7910 func tryGetStringExternal (address,key) = match getString(address, key) {
8011 case a: String =>
8112 a
8213 case _ =>
8314 ""
8415 }
8516
8617
18+func tryGetString (key) = tryGetStringExternal(this, key)
19+
20+
8721 func getOracle () = Address(fromBase58String(tryGetString("static_oracleAddress")))
22+
23+
24+func getEggAssetId () = fromBase58String(tryGetStringExternal(getOracle(), "static_eggAssetId"))
25+
26+
27+func getIncubatorAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), "static_incubatorAddress")))
28+
29+
30+func getRebirthAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), "static_rebirthAddress")))
31+
32+
33+func getSwopPromoAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), "static_swopPromoAddress")))
8834
8935
9036 func getBreederAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), "static_breederAddress")))
9137
9238
93-func getEggAssetId () = fromBase58String(tryGetStringExternal(getOracle(), "static_eggAssetId"))
39+func getRefContractAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), "static_refContractAddress")))
40+
41+
42+func getItemsAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), "static_itemsAddress")))
43+
44+
45+let RefererReward = 5
46+
47+func getRewardPerBlock () = 684
48+
49+
50+func isLocked () = {
51+ let masterAddress = Address(base58'3PEPftf2kWZDmAaWBjs6BUJa9957kiA2PkU')
52+ match getInteger(masterAddress, "egglock") {
53+ case b: Int =>
54+ b
55+ case _ =>
56+ 0
57+ }
58+ }
59+
60+
61+func tryGetInteger (key) = match getInteger(this, key) {
62+ case b: Int =>
63+ b
64+ case _ =>
65+ 0
66+}
67+
68+
69+func isUserBlacklisted (address) = false
70+
71+
72+func getAssetOrigin (generation) = if ((generation == "G"))
73+ then getIncubatorAddress()
74+ else getBreederAddress()
75+
76+
77+func getAssetRarity (genotype,generation) = {
78+ let quantity = valueOrErrorMessage(getInteger(getAssetOrigin(generation), (("stats_" + genotype) + "_quantity")), (("stats_" + genotype) + "_quantity not found"))
79+ let power = pow((10000 / quantity), 4, 5, 1, 2, FLOOR)
80+ if ((power > 0))
81+ then power
82+ else 2
83+ }
9484
9585
9686 func asString (value) = match value {
9787 case string: String =>
9888 string
9989 case _ =>
10090 throw("wrong type, expected: String")
10191 }
10292
10393
10494 func asInt (value) = match value {
10595 case int: Int =>
10696 int
10797 case _ =>
10898 throw("wrong type, expected: Int")
10999 }
110100
111101
112-func manipulateName (assetName,position,char) = ((take(assetName, (position - 1)) + char) + takeRight(assetName, (16 - position)))
102+func getAssetFarmingPower (assetId,address) = if (if ((value(assetInfo(assetId)).issuer == getBreederAddress()))
103+ then true
104+ else (value(assetInfo(assetId)).issuer == getIncubatorAddress()))
105+ then {
106+ let assetName = value(assetInfo(assetId)).name
107+ let generation = take(takeRight(assetName, 2), 1)
108+ let farmGen = asString(invoke(getBreederAddress(), "getGenFromName", [assetName], nil))
109+ if ((farmGen == farmGen))
110+ then {
111+ let farmBoost = asInt(invoke(getItemsAddress(), "calculateFarmingPowerBoost", [toBase58String(assetId), address], nil))
112+ if ((farmBoost == farmBoost))
113+ then {
114+ let rarity = getAssetRarity(farmGen, generation)
115+ let totalFarmingPower = (rarity + fraction(rarity, farmBoost, 100))
116+ $Tuple2(farmGen, totalFarmingPower)
117+ }
118+ else throw("Strict value is not equal to itself.")
119+ }
120+ else throw("Strict value is not equal to itself.")
121+ }
122+ else throw("not valid NFT")
113123
114124
115-func itemIsInCoolDown (artefactName,artefactId) = {
116- let unstakeHeightLast = tryGetInteger(keyUnstakeHeight(artefactName, artefactId))
117- let cooldownPeriod = 240
118- if ((height > (unstakeHeightLast + cooldownPeriod)))
119- then false
120- else true
125+func getLastKnownAssetFarmingPower (address,assetId) = tryGetInteger((((("address_" + address) + "_asset_") + assetId) + "_farmingPower"))
126+
127+
128+func getAssetsByGen (gen) = {
129+ let s = tryGetString(("assets_" + gen))
130+ if ((s == ""))
131+ then nil
132+ else split(s, ",")
133+ }
134+
135+
136+func calcInterest (previousInterest,previousInterestHeight,totalFarmingPower) = (previousInterest + (((scale * getRewardPerBlock()) * (height - previousInterestHeight)) / totalFarmingPower))
137+
138+
139+func getCurrentInterest () = if ((tryGetInteger("total_farmingPower") > 0))
140+ then {
141+ let previousInterest = tryGetInteger("total_lastCheckInterest")
142+ let previousInterestHeight = tryGetInteger("total_lastCheckInterestHeight")
143+ let totalFarmingPower = tryGetInteger("total_farmingPower")
144+ calcInterest(previousInterest, previousInterestHeight, totalFarmingPower)
145+ }
146+ else if ((tryGetInteger("total_startHeight") != 0))
147+ then tryGetInteger("total_lastCheckInterest")
148+ else throw("farming is not launched, yet")
149+
150+
151+func calcAssetRewardDelta (address,assetId,assetFarmingPower) = {
152+ let lastCheckAssetInterest = tryGetInteger((((("address_" + address) + "_asset_") + assetId) + "_lastCheckInterest"))
153+ let currentInterest = getCurrentInterest()
154+ (assetFarmingPower * (currentInterest - lastCheckAssetInterest))
155+ }
156+
157+
158+func addAssetIdToGenEntry (assetId,assetGen) = {
159+ let currentValue = tryGetString((("assets_" + assetGen) + "_locked"))
160+ if ((currentValue == ""))
161+ then assetId
162+ else ((currentValue + ",") + assetId)
163+ }
164+
165+
166+func getStakeResult (address,assetId,assetFarmingPower) = {
167+ let asset = toBase58String(assetId)
168+[IntegerEntry("total_farmingPower", (tryGetInteger("total_farmingPower") + assetFarmingPower)), IntegerEntry("total_lastCheckInterest", getCurrentInterest()), IntegerEntry("total_lastCheckInterestHeight", height), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_farmingPower"), assetFarmingPower), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_lastCheckInterest"), getCurrentInterest())]
169+ }
170+
171+
172+func getUnstakeResult (address,assetId,rewardDelta,withdrawnAmount,assetFarmingPower) = {
173+ let asset = toBase58String(assetId)
174+[IntegerEntry("total_farmingPower", (tryGetInteger("total_farmingPower") - assetFarmingPower)), IntegerEntry("total_lastCheckInterest", getCurrentInterest()), IntegerEntry("total_lastCheckInterestHeight", height), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_farmingPower"), 0), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_lastCheckInterest"), getCurrentInterest()), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"), (tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount")) + (withdrawnAmount * scale2))), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount"), (tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount")) + rewardDelta))]
175+ }
176+
177+
178+func calculatePerchPrice (address) = {
179+ let hasArtefactStaked = tryGetStringExternal(getItemsAddress(), (("ART-XMISTL_" + address) + "_owner"))
180+ if ((hasArtefactStaked == ""))
181+ then perchPrice
182+ else ((perchPrice / 10) * 9)
121183 }
122184
123185
124186 @Callable(i)
125187 func configureOracle (oracle) = if ((i.caller != this))
126188 then throw("admin only")
127189 else [StringEntry("static_oracleAddress", oracle)]
128190
129191
130192
131193 @Callable(i)
132-func calculateFarmingPowerBoost (duckId,address) = {
133- let lakeBoost = if ((tryGetString(keyArtefactOwner("ART-LAKE", address)) != ""))
134- then 2
135- else 0
136- let xmasTreeBoost = if ((tryGetString(keyArtefactOwner("ART-XTREE", address)) != ""))
137- then 3
138- else 0
139- let totalBoost = (lakeBoost + xmasTreeBoost)
140- $Tuple2(nil, totalBoost)
141- }
194+func init () = if ((i.caller != this))
195+ then throw("admin only")
196+ else [IntegerEntry("total_startHeight", height)]
142197
143198
144199
145200 @Callable(i)
146-func fixedGene (txIdStr,parentFixedGene,positionFixedGene) = {
147- let firstPayment = value(i.payments[0])
148- let firstAssetId = toBase58String(value(firstPayment.assetId))
149- if ((firstPayment.amount != 1))
150- then throw("NFT is not attached")
201+func buyPerch (color,refererAddress) = if ((isLocked() > 0))
202+ then throw("EGG operations are temporarily locked")
203+ else if ((0 > value(indexOf(["B", "R", "G", "Y"], color))))
204+ then throw("you need to set color properly")
151205 else {
152- let artefact = checkArtefactDetails(value(firstPayment.assetId))
153- if ((artefact != "ART-FIXGENE"))
154- then throw("You need to attach a ART-FIXGENE artefact")
155- else {
156- let txId = fromBase58String(txIdStr)
157- let finishHeightKey = getProcessFinishHeightKey(toString(i.caller), txId)
158- let processFinishHeight = getIntegerValue(getBreederAddress(), finishHeightKey)
159- let duckGenesString = asString(invoke(getBreederAddress(), "generateDuck", [txIdStr, processFinishHeight, parentFixedGene, positionFixedGene, "", 0], nil))
160- if ((duckGenesString == duckGenesString))
161- then {
162- let call = invoke(getBreederAddress(), "finishDuckHatchingItems", [txIdStr, duckGenesString], nil)
163- if ((call == call))
164- then [Burn(value(firstPayment.assetId), 1)]
165- else throw("Strict value is not equal to itself.")
166- }
167- else throw("Strict value is not equal to itself.")
168- }
206+ let firstPayment = value(i.payments[0])
207+ let exactPrice = calculatePerchPrice(toString(i.caller))
208+ if ((firstPayment.assetId != getEggAssetId()))
209+ then throw(("You can attach only EGG tokens with the following asset id: " + toBase58String(getEggAssetId())))
210+ else if ((firstPayment.amount != exactPrice))
211+ then throw(("To buy a perch you currently need the following amount of EGGlets: " + toString(exactPrice)))
212+ else {
213+ let refererRewardForPerch = fraction(firstPayment.amount, RefererReward, 100)
214+ let refCall = invoke(getRefContractAddress(), "refPayment", [refererAddress], [AttachedPayment(getEggAssetId(), refererRewardForPerch)])
215+ if ((refCall == refCall))
216+ then {
217+ let perchAmountKey = ((("address_" + toString(i.caller)) + "_perchesAvailable_") + color)
218+ let perchAmount = tryGetInteger(perchAmountKey)
219+[IntegerEntry(perchAmountKey, (perchAmount + 1))]
220+ }
221+ else throw("Strict value is not equal to itself.")
222+ }
169223 }
170- }
171224
172225
173226
174227 @Callable(i)
175-func freeGene (txIdStr) = {
176- let firstPayment = value(i.payments[0])
177- let firstAssetId = toBase58String(value(firstPayment.assetId))
178- if ((firstPayment.amount != 1))
179- then throw("NFT is not attached")
228+func addFreePerch (address,color) = if ((0 > value(indexOf(["B", "R", "G", "Y"], color))))
229+ then throw("you need to set color properly")
230+ else if (if (if ((i.caller != getRebirthAddress()))
231+ then (i.caller != this)
232+ else false)
233+ then (i.caller != getSwopPromoAddress())
234+ else false)
235+ then throw("rebirth and swop promo only")
180236 else {
181- let artefact = checkArtefactDetails(value(firstPayment.assetId))
182- if ((artefact != "ART-FREEGENE"))
183- then throw("You need to attach a ART-FREEGENE artefact")
184- else {
185- let txId = fromBase58String(txIdStr)
186- let finishHeightKey = getProcessFinishHeightKey(toString(i.caller), txId)
187- let processFinishHeight = getIntegerValue(getBreederAddress(), finishHeightKey)
188- let selectedGene = getRandomGenes(txId, processFinishHeight)
189- let randomPosition = getRandomNumber(7, txId, processFinishHeight, 3)
190- let duckGenesString = asString(invoke(getBreederAddress(), "generateDuck", [txIdStr, processFinishHeight, 0, 0, selectedGene, randomPosition], nil))
191- if ((duckGenesString == duckGenesString))
192- then {
193- let call = invoke(getBreederAddress(), "finishDuckHatchingItems", [txIdStr, duckGenesString], nil)
194- if ((call == call))
195- then [Burn(value(firstPayment.assetId), 1)]
196- else throw("Strict value is not equal to itself.")
197- }
198- else throw("Strict value is not equal to itself.")
199- }
237+ let perchAmountKey = ((("address_" + address) + "_perchesAvailable_") + color)
238+ let perchAmount = tryGetInteger(perchAmountKey)
239+ $Tuple2([IntegerEntry(perchAmountKey, (perchAmount + 1))], "")
200240 }
201- }
202241
203242
204243
205244 @Callable(i)
206-func copyDuck () = {
207- let firstPayment = value(i.payments[0])
208- let secondPayment = value(i.payments[1])
209- let firstAssetId = toBase58String(value(firstPayment.assetId))
210- let children = asInt(invoke(getBreederAddress(), "validateAndGetChildren", [firstAssetId], nil))
211- if ((children == children))
212- then if (if ((firstPayment.amount != 1))
213- then true
214- else (secondPayment.amount != 1))
245+func stakeNFT () = if ((isLocked() > 0))
246+ then throw("EGG operations are temporarily locked")
247+ else {
248+ let pmt = value(i.payments[0])
249+ let assetId = value(value(i.payments[0]).assetId)
250+ let address = toString(i.caller)
251+ let color = takeRight(value(assetInfo(assetId)).name, 1)
252+ let availablePerches = tryGetInteger(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color))
253+ if ((pmt.amount != 1))
215254 then throw("NFT is not attached")
216- else {
217- let artefact = checkArtefactDetails(value(secondPayment.assetId))
218- if ((artefact != "ART-MIRROR"))
219- then throw("You need to attach a ART-MIRROR artefact")
220- else {
221- let nftInfo = value(assetInfo(value(firstPayment.assetId)))
222- let asset1Gen = split(nftInfo.name, "")
223- if (if ((asset1Gen[14] == "G"))
224- then true
225- else (asset1Gen[14] == "J"))
226- then throw("You can't mirror this duck")
227- else {
228- let duckGen = nftInfo.name
229- let call = invoke(getBreederAddress(), "createDuckSpecialGenes", [i.caller.bytes, duckGen, children], nil)
230- if ((call == call))
231- then [ScriptTransfer(i.caller, 1, firstPayment.assetId), Burn(value(secondPayment.assetId), 1)]
232- else throw("Strict value is not equal to itself.")
233- }
234- }
235- }
236- else throw("Strict value is not equal to itself.")
237- }
255+ else if ((0 >= availablePerches))
256+ then throw(("no perches available for the color " + color))
257+ else {
258+ let $t096749747 = getAssetFarmingPower(assetId, address)
259+ let assetGen = $t096749747._1
260+ let assetFarmingPower = $t096749747._2
261+ let assetRewardDelta = calcAssetRewardDelta(address, toBase58String(assetId), assetFarmingPower)
262+ (getStakeResult(address, assetId, assetFarmingPower) ++ [IntegerEntry(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color), (availablePerches - 1))])
263+ }
264+ }
238265
239266
240267
241268 @Callable(i)
242-func addArteFactToDuck () = {
243- let firstPayment = value(i.payments[0])
244- let secondPayment = value(i.payments[1])
245- let firstAssetId = toBase58String(value(firstPayment.assetId))
246- if (if ((firstPayment.amount != 1))
247- then true
248- else (secondPayment.amount != 1))
249- then throw("NFT is not attached")
269+func unstakeNFT (asset) = if (isUserBlacklisted(toString(i.caller)))
270+ then throw("Ooops, looks like you lost in one of the Ducksquid games! As you already know, any loss has its consequences, so you will be not able to claim your farming rewards till the end of DuckSquid game. Quack in peace!")
271+ else if ((isLocked() > 0))
272+ then throw("EGG operations are temporarily locked")
250273 else {
251- let children = asInt(invoke(getBreederAddress(), "validateAndGetChildren", [firstAssetId], nil))
252- if ((children == children))
253- then if ((children == 0))
254- then throw("You can only pick a sterile NFT-duck")
274+ let assetId = fromBase58String(asset)
275+ let address = toString(i.caller)
276+ let assetFarmingPower = getLastKnownAssetFarmingPower(address, asset)
277+ let assetRewardDelta = calcAssetRewardDelta(address, asset, assetFarmingPower)
278+ let farmedAmount = (assetRewardDelta + tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount")))
279+ let withdrawnAmount = tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"))
280+ let reward = ((farmedAmount - withdrawnAmount) / (scale * 100))
281+ let color = takeRight(value(assetInfo(assetId)).name, 1)
282+ if ((0 >= assetFarmingPower))
283+ then throw("asset not available")
284+ else if ((color == "U"))
285+ then throw("use another function to unstake Jackpot NFT")
255286 else {
256- let artefact = checkArtefactDetails(value(secondPayment.assetId))
257- if (if ((artefact != "ART-XHAT"))
258- then (artefact != "ART-POMP")
259- else false)
260- then throw("You need to attach a ART-XHAT or ART-POMP artefact")
261- else {
262- let nftInfo = value(assetInfo(value(firstPayment.assetId)))
263- let asset1Gen = split(nftInfo.name, "")
264- if (if ((asset1Gen[14] == "G"))
265- then true
266- else (asset1Gen[14] == "J"))
267- then throw("You can't mirror this duck")
268- else if (if ((asset1Gen[5] == "S"))
269- then true
270- else (asset1Gen[5] == "T"))
271- then throw("you already attached a artefact")
272- else {
273- let char = if ((artefact == "ART-XHAT"))
274- then "T"
275- else if ((artefact == "ART-POMP"))
276- then "S"
277- else throw("No char defined")
278- let oldDuckGen = nftInfo.name
279- let oldFarmGen = asString(invoke(getBreederAddress(), "getGenFromName", [oldDuckGen], nil))
280- if ((oldFarmGen == oldFarmGen))
281- then {
282- let duckGen = manipulateName(oldDuckGen, 6, char)
283- let call = invoke(getBreederAddress(), "createDuckSpecialGenes", [i.caller.bytes, duckGen, children], nil)
284- if ((call == call))
285- then {
286- let callReduce = invoke(getBreederAddress(), "reduceRarity", [firstAssetId, oldFarmGen], nil)
287- if ((callReduce == callReduce))
288- then [Burn(value(firstPayment.assetId), 1), Burn(value(secondPayment.assetId), 1)]
289- else throw("Strict value is not equal to itself.")
290- }
291- else throw("Strict value is not equal to itself.")
292- }
293- else throw("Strict value is not equal to itself.")
294- }
295- }
287+ let result = getUnstakeResult(address, assetId, assetRewardDelta, reward, assetFarmingPower)
288+ $Tuple2((result ++ [IntegerEntry(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color), (tryGetInteger(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color)) + 1)), ScriptTransfer(i.caller, (reward * 1000000), getEggAssetId()), ScriptTransfer(i.caller, 1, assetId)]), (reward * 1000000))
296289 }
297- else throw("Strict value is not equal to itself.")
298290 }
299- }
300291
301292
302293
303294 @Callable(i)
304-func stakeItem () = if (if ((size(i.payments) == 1))
305- then (i.payments[0].amount == 1)
306- else false)
307- then {
308- let assetId = value(i.payments[0].assetId)
309- let artefactName = checkArtefactDetails(assetId)
310- if (containsElement(allStakeable, artefactName))
311- then if (if (containsElement(stakeableWithLock, artefactName))
312- then itemIsInCoolDown(artefactName, toBase58String(assetId))
313- else false)
314- then throw("Item can't be staked yet, it's in cooldown")
315- else {
316- let invoker = toString(i.caller)
317- let artefactId = tryGetString(keyArtefactOwner(artefactName, invoker))
318- if ((artefactId == ""))
319- then [StringEntry(keyArtefactOwner(artefactName, invoker), toBase58String(assetId))]
320- else throw(("You are already staking " + artefactName))
321- }
322- else throw("You can't stake this artafect")
295+func stakeJackpot (color) = if ((isLocked() > 0))
296+ then throw("EGG operations are temporarily locked")
297+ else {
298+ let pmt = value(i.payments[0])
299+ let assetId = value(pmt.assetId)
300+ let address = toString(i.caller)
301+ let availablePerches = tryGetInteger(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color))
302+ let assetIssuer = value(assetInfo(assetId)).issuer
303+ if ((pmt.amount != 1))
304+ then throw("NFT is not attached")
305+ else if (if ((assetIssuer == getIncubatorAddress()))
306+ then true
307+ else (assetIssuer == getBreederAddress()))
308+ then if ((takeRight(value(value(assetInfo(assetId)).name), 1) != "U"))
309+ then throw("jackpot only")
310+ else if ((0 >= availablePerches))
311+ then throw(("no perches available for the color " + color))
312+ else (getStakeResult(address, assetId, 100) ++ [IntegerEntry(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color), (availablePerches - 1)), StringEntry((((("address_" + toString(i.caller)) + "_asset_") + toBase58String(assetId)) + "_perchColor"), color)])
313+ else throw("asset is not valid")
323314 }
324- else throw("Invalid payment")
325315
326316
327317
328318 @Callable(i)
329-func unstakeItem (artefactName) = if (containsElement(allArtefact, artefactName))
330- then {
331- let invoker = toString(i.caller)
332- let artefactId = tryGetString(keyArtefactOwner(artefactName, invoker))
333- if ((artefactId == ""))
334- then throw(("You didnt stake " + artefactName))
335- else [IntegerEntry(keyUnstakeHeight(artefactName, artefactId), height), ScriptTransfer(i.caller, 1, fromBase58String(artefactId)), DeleteEntry(keyArtefactOwner(artefactName, invoker))]
336- }
337- else throw("This artefact doesn't exist")
319+func unstakeJackpot (asset) = if (isUserBlacklisted(toString(i.caller)))
320+ then throw("Ooops, looks like you lost in one of the Ducksquid games! As you already know, any loss has its consequences, so you will be not able to claim your farming rewards till the end of DuckSquid game. Quack in peace!")
321+ else if ((isLocked() > 0))
322+ then throw("EGG operations are temporarily locked")
323+ else {
324+ let assetId = fromBase58String(asset)
325+ let address = toString(i.caller)
326+ let color = tryGetString((((("address_" + address) + "_asset_") + asset) + "_perchColor"))
327+ let assetFarmingPower = getLastKnownAssetFarmingPower(address, asset)
328+ let assetRewardDelta = calcAssetRewardDelta(address, asset, assetFarmingPower)
329+ let farmedAmount = (assetRewardDelta + tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount")))
330+ let withdrawnAmount = tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"))
331+ let reward = ((farmedAmount - withdrawnAmount) / (scale * 100))
332+ if ((takeRight(value(value(assetInfo(assetId)).name), 1) != "U"))
333+ then throw("jackpot only")
334+ else if ((assetFarmingPower > 0))
335+ then {
336+ let result = getUnstakeResult(address, assetId, assetRewardDelta, reward, assetFarmingPower)
337+ $Tuple2((result ++ [IntegerEntry(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color), (tryGetInteger(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color)) + 1)), ScriptTransfer(i.caller, (reward * 1000000), getEggAssetId()), ScriptTransfer(i.caller, 1, assetId)]), (reward * 1000000))
338+ }
339+ else throw("")
340+ }
338341
339342
340343
341344 @Callable(i)
342-func preInit () = [IntegerEntry("static_ART-LAKE_farmingSlots", 200), IntegerEntry("static_ART-LAKE_farmingBoost", 2), IntegerEntry("static_ART-HOUSE_farmingSlots", 4), IntegerEntry("static_ART-HOUSE_farmingBoost", 30), IntegerEntry("static_ART-BIGHOUSE_farmingSlots", 10), IntegerEntry("static_ART-BIGHOUSE_farmingBoost", 15)]
345+func claimReward (asset) = if (isUserBlacklisted(toString(i.caller)))
346+ then throw("Ooops, looks like you lost in one of the Ducksquid games! As you already know, any loss has its consequences, so you will be not able to claim your farming rewards till the end of DuckSquid game. Quack in peace!")
347+ else if ((isLocked() > 0))
348+ then throw("EGG operations are temporarily locked")
349+ else {
350+ let address = toString(i.caller)
351+ let assetId = fromBase58String(asset)
352+ let assetFarmingPower = getLastKnownAssetFarmingPower(address, asset)
353+ let assetRewardDelta = calcAssetRewardDelta(address, asset, assetFarmingPower)
354+ let farmedAmount = (assetRewardDelta + tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount")))
355+ let withdrawnAmount = tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"))
356+ let reward = ((farmedAmount - withdrawnAmount) / (scale * 100))
357+ if ((0 >= reward))
358+ then throw("you have no EGGs to withdraw")
359+ else $Tuple2([IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"), (tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount")) + (reward * scale2))), ScriptTransfer(Address(fromBase58String(address)), (reward * 1000000), getEggAssetId())], (reward * 1000000))
360+ }
343361
344-
345-
346-@Callable(i)
347-func issueArtefact (type,receiver) = if ((i.caller == this))
348- then {
349- let txIdStr = toBase58String(i.transactionId)
350- let address = Address(fromBase58String(receiver))
351- let artefact = Issue(type, "NFT artefact of Waves Ducks game. Drop #2.", 1, 0, false, unit, 0)
352- let artefactId = calculateAssetId(artefact)
353-[artefact, StringEntry((("artefact_" + toBase58String(artefactId)) + "_type"), type), ScriptTransfer(address, 1, artefactId)]
354- }
355- else throw("admin only")
356-
357-
358-
359-@Callable(i)
360-func setLock (n) = if ((i.caller == this))
361- then [IntegerEntry("global_locked", n)]
362- else throw("admin only")
363-
364-
365-
366-@Callable(i)
367-func buyArtefact () = if ((lastBlock.timestamp > 1639742400000))
368- then throw("There are no active sales now... ")
369- else if ((tryGetInteger("global_locked") > 0))
370- then throw("contract is temporarily locked")
371- else if ((tryGetInteger("global_artAmount") >= artefactsLimit))
372- then throw("SOLDOUT!!! Hurray!")
373- else if (if ((1639605600000 > lastBlock.timestamp))
374- then (i.caller != Address(devAddress))
375- else false)
376- then throw("Too early...")
377- else {
378- let firstPayment = value(i.payments[0])
379- if ((firstPayment.assetId != getEggAssetId()))
380- then throw(("You can attach only EGG tokens with the following asset id: " + toBase58String(getEggAssetId())))
381- else if ((eggsNeeded > firstPayment.amount))
382- then throw(("To hatch a duck you currently need the following amount of EGGlets: " + toString(eggsNeeded)))
383- else [StringEntry((((toString(i.caller) + "_") + toBase58String(i.transactionId)) + "_status"), "started"), IntegerEntry((((toString(i.caller) + "_") + toBase58String(i.transactionId)) + "_finishHeight"), (height + 2)), IntegerEntry("global_artAmount", (tryGetInteger("global_artAmount") + 1))]
384- }
385-
386-
387-
388-@Callable(i)
389-func setGlobalArtAmount (newAmount) = if (if ((i.caller == this))
390- then true
391- else (i.caller == Address(devAddress)))
392- then [IntegerEntry("global_artAmount", newAmount)]
393- else throw("Permission denied")
394-
395-
396-
397-@Callable(i)
398-func claimArtefact (boxIdStr) = {
399- let txId = fromBase58String(boxIdStr)
400- let statusKey = (((toString(i.caller) + "_") + boxIdStr) + "_status")
401- let heightKey = (((toString(i.caller) + "_") + boxIdStr) + "_finishHeight")
402- if ((getStringValue(statusKey) != "started"))
403- then throw("claimed already")
404- else if ((getIntegerValue(heightKey) > height))
405- then throw("you cannot claim yet")
406- else {
407- let artType = getRandomArtefact(txId, getIntegerValue(heightKey))
408- let asset = Issue(artType, "Artefact of Waves Ducks metaverse.", 1, 0, false, unit, getIntegerValue(heightKey))
409- let assetId = calculateAssetId(asset)
410-[StringEntry(statusKey, artType), StringEntry((((toString(i.caller) + "_") + boxIdStr) + "_artefactId"), toBase58String(assetId)), StringEntry((toBase58String(assetId) + "_type"), artType), asset, ScriptTransfer(i.caller, 1, assetId)]
411- }
412- }
413-
414-
415-@Verifier(tx)
416-func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
417362

github/deemru/w8io/3ef1775 
108.13 ms