tx · B41BtyqVQJRVEVfKnNSqX17thSsfg4kKXLxRUdyymEQd

3PAETTtuW7aSiyKtn9GuML3RgtV1xdq1mQW:  -0.01800000 Waves

2024.04.17 20:18 [4133016] smart account 3PAETTtuW7aSiyKtn9GuML3RgtV1xdq1mQW > SELF 0.00000000 Waves

{ "type": 13, "id": "B41BtyqVQJRVEVfKnNSqX17thSsfg4kKXLxRUdyymEQd", "fee": 1800000, "feeAssetId": null, "timestamp": 1713374303640, "version": 2, "chainId": 87, "sender": "3PAETTtuW7aSiyKtn9GuML3RgtV1xdq1mQW", "senderPublicKey": "DSNxHVyf38CbPoz2oSJ1b4FWqRvqFsAphCzdtrPeWPHa", "proofs": [ "2wFVKmc4t9xG8JLfJYwdifJzCSWEry1sPgnsRtUVhMDmiRaghefADKSX5fjbimE6txMaz932rZS4ZiQKsP5wKxhK" ], "script": "base64:AAIFAAAAAAAAADwIAhIDCgEIEgMKAQgSABIECgIICBIECgIICBIAEgASAwoBCBIDCgEIEgMKAQgSAwoBCBIDCgEIEgMKAQgAAAA4AAAAAApwZXJjaFByaWNlCQAAaAAAAAIAAAAAAAAAAGQAAAAAAAAPQkAAAAAABXNjYWxlAAAAAAAAACcQAAAAAAZzY2FsZTIAAAAAAAAPQkABAAAAFHRyeUdldFN0cmluZ0V4dGVybmFsAAAAAgAAAAdhZGRyZXNzAAAAA2tleQQAAAAHJG1hdGNoMAkABB0AAAACBQAAAAdhZGRyZXNzBQAAAANrZXkDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABlN0cmluZwQAAAABYQUAAAAHJG1hdGNoMAUAAAABYQIAAAAAAQAAAAx0cnlHZXRTdHJpbmcAAAABAAAAA2tleQkBAAAAFHRyeUdldFN0cmluZ0V4dGVybmFsAAAAAgUAAAAEdGhpcwUAAAADa2V5AQAAABdzdGF0aWNLZXlfb3JhY2xlQWRkcmVzcwAAAAACAAAAFHN0YXRpY19vcmFjbGVBZGRyZXNzAQAAABRzdGF0aWNLZXlfZWdnQXNzZXRJZAAAAAACAAAAEXN0YXRpY19lZ2dBc3NldElkAQAAABpzdGF0aWNLZXlfaW5jdWJhdG9yQWRkcmVzcwAAAAACAAAAF3N0YXRpY19pbmN1YmF0b3JBZGRyZXNzAQAAABhzdGF0aWNLZXlfYnJlZWRlckFkZHJlc3MAAAAAAgAAABVzdGF0aWNfYnJlZWRlckFkZHJlc3MBAAAAFnN0YXRpY0tleV9pdGVtc0FkZHJlc3MAAAAAAgAAABNzdGF0aWNfaXRlbXNBZGRyZXNzAQAAABlzdGF0aWNLZXlfbWV0YVJhY2VBZGRyZXNzAAAAAAIAAAAWc3RhdGljX21ldGFSYWNlQWRkcmVzcwEAAAAbc3RhdGljS2V5X2FjY0Jvb3N0ZXJBZGRyZXNzAAAAAAIAAAAYc3RhdGljX2FjY0Jvb3N0ZXJBZGRyZXNzAQAAAB9zdGF0aWNLZXlfcHJveHlTdGFraW5nQ29udHJhY3RzAAAAAAIAAAAcc3RhdGljX3Byb3h5U3Rha2luZ0NvbnRyYWN0cwEAAAAVc3RhdGljS2V5X21haW50ZW5hbmNlAAAAAAIAAAASc3RhdGljX21haW50ZW5hbmNlAQAAABlzdGF0aWNLZXlfY2ZNYXN0ZXJBZGRyZXNzAAAAAAIAAAAWc3RhdGljX2NmTWFzdGVyQWRkcmVzcwEAAAASc3RhdGljS2V5X2V4dHJhRmVlAAAAAAIAAAAPc3RhdGljX2V4dHJhRmVlAQAAABdzdGF0aWNLZXlfZmVlQWdncmVnYXRvcgAAAAACAAAAFHN0YXRpY19mZWVBZ2dyZWdhdG9yAQAAABRzdGF0aWNLZXlfZmFybWluZ05ldwAAAAACAAAAGHN0YXRpY19mYXJtaW5nQWRkcmVzc05ldwEAAAAJZ2V0T3JhY2xlAAAAAAkBAAAAB0FkZHJlc3MAAAABCQACWQAAAAEJAQAAAAx0cnlHZXRTdHJpbmcAAAABCQEAAAAXc3RhdGljS2V5X29yYWNsZUFkZHJlc3MAAAAAAQAAAA1nZXRFZ2dBc3NldElkAAAAAAkAAlkAAAABCQEAAAAUdHJ5R2V0U3RyaW5nRXh0ZXJuYWwAAAACCQEAAAAJZ2V0T3JhY2xlAAAAAAkBAAAAFHN0YXRpY0tleV9lZ2dBc3NldElkAAAAAAEAAAATZ2V0SW5jdWJhdG9yQWRkcmVzcwAAAAAJAQAAAAdBZGRyZXNzAAAAAQkAAlkAAAABCQEAAAAUdHJ5R2V0U3RyaW5nRXh0ZXJuYWwAAAACCQEAAAAJZ2V0T3JhY2xlAAAAAAkBAAAAGnN0YXRpY0tleV9pbmN1YmF0b3JBZGRyZXNzAAAAAAEAAAARZ2V0QnJlZWRlckFkZHJlc3MAAAAACQEAAAAHQWRkcmVzcwAAAAEJAAJZAAAAAQkBAAAAFHRyeUdldFN0cmluZ0V4dGVybmFsAAAAAgkBAAAACWdldE9yYWNsZQAAAAAJAQAAABhzdGF0aWNLZXlfYnJlZWRlckFkZHJlc3MAAAAAAQAAAA9nZXRJdGVtc0FkZHJlc3MAAAAACQEAAAAHQWRkcmVzcwAAAAEJAAJZAAAAAQkBAAAAFHRyeUdldFN0cmluZ0V4dGVybmFsAAAAAgkBAAAACWdldE9yYWNsZQAAAAAJAQAAABZzdGF0aWNLZXlfaXRlbXNBZGRyZXNzAAAAAAEAAAASZ2V0TWV0YXJhY2VBZGRyZXNzAAAAAAkBAAAAB0FkZHJlc3MAAAABCQACWQAAAAEJAQAAABR0cnlHZXRTdHJpbmdFeHRlcm5hbAAAAAIJAQAAAAlnZXRPcmFjbGUAAAAACQEAAAAZc3RhdGljS2V5X21ldGFSYWNlQWRkcmVzcwAAAAABAAAAFGdldEFjY0Jvb3N0ZXJBZGRyZXNzAAAAAAkBAAAAB0FkZHJlc3MAAAABCQACWQAAAAEJAQAAABR0cnlHZXRTdHJpbmdFeHRlcm5hbAAAAAIJAQAAAAlnZXRPcmFjbGUAAAAACQEAAAAbc3RhdGljS2V5X2FjY0Jvb3N0ZXJBZGRyZXNzAAAAAAEAAAAPZ2V0UHJveHlTdGFraW5nAAAAAAkBAAAAFHRyeUdldFN0cmluZ0V4dGVybmFsAAAAAgkBAAAACWdldE9yYWNsZQAAAAAJAQAAAB9zdGF0aWNLZXlfcHJveHlTdGFraW5nQ29udHJhY3RzAAAAAAEAAAAOZ2V0TWFpbnRlbmFuY2UAAAAACQEAAAAUdHJ5R2V0U3RyaW5nRXh0ZXJuYWwAAAACCQEAAAAJZ2V0T3JhY2xlAAAAAAkBAAAAFXN0YXRpY0tleV9tYWludGVuYW5jZQAAAAABAAAAEmdldENmTWFzdGVyQWRkcmVzcwAAAAAJAQAAAAdBZGRyZXNzAAAAAQkAAlkAAAABCQEAAAAUdHJ5R2V0U3RyaW5nRXh0ZXJuYWwAAAACCQEAAAAJZ2V0T3JhY2xlAAAAAAkBAAAAGXN0YXRpY0tleV9jZk1hc3RlckFkZHJlc3MAAAAAAQAAABBnZXRGZWVBZ2dyZWdhdG9yAAAAAAkBAAAAB0FkZHJlc3MAAAABCQACWQAAAAEJAQAAABR0cnlHZXRTdHJpbmdFeHRlcm5hbAAAAAIJAQAAAAlnZXRPcmFjbGUAAAAACQEAAAAXc3RhdGljS2V5X2ZlZUFnZ3JlZ2F0b3IAAAAAAQAAABRnZXROZXdGYXJtaW5nQWRkcmVzcwAAAAAJAQAAAAdBZGRyZXNzAAAAAQkAAlkAAAABCQEAAAAUdHJ5R2V0U3RyaW5nRXh0ZXJuYWwAAAACCQEAAAAJZ2V0T3JhY2xlAAAAAAkBAAAAFHN0YXRpY0tleV9mYXJtaW5nTmV3AAAAAAAAAAANUmVmZXJlclJld2FyZAAAAAAAAAAABQEAAAAWY2hlY2tBZGRpdGlvbmFsUGF5bWVudAAAAAEA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dAAAAAAAAAAAZAQAAAAKZ2VuZXJhdGlvbgkAAS8AAAACCQEAAAAJdGFrZVJpZ2h0AAAAAgUAAAAJYXNzZXROYW1lAAAAAAAAAAACAAAAAAAAAAABCQEAAAAOZ2V0QXNzZXRSYXJpdHkAAAACBQAAAAdmYXJtR2VuBQAAAApnZW5lcmF0aW9uBAAAABF0b3RhbEZhcm1pbmdQb3dlcgkAAGQAAAACBQAAAAZyYXJpdHkJAABrAAAAAwUAAAAGcmFyaXR5BQAAAAlmYXJtQm9vc3QAAAAAAAAAAGQJAAUUAAAAAgUAAAAHZmFybUdlbgUAAAARdG90YWxGYXJtaW5nUG93ZXIJAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAAIAAAABAgAAAA1ub3QgdmFsaWQgTkZUAQAAAB1nZXRMYXN0S25vd25Bc3NldEZhcm1pbmdQb3dlcgAAAAIAAAAHYWRkcmVzcwAAAAdhc3NldElkCQEAAAANdHJ5R2V0SW50ZWdlcgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAIYWRkcmVzc18FAAAAB2FkZHJlc3MCAAAAB19hc3NldF8FAAAAB2Fzc2V0SWQCAAAADV9mYXJtaW5nUG93ZXIBAAAADGNhbGNJbnRlcmVzdAAAAAMAAAAQcHJldmlvdXNJbnRlcmVzdAAAABZwcmV2aW91c0ludGVyZXN0SGVpZ2h0AAAAEXRvdGFsRmFybWluZ1Bvd2VyCQAAZAAAAAIFAAAAEHByZXZpb3VzSW50ZXJlc3QJAABpAAAAAgkAAGgAAAACCQAAaAAAAAIFAAAABXNjYWxlCQEAAAARZ2V0UmV3YXJkUGVyQmxvY2sAAAAACQAAZQAAAAIFAAAABmhlaWdodAUAAAAWcHJldmlvdXNJbnRlcmVzdEhlaWdodAUAAAARdG90YWxGYXJtaW5nUG93ZXIBAAAAEmdldEN1cnJlbnRJbnRlcmVzdAAAAAADCQAAZgAAAAIJAQAAAA10cnlHZXRJbnRlZ2VyAAAAAQIAAAASdG90YWxfZmFybWluZ1Bvd2VyAAAAAAAAAAAABAAAABBwcmV2aW91c0ludGVyZXN0CQEAAAANdHJ5R2V0SW50ZWdlcgAAAAECAAAAF3RvdGFsX2xhc3RDaGVja0ludGVyZXN0BAAAABZwcmV2aW91c0ludGVyZXN0SGVpZ2h0CQEAAAANdHJ5R2V0SW50ZWdlcgAAAAECAAAAHXRvdGFsX2xhc3RDaGVja0ludGVyZXN0SGVpZ2h0BAAAABF0b3RhbEZhcm1pbmdQb3dlcgkBAAAADXRyeUdldEludGVnZXIAAAABAgAAABJ0b3RhbF9mYXJtaW5nUG93ZXIJAQAAAAxjYWxjSW50ZXJlc3QAAAADBQAAABBwcmV2aW91c0ludGVyZXN0BQAAABZwcmV2aW91c0ludGVyZXN0SGVpZ2h0BQAAABF0b3RhbEZhcm1pbmdQb3dlcgMJAQAAAAIhPQAAAAIJAQAAAA10cnlHZXRJbnRlZ2VyAAAAAQIAAAARdG90YWxfc3RhcnRIZWlnaHQAAAAAAAAAAAAJAQAAAA10cnlHZXRJbnRlZ2VyAAAAAQIAAAAXdG90YWxfbGFzdENoZWNrSW50ZXJlc3QJAAACAAAAAQIAAAAcZmFybWluZyBpcyBub3QgbGF1bmNoZWQsIHlldAEAAAAUY2FsY0Fzc2V0UmV3YXJkRGVsdGEAAAADAAAAB2FkZHJlc3MAAAAHYXNzZXRJZAAAABFhc3NldEZhcm1pbmdQb3dlcgQAAAAWbGFzdENoZWNrQXNzZXRJbnRlcmVzdAkBAAAADXRyeUdldEludGVnZXIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAACGFkZHJlc3NfBQAAAAdhZGRyZXNzAgAAAAdfYXNzZXRfBQAAAAdhc3NldElkAgAAABJfbGFzdENoZWNrSW50ZXJlc3QEAAAAD2N1cnJlbnRJbnRlcmVzdAkBAAAAEmdldEN1cnJlbnRJbnRlcmVzdAAAAAAJAABoAAAAAgUAAAARYXNzZXRGYXJtaW5nUG93ZXIJAABlAAAAAgUAAAAPY3VycmVudEludGVyZXN0BQAAABZsYXN0Q2hlY2tBc3NldEludGVyZXN0AQAAABRhZGRBc3NldElkVG9HZW5FbnRyeQAAAAIAAAAHYXNzZXRJZAAAAAhhc3NldEdlbgQAAAAMY3VycmVudFZhbHVlCQEAAAAMdHJ5R2V0U3RyaW5nAAAAAQkAASwAAAACCQABLAAAAAICAAAAB2Fzc2V0c18FAAAACGFzc2V0R2VuAgAAAAdfbG9ja2VkAwkAAAAAAAACBQAAAAxjdXJyZW50VmFsdWUCAAAAAAUAAAAHYXNzZXRJZAkAASwAAAACCQABLAAAAAIFAAAADGN1cnJlbnRWYWx1ZQIAAAABLAUAAAAHYXNzZXRJZAEAAAAOZ2V0U3Rha2VSZXN1bHQAAAAEAAAAB2FkZHJlc3MAAAAHYXNzZXRJZAAAABFhc3NldEZhcm1pbmdQb3dlcgAAAAh1bnN0YWtlcgQAAAAFYXNzZXQJAAJYAAAAAQUAAAAHYXNzZXRJZAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgIAAAASdG90YWxfZmFybWluZ1Bvd2VyCQAAZAAAAAIJAQAAAA10cnlHZXRJbnRlZ2VyAAAAAQIAAAASdG90YWxfZmFybWluZ1Bvd2VyBQAAABFhc3NldEZhcm1pbmdQb3dlcgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgIAAAAXdG90YWxfbGFzdENoZWNrSW50ZXJlc3QJAQAAABJnZXRDdXJyZW50SW50ZXJlc3QAAAAACQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACAgAAAB10b3RhbF9sYXN0Q2hlY2tJbnRlcmVzdEhlaWdodAUAAAAGaGVpZ2h0CQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAAEsAAAAAgkAASwAAAACAgAAAAZhc3NldF8FAAAABWFzc2V0AgAAAAZfb3duZXIFAAAAB2FkZHJlc3MJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAIYWRkcmVzc18FAAAAB2FkZHJlc3MCAAAAB19hc3NldF8FAAAABWFzc2V0AgAAAA1fZmFybWluZ1Bvd2VyBQAAABFhc3NldEZhcm1pbmdQb3dlcgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAAAhhZGRyZXNzXwUAAAAHYWRkcmVzcwIAAAAHX2Fzc2V0XwUAAAAFYXNzZXQCAAAAEl9sYXN0Q2hlY2tJbnRlcmVzdAkBAAAAEmdldEN1cnJlbnRJbnRlcmVzdAAAAAAJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAAAhhZGRyZXNzXwUAAAAHYWRkcmVzcwIAAAAHX2Fzc2V0XwUAAAAFYXNzZXQCAAAACV91bnN0YWtlcgUAAAAIdW5zdGFrZXIFAAAAA25pbAEAAAAQZ2V0VW5zdGFrZVJlc3VsdAAAAAYAAAAHYWRkcmVzcwAAAAdhc3NldElkAAAABWNvbG9yAAAABmNhbGxlcgAAAApyZWFsQ2FsbGVyAAAACWNsYWltRWdncwQAAAAGbG9ja2VkCQEAAAAIaXNMb2NrZWQAAAAAAwkAAAAAAAACBQAAAAZsb2NrZWQFAAAABmxvY2tlZAQAAAAFYXNzZXQJAAJYAAAAAQUAAAAHYXNzZXRJZAQAAAAIdW5zdGFrZXIJAQAAAAx0cnlHZXRTdHJpbmcAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAACGFkZHJlc3NfBQAAAAdhZGRyZXNzAgAAAAdfYXNzZXRfBQAAAAVhc3NldAIAAAAJX3Vuc3Rha2VyAwMJAQAAAAIhPQAAAAIFAAAACHVuc3Rha2VyAgAAAAAJAQAAAAIhPQAAAAIFAAAACHVuc3Rha2VyBQAAAApyZWFsQ2FsbGVyBwkAAAIAAAABAgAAAFdGVU46IEl0IHNlZW1zIGR1Y2sgd2FzIHN0YWtlZCB0aHJvdWggYSBkYXBwLCBub3QgZGlyZWN0bHksIHBsZWFzZSB1bnN0YWtlIHRocm91Z2ggZGFwcCEEAAAAEWFzc2V0RmFybWluZ1Bvd2VyCQEAAAAdZ2V0TGFzdEtub3duQXNzZXRGYXJtaW5nUG93ZXIAAAACBQAAAAdhZGRyZXNzBQAAAAVhc3NldAMJAQAAAAEhAAAAAQkAAGYAAAACBQAAABFhc3NldEZhcm1pbmdQb3dlcgAAAAAAAAAAAAkAAAIAAAABAgAAACpGR1U6IEFzc2V0IGZhcm1pbmcgcG93ZXIgbm90IGJpZ2dlciB0aGVuIDAEAAAAEGFzc2V0UmV3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", "height": 4133016, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 6vYJqpd2jaTMbX9Je6K8FFHPceyRrGrt3GLUbrg1Ah1Z Next: DV2KsVzPZGpDCzbPqxYyEQmzs4oxp3FeSWWQ3Ktwu6xM Diff:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let Scale = 100000000
4+let perchPrice = (100 * 1000000)
5+
6+let scale = 10000
7+
8+let scale2 = 1000000
59
610 func tryGetStringExternal (address,key) = match getString(address, key) {
711 case a: String =>
1317
1418 func tryGetString (key) = tryGetStringExternal(this, key)
1519
16-
17-func staticKey_refContractAddress () = "static_refContractAddress"
18-
19-
20-let keyGlobalLastInterest = "global_lastCheck_interest"
2120
2221 func staticKey_oracleAddress () = "static_oracleAddress"
2322
3130 func staticKey_breederAddress () = "static_breederAddress"
3231
3332
33+func staticKey_itemsAddress () = "static_itemsAddress"
34+
35+
36+func staticKey_metaRaceAddress () = "static_metaRaceAddress"
37+
38+
3439 func staticKey_accBoosterAddress () = "static_accBoosterAddress"
3540
3641
37-func staticKey_couponsAddress () = "static_couponsAddress"
42+func staticKey_proxyStakingContracts () = "static_proxyStakingContracts"
3843
3944
40-func staticKey_burnAddress () = "static_burnAddress"
45+func staticKey_maintenance () = "static_maintenance"
46+
47+
48+func staticKey_cfMasterAddress () = "static_cfMasterAddress"
4149
4250
4351 func staticKey_extraFee () = "static_extraFee"
4654 func staticKey_feeAggregator () = "static_feeAggregator"
4755
4856
49-let keyGlobalEarned = "global_earnings"
50-
51-func staticKey_perchFee () = "static_perchFee"
52-
53-
54-func staticKey_rebirthAddress () = "static_rebirthAddress"
55-
56-
57-func staticKey_turtleRebirthAddress () = "static_turtleRebirthAddress"
58-
59-
60-func staticKey_itemsAddress () = "static_itemsAddress"
61-
62-
63-func totalStakedKey () = "total_staked"
64-
65-
66-func staticKey_proxyStakingContracts () = "static_proxyStakingContracts"
57+func staticKey_farmingNew () = "static_farmingAddressNew"
6758
6859
6960 func getOracle () = Address(fromBase58String(tryGetString(staticKey_oracleAddress())))
70-
71-
72-func getRebirthAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_rebirthAddress())))
7361
7462
7563 func getEggAssetId () = fromBase58String(tryGetStringExternal(getOracle(), staticKey_eggAssetId()))
8169 func getBreederAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_breederAddress())))
8270
8371
72+func getItemsAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_itemsAddress())))
73+
74+
75+func getMetaraceAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_metaRaceAddress())))
76+
77+
8478 func getAccBoosterAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_accBoosterAddress())))
8579
8680
87-func getCouponsAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_couponsAddress())))
81+func getProxyStaking () = tryGetStringExternal(getOracle(), staticKey_proxyStakingContracts())
8882
8983
90-func getBurnAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_burnAddress())))
84+func getMaintenance () = tryGetStringExternal(getOracle(), staticKey_maintenance())
85+
86+
87+func getCfMasterAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_cfMasterAddress())))
9188
9289
9390 func getFeeAggregator () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_feeAggregator())))
9491
9592
96-func getRefContractAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_refContractAddress())))
97-
98-
99-func getTurtleRebirthAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_turtleRebirthAddress())))
100-
101-
102-func getItemsAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_itemsAddress())))
103-
104-
105-func getProxyStaking () = tryGetStringExternal(getOracle(), staticKey_proxyStakingContracts())
106-
107-
108-func keyLastCheckInterest (address,asset) = (((("address_" + address) + "_asset_") + asset) + "_lastCheckInterest")
109-
110-
111-func assetFarmingPower (address,asset) = (((("address_" + address) + "_asset_") + asset) + "_farmingPower")
112-
113-
114-func rewardClaimedKey (address,asset) = (((address + "_asset_") + asset) + "_claimed")
115-
116-
117-func totalStakedUserKey (address) = ("total_staked_" + address)
93+func getNewFarmingAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_farmingNew())))
11894
11995
12096 let RefererReward = 5
129105 }
130106
131107
108+func getRewardPerBlock () = 0
109+
110+
111+func isLocked () = if ((getMaintenance() != ""))
112+ then throw(getMaintenance())
113+ else 0
114+
115+
132116 func tryGetInteger (key) = match getInteger(this, key) {
133117 case b: Int =>
134118 b
135119 case _ =>
136120 0
137-}
138-
139-
140-func asInt (value) = match value {
141- case int: Int =>
142- int
143- case _ =>
144- throw("FAI: wrong type, expected: Int")
145-}
146-
147-
148-func asIntTuple (value) = match value {
149- case int: (Int, Int) =>
150- int
151- case _ =>
152- throw("FAI: wrong type, expected: (Int,Int)")
153-}
154-
155-
156-func handleStakingTopUp (amount) = {
157- let currentInterest = tryGetInteger(keyGlobalLastInterest)
158- let totalStakedAmount = tryGetInteger(totalStakedKey())
159- let interestDelta = if ((totalStakedAmount > 0))
160- then fraction(amount, Scale, totalStakedAmount)
161- else 0
162-[IntegerEntry(keyGlobalEarned, (tryGetInteger(keyGlobalEarned) + amount)), IntegerEntry(keyGlobalLastInterest, (currentInterest + interestDelta))]
163- }
164-
165-
166-func asString (value) = match value {
167- case string: String =>
168- string
169- case _ =>
170- throw("FAS: wrong type, expected: String")
171121 }
172122
173123
201151 }
202152
203153
204-func getAssetRarityComplete (isJackpot,assetName) = {
205- let rarity = if (isJackpot)
206- then 100
207- else {
208- let generation = take(takeRight(assetName, 2), 1)
209- let farmGen = asString(invoke(getBreederAddress(), "getGenFromName", [assetName], nil))
210- if ((farmGen == farmGen))
211- then getAssetRarity(farmGen, generation)
212- else throw("Strict value is not equal to itself.")
213- }
214- rarity
215- }
154+func asString (value) = match value {
155+ case string: String =>
156+ string
157+ case _ =>
158+ throw("FAS: wrong type, expected: String")
159+}
216160
217161
218-func updateFarmingPower (address,asset) = {
219- let totalStaked = tryGetInteger(totalStakedKey())
220- let totalStakedUser = tryGetInteger(totalStakedUserKey(address))
221- let currentFP = tryGetInteger(assetFarmingPower(address, asset))
222- let newFP = asIntTuple(invoke(this, "calculateFarmPower", [asset], nil))
223- if ((currentFP != 0))
224- then [IntegerEntry(totalStakedKey(), ((totalStaked - currentFP) + newFP._1)), IntegerEntry(totalStakedUserKey(address), ((totalStakedUser - currentFP) + newFP._1)), IntegerEntry(assetFarmingPower(address, asset), newFP._1), IntegerEntry("DEBUG_currentFP", currentFP), IntegerEntry("DEBUG_newFP", newFP._1)]
225- else nil
226- }
227-
228-
229-func claimStakingResult (address,asset,recalc) = {
230- let currentInterest = tryGetInteger(keyGlobalLastInterest)
231- let lastCheckInterest = tryGetInteger(keyLastCheckInterest(address, asset))
232- let stakedAmount = tryGetInteger(assetFarmingPower(address, asset))
233- let fpUpdate = if (recalc)
234- then updateFarmingPower(address, asset)
235- else nil
236- if ((fpUpdate == fpUpdate))
237- then {
238- let reward = if ((lastCheckInterest > 0))
239- then fraction((currentInterest - lastCheckInterest), stakedAmount, Scale)
240- else 0
241- $Tuple2(([ScriptTransfer(Address(fromBase58String(address)), reward, getEggAssetId()), IntegerEntry(keyLastCheckInterest(address, asset), currentInterest), IntegerEntry(rewardClaimedKey(address, asset), (tryGetInteger(rewardClaimedKey(address, asset)) + reward))] ++ fpUpdate), reward)
242- }
243- else throw("Strict value is not equal to itself.")
244- }
162+func asInt (value) = match value {
163+ case int: Int =>
164+ int
165+ case _ =>
166+ throw("FAI: wrong type, expected: Int")
167+}
245168
246169
247170 func asBoolean (value) = match value {
252175 }
253176
254177
178+func getAssetFarmingPower (assetId,address) = if (if ((value(assetInfo(assetId)).issuer == getBreederAddress()))
179+ then true
180+ else (value(assetInfo(assetId)).issuer == getIncubatorAddress()))
181+ then {
182+ let farmBoost = asInt(invoke(getItemsAddress(), "calculateFarmingPowerBoost", [toBase58String(assetId), address], nil))
183+ if ((farmBoost == farmBoost))
184+ then {
185+ let assetName = value(assetInfo(assetId)).name
186+ let isJackpot = (takeRight(value(assetName), 1) == "U")
187+ let farmGen = if (isJackpot)
188+ then ""
189+ else asString(invoke(getBreederAddress(), "getGenFromName", [assetName], nil))
190+ if ((farmGen == farmGen))
191+ then {
192+ let rarity = if (isJackpot)
193+ then 100
194+ else {
195+ let generation = take(takeRight(assetName, 2), 1)
196+ getAssetRarity(farmGen, generation)
197+ }
198+ let totalFarmingPower = (rarity + fraction(rarity, farmBoost, 100))
199+ $Tuple2(farmGen, totalFarmingPower)
200+ }
201+ else throw("Strict value is not equal to itself.")
202+ }
203+ else throw("Strict value is not equal to itself.")
204+ }
205+ else throw("not valid NFT")
206+
207+
208+func getLastKnownAssetFarmingPower (address,assetId) = tryGetInteger((((("address_" + address) + "_asset_") + assetId) + "_farmingPower"))
209+
210+
211+func calcInterest (previousInterest,previousInterestHeight,totalFarmingPower) = (previousInterest + (((scale * getRewardPerBlock()) * (height - previousInterestHeight)) / totalFarmingPower))
212+
213+
214+func getCurrentInterest () = if ((tryGetInteger("total_farmingPower") > 0))
215+ then {
216+ let previousInterest = tryGetInteger("total_lastCheckInterest")
217+ let previousInterestHeight = tryGetInteger("total_lastCheckInterestHeight")
218+ let totalFarmingPower = tryGetInteger("total_farmingPower")
219+ calcInterest(previousInterest, previousInterestHeight, totalFarmingPower)
220+ }
221+ else if ((tryGetInteger("total_startHeight") != 0))
222+ then tryGetInteger("total_lastCheckInterest")
223+ else throw("farming is not launched, yet")
224+
225+
226+func calcAssetRewardDelta (address,assetId,assetFarmingPower) = {
227+ let lastCheckAssetInterest = tryGetInteger((((("address_" + address) + "_asset_") + assetId) + "_lastCheckInterest"))
228+ let currentInterest = getCurrentInterest()
229+ (assetFarmingPower * (currentInterest - lastCheckAssetInterest))
230+ }
231+
232+
233+func addAssetIdToGenEntry (assetId,assetGen) = {
234+ let currentValue = tryGetString((("assets_" + assetGen) + "_locked"))
235+ if ((currentValue == ""))
236+ then assetId
237+ else ((currentValue + ",") + assetId)
238+ }
239+
240+
241+func getStakeResult (address,assetId,assetFarmingPower,unstaker) = {
242+ let asset = toBase58String(assetId)
243+[IntegerEntry("total_farmingPower", (tryGetInteger("total_farmingPower") + assetFarmingPower)), IntegerEntry("total_lastCheckInterest", getCurrentInterest()), IntegerEntry("total_lastCheckInterestHeight", height), StringEntry((("asset_" + asset) + "_owner"), address), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_farmingPower"), assetFarmingPower), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_lastCheckInterest"), getCurrentInterest()), StringEntry((((("address_" + address) + "_asset_") + asset) + "_unstaker"), unstaker)]
244+ }
245+
246+
247+func getUnstakeResult (address,assetId,color,caller,realCaller,claimEggs) = {
248+ let locked = isLocked()
249+ if ((locked == locked))
250+ then {
251+ let asset = toBase58String(assetId)
252+ let unstaker = tryGetString((((("address_" + address) + "_asset_") + asset) + "_unstaker"))
253+ if (if ((unstaker != ""))
254+ then (unstaker != realCaller)
255+ else false)
256+ then throw("FUN: It seems duck was staked throuh a dapp, not directly, please unstake through dapp!")
257+ else {
258+ let assetFarmingPower = getLastKnownAssetFarmingPower(address, asset)
259+ if (!((assetFarmingPower > 0)))
260+ then throw("FGU: Asset farming power not bigger then 0")
261+ else {
262+ let assetRewardDelta = calcAssetRewardDelta(address, asset, assetFarmingPower)
263+ let farmedAmount = (assetRewardDelta + tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount")))
264+ let withdrawnAmount = tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"))
265+ let reward = ((farmedAmount - withdrawnAmount) / (scale * 100))
266+ let isWithoutPerch = tryGetBoolean((((("address_" + address) + "_asset_") + asset) + "_without_perch"))
267+ let rewardAfterSickNess = reward
268+ let appendPerches = if (isWithoutPerch)
269+ then [DeleteEntry((((("address_" + address) + "_asset_") + asset) + "_without_perch"))]
270+ else [IntegerEntry(((("address_" + address) + "_perchesAvailable_") + color), (tryGetInteger(((("address_" + address) + "_perchesAvailable_") + color)) + 1))]
271+ let sendTx = if (claimEggs)
272+ then $Tuple2([ScriptTransfer(caller, (rewardAfterSickNess * 1000000), getEggAssetId())], (rewardAfterSickNess * 1000000))
273+ else $Tuple2(nil, 0)
274+ $Tuple2(((([IntegerEntry("total_farmingPower", (tryGetInteger("total_farmingPower") - assetFarmingPower)), IntegerEntry("total_lastCheckInterest", getCurrentInterest()), IntegerEntry("total_lastCheckInterestHeight", height), DeleteEntry((("asset_" + asset) + "_owner")), DeleteEntry((((("address_" + address) + "_asset_") + asset) + "_unstaker")), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_farmingPower"), 0), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_lastCheckInterest"), getCurrentInterest()), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"), (withdrawnAmount + (rewardAfterSickNess * scale2))), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount"), (tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount")) + assetRewardDelta))] ++ appendPerches) ++ [ScriptTransfer(caller, 1, assetId)]) ++ sendTx._1), sendTx._2)
275+ }
276+ }
277+ }
278+ else throw("Strict value is not equal to itself.")
279+ }
280+
281+
255282 func calculatePerchPrice (address) = {
256283 let hasArtefactStaked = tryGetStringExternal(getAccBoosterAddress(), (("ART-XMISTL_" + address) + "_owner"))
257- let perchPrice = getIntegerValue(getOracle(), staticKey_perchFee())
258284 if ((hasArtefactStaked == ""))
259285 then perchPrice
260286 else ((perchPrice / 10) * 9)
268294 }
269295
270296
297+func unstakeNFTInternal (asset,i,claimEgg) = {
298+ let assetId = fromBase58String(asset)
299+ let realCaller = toString(i.caller)
300+ let address = if (isProxyStakingSc(toString(i.caller)))
301+ then toString(i.originCaller)
302+ else realCaller
303+ let color = takeRight(value(assetInfo(assetId)).name, 1)
304+ if ((color == "U"))
305+ then throw("FUN: use another function to unstake Jackpot NFT")
306+ else {
307+ let result = getUnstakeResult(address, assetId, color, i.caller, realCaller, claimEgg)
308+ result
309+ }
310+ }
311+
312+
313+func unstakeJackpotInternal (asset,i,claimEgg) = {
314+ let assetId = fromBase58String(asset)
315+ let realCaller = toString(i.caller)
316+ let address = if (isProxyStakingSc(toString(i.caller)))
317+ then toString(i.originCaller)
318+ else realCaller
319+ let color = tryGetString((((("address_" + address) + "_asset_") + asset) + "_perchColor"))
320+ if ((takeRight(value(value(assetInfo(assetId)).name), 1) != "U"))
321+ then throw("jackpot only")
322+ else {
323+ let result = getUnstakeResult(address, assetId, color, i.caller, realCaller, claimEgg)
324+ result
325+ }
326+ }
327+
328+
329+func getBool (key) = match getBoolean(this, key) {
330+ case b: Boolean =>
331+ b
332+ case _ =>
333+ false
334+}
335+
336+
337+func isTestEnv () = getBool("TESTENV")
338+
339+
271340 @Callable(i)
272-func calculateFarmPower (assetId) = if (!(if ((value(assetInfo(fromBase58String(assetId))).issuer == getBreederAddress()))
273- then true
274- else (value(assetInfo(fromBase58String(assetId))).issuer == getIncubatorAddress())))
275- then throw("This does not seem like a valid Duck!")
276- else {
277- let assetName = value(assetInfo(fromBase58String(assetId))).name
278- let gen = takeRight(assetName, 1)
279- let isJackpot = (takeRight(assetName, 1) == "U")
280- let rarity = getAssetRarityComplete(isJackpot, assetName)
281- let genotype = split(dropRight(drop(assetName, 5), 3), "")
282- func uniqueArrayFilter (accum,nextGen) = if (!(containsElement(accum, nextGen)))
283- then (accum :+ nextGen)
284- else accum
285-
286- let uniqueList = {
287- let $l = genotype
288- let $s = size($l)
289- let $acc0 = nil
290- func $f0_1 ($a,$i) = if (($i >= $s))
291- then $a
292- else uniqueArrayFilter($a, $l[$i])
293-
294- func $f0_2 ($a,$i) = if (($i >= $s))
295- then $a
296- else throw("List size exceeds 8")
297-
298- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8)
299- }
300- let totalGenes = if ((gen == "U"))
301- then 8
302- else size(uniqueList)
303- let power = pow(15, 1, totalGenes, 0, 2, DOWN)
304- let multiplier = (((height - 3750000) * 100) / (((60 * 24) * 30) * 3))
305- let basePower = tryGetInteger((assetId + "_basePower"))
306- let finalPower = if ((basePower > 0))
307- then basePower
308- else ((power * multiplier) / 100)
309- let finalPowerRarity = ((finalPower * rarity) / 100)
310- let farmBoost = asInt(invoke(getItemsAddress(), "calculateFarmingPowerBoost", [assetId, toString(i.originCaller)], nil))
311- if ((farmBoost == farmBoost))
312- then {
313- let finalPowerRarityBoost = (finalPowerRarity + ((finalPowerRarity * farmBoost) / 100))
314- $Tuple2([IntegerEntry(("DEBUG_" + assetName), finalPower), IntegerEntry(("DEBUG_RARITY" + assetName), rarity), IntegerEntry(("DEBUG_FPRARITY_" + assetName), finalPowerRarity), IntegerEntry(("DEBUG_FARMBOOST_" + assetName), farmBoost), IntegerEntry(("DEBUG_FPRARITYBOOST_" + assetName), finalPowerRarityBoost), IntegerEntry(("DEBUG_POWER_" + assetName), power), IntegerEntry(("DEBUG_BASEPOWER_" + assetName), basePower), IntegerEntry(("DEBUG_COEFFICIENT_" + assetName), multiplier), IntegerEntry(("DEBUG_BOOST_" + assetName), farmBoost)], $Tuple2(finalPowerRarityBoost, finalPower))
315- }
316- else throw("Strict value is not equal to itself.")
317- }
341+func removePerches (address) = if ((i.caller != getNewFarmingAddress()))
342+ then throw("FRP: admin only")
343+ else [IntegerEntry((("address_" + address) + "_perchesAvailable_R"), 0), IntegerEntry((("address_" + address) + "_perchesAvailable_G"), 0), IntegerEntry((("address_" + address) + "_perchesAvailable_B"), 0), IntegerEntry((("address_" + address) + "_perchesAvailable_U"), 0)]
318344
319345
320346
326352
327353
328354 @Callable(i)
329-func buyPerch (colorI,refererAddress) = {
330- let validPayment = checkAdditionalPayment(i.payments[0])
355+func init () = if ((i.caller != this))
356+ then throw("FI: admin only")
357+ else [IntegerEntry("total_startHeight", height)]
358+
359+
360+
361+@Callable(i)
362+func buyPerch (colorI,refererAddress) = throw("FBN: function is disabled, migration to new sc ongoing")
363+
364+
365+
366+@Callable(i)
367+func addFreePerch (address,color) = throw("FBN: function is disabled, migration to new sc ongoing")
368+
369+
370+
371+@Callable(i)
372+func stakeNFT () = throw("FBN: function is disabled, migration to new sc ongoing")
373+
374+
375+
376+@Callable(i)
377+func stakeNFTWithoutPerch () = throw("FBN: function is disabled, migration to new sc ongoing")
378+
379+
380+
381+@Callable(i)
382+func unstakeNFT (asset) = {
383+ let validPayment = if ((i.caller == getMetaraceAddress()))
384+ then nil
385+ else checkAdditionalPayment(i.payments[0])
331386 if ((validPayment == validPayment))
332387 then {
333- let color = if ((colorI == "U"))
334- then "B"
335- else colorI
336- if ((0 > value(indexOf(["B", "R", "G", "Y"], color))))
337- then throw("you need to set color properly")
338- else {
339- let exactPrice = calculatePerchPrice(toString(i.caller))
340- let leftToPay = if ((i.originCaller == i.caller))
341- then {
342- let amountPaidByCoupons = asInt(invoke(getCouponsAddress(), "useCoupons", [exactPrice], nil))
343- if ((amountPaidByCoupons == amountPaidByCoupons))
344- then (exactPrice - amountPaidByCoupons)
345- else throw("Strict value is not equal to itself.")
346- }
347- else exactPrice
348- let firstPayment = if ((size(i.payments) == 2))
349- then value(i.payments[1])
350- else value(i.payments[0])
351- if ((firstPayment.assetId != getEggAssetId()))
352- then throw(("FBP: You can attach only EGG tokens with the following asset id: " + toBase58String(getEggAssetId())))
353- else if ((firstPayment.amount != leftToPay))
354- then throw(((("FBP: To buy a perch you currently need the following amount of EGGlets: " + toString(leftToPay)) + " ") + toString(i.caller)))
355- else {
356- let refererRewardForPerch = fraction(leftToPay, 5, 100)
357- let refCall = asBoolean(invoke(getRefContractAddress(), "refPayment", [refererAddress], [AttachedPayment(getEggAssetId(), refererRewardForPerch)]))
358- if ((refCall == refCall))
359- then {
360- let toBurn = if (refCall)
361- then (leftToPay - refererRewardForPerch)
362- else leftToPay
363- let burnCall = invoke(getBurnAddress(), "burnAttachedPayments", nil, [AttachedPayment(getEggAssetId(), toBurn)])
364- if ((burnCall == burnCall))
365- then {
366- let perchAmountKey = ((("address_" + toString(i.caller)) + "_perchesAvailable_") + color)
367- let perchAmount = tryGetInteger(perchAmountKey)
368- ([IntegerEntry(perchAmountKey, (perchAmount + 1))] ++ validPayment)
369- }
370- else throw("Strict value is not equal to itself.")
371- }
372- else throw("Strict value is not equal to itself.")
373- }
374- }
388+ let result = unstakeNFTInternal(asset, i, true)
389+ $Tuple2((result._1 ++ validPayment), result._2)
375390 }
376391 else throw("Strict value is not equal to itself.")
377392 }
379394
380395
381396 @Callable(i)
382-func addFreePerch (address,color,amount) = if ((0 > value(indexOf(["B", "R", "G", "Y"], color))))
383- then throw("you need to set color properly")
384- else if (if (if ((i.caller != getRebirthAddress()))
385- then (i.caller != getTurtleRebirthAddress())
386- else false)
387- then (i.caller != this)
388- else false)
389- then throw("rebirth and admin only")
390- else {
391- let perchAmountKey = ((("address_" + address) + "_perchesAvailable_") + color)
392- let perchAmount = tryGetInteger(perchAmountKey)
393- $Tuple2([IntegerEntry(perchAmountKey, (perchAmount + amount))], "")
394- }
397+func unstakeNFTWithoutClaim (asset) = unstakeNFTInternal(asset, i, false)
395398
396399
397400
398401 @Callable(i)
399-func migratePerches (address) = {
400- let oldFarming = addressFromStringValue(tryGetStringExternal(getOracle(), "static_farmingAddress"))
401- func tryGetIntegerOldFarming (key) = match getInteger(oldFarming, key) {
402- case b: Int =>
403- b
404- case _ =>
405- 0
406- }
407-
408- let perchAmountB = tryGetIntegerOldFarming((("address_" + address) + "_perchesAvailable_B"))
409- let perchAmountR = tryGetIntegerOldFarming((("address_" + address) + "_perchesAvailable_R"))
410- let perchAmountG = tryGetIntegerOldFarming((("address_" + address) + "_perchesAvailable_G"))
411- let perchAmountY = tryGetIntegerOldFarming((("address_" + address) + "_perchesAvailable_Y"))
412- let perchAmountBInvoke = invoke(this, "addFreePerch", [address, "B", perchAmountB], nil)
413- let perchAmountRInvoke = invoke(this, "addFreePerch", [address, "R", perchAmountR], nil)
414- let perchAmountGInvoke = invoke(this, "addFreePerch", [address, "G", perchAmountG], nil)
415- let perchAmountYInvoke = invoke(this, "addFreePerch", [address, "Y", perchAmountY], nil)
416- let invokePerchesDelete = invoke(oldFarming, "removePerches", [address], nil)
417- nil
418- }
402+func stakeJackpot (color) = throw("FBN: function is disabled, migration to new sc ongoing")
419403
420404
421405
422406 @Callable(i)
423-func stakeNFT (jColor,usePerchOrigin,stakeWithoutPerch) = if (true)
424- then throw("Staking is disabled")
425- else if (if (stakeWithoutPerch)
426- then !(isProxyStakingSc(toString(i.caller)))
427- else false)
428- then throw("You can't stake without a perch")
429- else {
430- let validPayment = checkAdditionalPayment(i.payments[0])
431- if ((validPayment == validPayment))
432- then {
433- let pmt = value(i.payments[1])
434- let assetId = value(pmt.assetId)
435- let assetName = value(value(assetInfo(assetId)).name)
436- let isJackpot = (takeRight(assetName, 1) == "U")
437- let address = toString(i.caller)
438- let perchAddress = if (usePerchOrigin)
439- then toString(i.originCaller)
440- else address
441- let rarity = getAssetRarityComplete(isJackpot, assetName)
442- let perches = if (stakeWithoutPerch)
443- then nil
444- else {
445- let color = if (isJackpot)
446- then jColor
447- else takeRight(assetName, 1)
448- let availablePerches = tryGetInteger(((("address_" + perchAddress) + "_perchesAvailable_") + color))
449- if ((0 >= availablePerches))
450- then throw(("no perches available for the color " + color))
451- else [IntegerEntry(((("address_" + perchAddress) + "_perchesAvailable_") + color), (availablePerches - 1)), StringEntry((((("address_" + address) + "_asset_") + toBase58String(assetId)) + "_perchColor"), color)]
452- }
453- if ((perches == perches))
454- then if ((pmt.amount != 1))
455- then throw("NFT is not attached")
456- else {
457- let farmingPower = asIntTuple(invoke(this, "calculateFarmPower", [toBase58String(assetId)], nil))
458- if ((farmingPower == farmingPower))
459- then {
460- let result = claimStakingResult(address, toBase58String(assetId), false)
461- if ((result == result))
462- then ((([IntegerEntry(totalStakedKey(), (tryGetInteger(totalStakedKey()) + farmingPower._1)), IntegerEntry(totalStakedUserKey(address), (tryGetInteger(totalStakedUserKey(address)) + farmingPower._1)), StringEntry((toBase58String(assetId) + "_owner"), address), BooleanEntry((toBase58String(assetId) + "_use_origin"), usePerchOrigin), StringEntry((toBase58String(assetId) + "_original_caller"), toString(i.originCaller)), IntegerEntry(assetFarmingPower(address, toBase58String(assetId)), farmingPower._1), IntegerEntry((toBase58String(assetId) + "_basePower"), farmingPower._2), BooleanEntry((toBase58String(assetId) + "_without_perch"), stakeWithoutPerch)] ++ validPayment) ++ perches) ++ result._1)
463- else throw("Strict value is not equal to itself.")
464- }
465- else throw("Strict value is not equal to itself.")
466- }
467- else throw("Strict value is not equal to itself.")
468- }
469- else throw("Strict value is not equal to itself.")
470- }
471-
472-
473-
474-@Callable(i)
475-func unstakeNFT (asset) = {
476- let address = toString(i.caller)
477- let result = claimStakingResult(address, asset, false)
478- if ((result == result))
407+func unstakeJackpot (asset) = {
408+ let validPayment = checkAdditionalPayment(i.payments[0])
409+ if ((validPayment == validPayment))
479410 then {
480- let validPayment = checkAdditionalPayment(i.payments[0])
481- if ((validPayment == validPayment))
482- then {
483- let color = tryGetString((((("address_" + address) + "_asset_") + asset) + "_perchColor"))
484- let withoutPerch = tryGetBoolean((asset + "_without_perch"))
485- let perches = if (withoutPerch)
486- then nil
487- else {
488- let usePerchOrigin = tryGetBoolean((asset + "_use_origin"))
489- let perchOwner = if (usePerchOrigin)
490- then toString(i.originCaller)
491- else address
492-[IntegerEntry(((("address_" + address) + "_perchesAvailable_") + color), (tryGetInteger(((("address_" + address) + "_perchesAvailable_") + color)) + 1))]
493- }
494- if ((perches == perches))
495- then {
496- let assetFP = tryGetInteger(assetFarmingPower(address, asset))
497- if ((assetFP == assetFP))
498- then $Tuple2(((([IntegerEntry(totalStakedKey(), (tryGetInteger(totalStakedKey()) - assetFP)), IntegerEntry(totalStakedUserKey(address), (tryGetInteger(totalStakedUserKey(address)) - assetFP)), DeleteEntry((asset + "_owner")), DeleteEntry(assetFarmingPower(address, asset)), DeleteEntry((((("address_" + address) + "_asset_") + asset) + "_perchColor")), DeleteEntry((asset + "_original_caller")), DeleteEntry((asset + "_use_origin")), DeleteEntry((asset + "_without_perch")), ScriptTransfer(Address(fromBase58String(address)), 1, fromBase58String(asset))] ++ validPayment) ++ perches) ++ result._1), result._2)
499- else throw("Strict value is not equal to itself.")
500- }
501- else throw("Strict value is not equal to itself.")
502- }
503- else throw("Strict value is not equal to itself.")
411+ let result = unstakeJackpotInternal(asset, i, true)
412+ $Tuple2((result._1 ++ validPayment), result._2)
504413 }
505414 else throw("Strict value is not equal to itself.")
506415 }
508417
509418
510419 @Callable(i)
511-func topUpReward () = {
512- let firstPayment = value(i.payments[0])
513- if ((firstPayment.assetId != getEggAssetId()))
514- then throw(("FBP: You can attach only EGG tokens with the following asset id: " + toBase58String(getEggAssetId())))
515- else {
516- let resHandleStaking = handleStakingTopUp(firstPayment.amount)
517- $Tuple2(resHandleStaking, true)
518- }
519- }
420+func unstakeJackpotWithoutClaimEgg (asset) = unstakeJackpotInternal(asset, i, false)
520421
521422
522423
523424 @Callable(i)
524-func claimReward (assetId) = {
525- let validPayment = checkAdditionalPayment(i.payments[0])
526- if ((validPayment == validPayment))
527- then if ((tryGetString((assetId + "_owner")) != toString(i.caller)))
528- then throw("You don't own this duck!!")
529- else if ((size(i.payments) > 1))
530- then throw("Please don't add extra payments")
531- else {
532- let result = claimStakingResult(toString(i.caller), assetId, true)
533- $Tuple2((validPayment ++ result._1), result._2)
425+func claimReward (asset) = {
426+ let locked = isLocked()
427+ if ((locked == locked))
428+ then {
429+ let validPayment = if ((i.originCaller == getCfMasterAddress()))
430+ then nil
431+ else checkAdditionalPayment(i.payments[0])
432+ if ((validPayment == validPayment))
433+ then {
434+ let address = if ((i.originCaller == getCfMasterAddress()))
435+ then toString(i.caller)
436+ else toString(i.originCaller)
437+ let assetId = fromBase58String(asset)
438+ let assetFarmingPower = getLastKnownAssetFarmingPower(address, asset)
439+ let assetRewardDelta = calcAssetRewardDelta(address, asset, assetFarmingPower)
440+ let farmedAmount = (assetRewardDelta + tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount")))
441+ let withdrawnAmount = tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"))
442+ let reward = ((farmedAmount - withdrawnAmount) / (scale * 100))
443+ if ((0 >= reward))
444+ then throw("FCR: you have no EGGs to withdraw")
445+ else $Tuple2(([IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"), (tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount")) + (reward * scale2))), ScriptTransfer(Address(fromBase58String(address)), (reward * 1000000), getEggAssetId())] ++ validPayment), (reward * 1000000))
534446 }
447+ else throw("Strict value is not equal to itself.")
448+ }
535449 else throw("Strict value is not equal to itself.")
536450 }
537451
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let Scale = 100000000
4+let perchPrice = (100 * 1000000)
5+
6+let scale = 10000
7+
8+let scale2 = 1000000
59
610 func tryGetStringExternal (address,key) = match getString(address, key) {
711 case a: String =>
812 a
913 case _ =>
1014 ""
1115 }
1216
1317
1418 func tryGetString (key) = tryGetStringExternal(this, key)
1519
16-
17-func staticKey_refContractAddress () = "static_refContractAddress"
18-
19-
20-let keyGlobalLastInterest = "global_lastCheck_interest"
2120
2221 func staticKey_oracleAddress () = "static_oracleAddress"
2322
2423
2524 func staticKey_eggAssetId () = "static_eggAssetId"
2625
2726
2827 func staticKey_incubatorAddress () = "static_incubatorAddress"
2928
3029
3130 func staticKey_breederAddress () = "static_breederAddress"
3231
3332
33+func staticKey_itemsAddress () = "static_itemsAddress"
34+
35+
36+func staticKey_metaRaceAddress () = "static_metaRaceAddress"
37+
38+
3439 func staticKey_accBoosterAddress () = "static_accBoosterAddress"
3540
3641
37-func staticKey_couponsAddress () = "static_couponsAddress"
42+func staticKey_proxyStakingContracts () = "static_proxyStakingContracts"
3843
3944
40-func staticKey_burnAddress () = "static_burnAddress"
45+func staticKey_maintenance () = "static_maintenance"
46+
47+
48+func staticKey_cfMasterAddress () = "static_cfMasterAddress"
4149
4250
4351 func staticKey_extraFee () = "static_extraFee"
4452
4553
4654 func staticKey_feeAggregator () = "static_feeAggregator"
4755
4856
49-let keyGlobalEarned = "global_earnings"
50-
51-func staticKey_perchFee () = "static_perchFee"
52-
53-
54-func staticKey_rebirthAddress () = "static_rebirthAddress"
55-
56-
57-func staticKey_turtleRebirthAddress () = "static_turtleRebirthAddress"
58-
59-
60-func staticKey_itemsAddress () = "static_itemsAddress"
61-
62-
63-func totalStakedKey () = "total_staked"
64-
65-
66-func staticKey_proxyStakingContracts () = "static_proxyStakingContracts"
57+func staticKey_farmingNew () = "static_farmingAddressNew"
6758
6859
6960 func getOracle () = Address(fromBase58String(tryGetString(staticKey_oracleAddress())))
70-
71-
72-func getRebirthAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_rebirthAddress())))
7361
7462
7563 func getEggAssetId () = fromBase58String(tryGetStringExternal(getOracle(), staticKey_eggAssetId()))
7664
7765
7866 func getIncubatorAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_incubatorAddress())))
7967
8068
8169 func getBreederAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_breederAddress())))
8270
8371
72+func getItemsAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_itemsAddress())))
73+
74+
75+func getMetaraceAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_metaRaceAddress())))
76+
77+
8478 func getAccBoosterAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_accBoosterAddress())))
8579
8680
87-func getCouponsAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_couponsAddress())))
81+func getProxyStaking () = tryGetStringExternal(getOracle(), staticKey_proxyStakingContracts())
8882
8983
90-func getBurnAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_burnAddress())))
84+func getMaintenance () = tryGetStringExternal(getOracle(), staticKey_maintenance())
85+
86+
87+func getCfMasterAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_cfMasterAddress())))
9188
9289
9390 func getFeeAggregator () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_feeAggregator())))
9491
9592
96-func getRefContractAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_refContractAddress())))
97-
98-
99-func getTurtleRebirthAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_turtleRebirthAddress())))
100-
101-
102-func getItemsAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_itemsAddress())))
103-
104-
105-func getProxyStaking () = tryGetStringExternal(getOracle(), staticKey_proxyStakingContracts())
106-
107-
108-func keyLastCheckInterest (address,asset) = (((("address_" + address) + "_asset_") + asset) + "_lastCheckInterest")
109-
110-
111-func assetFarmingPower (address,asset) = (((("address_" + address) + "_asset_") + asset) + "_farmingPower")
112-
113-
114-func rewardClaimedKey (address,asset) = (((address + "_asset_") + asset) + "_claimed")
115-
116-
117-func totalStakedUserKey (address) = ("total_staked_" + address)
93+func getNewFarmingAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_farmingNew())))
11894
11995
12096 let RefererReward = 5
12197
12298 func checkAdditionalPayment (payment) = if (isDefined(payment.assetId))
12399 then throw("FCAP: Please attach waves")
124100 else {
125101 let feeAmount = getIntegerValue(getOracle(), staticKey_extraFee())
126102 if ((payment.amount != feeAmount))
127103 then throw((("FCAP: Please attach exactly " + toString(feeAmount)) + " amount of wavelets"))
128104 else [ScriptTransfer(getFeeAggregator(), feeAmount, unit)]
129105 }
130106
131107
108+func getRewardPerBlock () = 0
109+
110+
111+func isLocked () = if ((getMaintenance() != ""))
112+ then throw(getMaintenance())
113+ else 0
114+
115+
132116 func tryGetInteger (key) = match getInteger(this, key) {
133117 case b: Int =>
134118 b
135119 case _ =>
136120 0
137-}
138-
139-
140-func asInt (value) = match value {
141- case int: Int =>
142- int
143- case _ =>
144- throw("FAI: wrong type, expected: Int")
145-}
146-
147-
148-func asIntTuple (value) = match value {
149- case int: (Int, Int) =>
150- int
151- case _ =>
152- throw("FAI: wrong type, expected: (Int,Int)")
153-}
154-
155-
156-func handleStakingTopUp (amount) = {
157- let currentInterest = tryGetInteger(keyGlobalLastInterest)
158- let totalStakedAmount = tryGetInteger(totalStakedKey())
159- let interestDelta = if ((totalStakedAmount > 0))
160- then fraction(amount, Scale, totalStakedAmount)
161- else 0
162-[IntegerEntry(keyGlobalEarned, (tryGetInteger(keyGlobalEarned) + amount)), IntegerEntry(keyGlobalLastInterest, (currentInterest + interestDelta))]
163- }
164-
165-
166-func asString (value) = match value {
167- case string: String =>
168- string
169- case _ =>
170- throw("FAS: wrong type, expected: String")
171121 }
172122
173123
174124 func tryGetBoolean (key) = match getBoolean(this, key) {
175125 case b: Boolean =>
176126 b
177127 case _ =>
178128 false
179129 }
180130
181131
182132 func tryGetBooleanExternal (address,key) = match getBoolean(address, key) {
183133 case b: Boolean =>
184134 b
185135 case _ =>
186136 false
187137 }
188138
189139
190140 func getAssetOrigin (generation) = if ((generation == "G"))
191141 then getIncubatorAddress()
192142 else getBreederAddress()
193143
194144
195145 func getAssetRarity (genotype,generation) = {
196146 let quantity = valueOrErrorMessage(getInteger(getAssetOrigin(generation), (("stats_" + genotype) + "_quantity")), (("stats_" + genotype) + "_quantity not found"))
197147 let power = pow((10000 / quantity), 4, 5, 1, 2, FLOOR)
198148 if ((power > 0))
199149 then power
200150 else 2
201151 }
202152
203153
204-func getAssetRarityComplete (isJackpot,assetName) = {
205- let rarity = if (isJackpot)
206- then 100
207- else {
208- let generation = take(takeRight(assetName, 2), 1)
209- let farmGen = asString(invoke(getBreederAddress(), "getGenFromName", [assetName], nil))
210- if ((farmGen == farmGen))
211- then getAssetRarity(farmGen, generation)
212- else throw("Strict value is not equal to itself.")
213- }
214- rarity
215- }
154+func asString (value) = match value {
155+ case string: String =>
156+ string
157+ case _ =>
158+ throw("FAS: wrong type, expected: String")
159+}
216160
217161
218-func updateFarmingPower (address,asset) = {
219- let totalStaked = tryGetInteger(totalStakedKey())
220- let totalStakedUser = tryGetInteger(totalStakedUserKey(address))
221- let currentFP = tryGetInteger(assetFarmingPower(address, asset))
222- let newFP = asIntTuple(invoke(this, "calculateFarmPower", [asset], nil))
223- if ((currentFP != 0))
224- then [IntegerEntry(totalStakedKey(), ((totalStaked - currentFP) + newFP._1)), IntegerEntry(totalStakedUserKey(address), ((totalStakedUser - currentFP) + newFP._1)), IntegerEntry(assetFarmingPower(address, asset), newFP._1), IntegerEntry("DEBUG_currentFP", currentFP), IntegerEntry("DEBUG_newFP", newFP._1)]
225- else nil
226- }
227-
228-
229-func claimStakingResult (address,asset,recalc) = {
230- let currentInterest = tryGetInteger(keyGlobalLastInterest)
231- let lastCheckInterest = tryGetInteger(keyLastCheckInterest(address, asset))
232- let stakedAmount = tryGetInteger(assetFarmingPower(address, asset))
233- let fpUpdate = if (recalc)
234- then updateFarmingPower(address, asset)
235- else nil
236- if ((fpUpdate == fpUpdate))
237- then {
238- let reward = if ((lastCheckInterest > 0))
239- then fraction((currentInterest - lastCheckInterest), stakedAmount, Scale)
240- else 0
241- $Tuple2(([ScriptTransfer(Address(fromBase58String(address)), reward, getEggAssetId()), IntegerEntry(keyLastCheckInterest(address, asset), currentInterest), IntegerEntry(rewardClaimedKey(address, asset), (tryGetInteger(rewardClaimedKey(address, asset)) + reward))] ++ fpUpdate), reward)
242- }
243- else throw("Strict value is not equal to itself.")
244- }
162+func asInt (value) = match value {
163+ case int: Int =>
164+ int
165+ case _ =>
166+ throw("FAI: wrong type, expected: Int")
167+}
245168
246169
247170 func asBoolean (value) = match value {
248171 case boolean: Boolean =>
249172 boolean
250173 case _ =>
251174 throw("FAB: wrong type, expected: Boolean")
252175 }
253176
254177
178+func getAssetFarmingPower (assetId,address) = if (if ((value(assetInfo(assetId)).issuer == getBreederAddress()))
179+ then true
180+ else (value(assetInfo(assetId)).issuer == getIncubatorAddress()))
181+ then {
182+ let farmBoost = asInt(invoke(getItemsAddress(), "calculateFarmingPowerBoost", [toBase58String(assetId), address], nil))
183+ if ((farmBoost == farmBoost))
184+ then {
185+ let assetName = value(assetInfo(assetId)).name
186+ let isJackpot = (takeRight(value(assetName), 1) == "U")
187+ let farmGen = if (isJackpot)
188+ then ""
189+ else asString(invoke(getBreederAddress(), "getGenFromName", [assetName], nil))
190+ if ((farmGen == farmGen))
191+ then {
192+ let rarity = if (isJackpot)
193+ then 100
194+ else {
195+ let generation = take(takeRight(assetName, 2), 1)
196+ getAssetRarity(farmGen, generation)
197+ }
198+ let totalFarmingPower = (rarity + fraction(rarity, farmBoost, 100))
199+ $Tuple2(farmGen, totalFarmingPower)
200+ }
201+ else throw("Strict value is not equal to itself.")
202+ }
203+ else throw("Strict value is not equal to itself.")
204+ }
205+ else throw("not valid NFT")
206+
207+
208+func getLastKnownAssetFarmingPower (address,assetId) = tryGetInteger((((("address_" + address) + "_asset_") + assetId) + "_farmingPower"))
209+
210+
211+func calcInterest (previousInterest,previousInterestHeight,totalFarmingPower) = (previousInterest + (((scale * getRewardPerBlock()) * (height - previousInterestHeight)) / totalFarmingPower))
212+
213+
214+func getCurrentInterest () = if ((tryGetInteger("total_farmingPower") > 0))
215+ then {
216+ let previousInterest = tryGetInteger("total_lastCheckInterest")
217+ let previousInterestHeight = tryGetInteger("total_lastCheckInterestHeight")
218+ let totalFarmingPower = tryGetInteger("total_farmingPower")
219+ calcInterest(previousInterest, previousInterestHeight, totalFarmingPower)
220+ }
221+ else if ((tryGetInteger("total_startHeight") != 0))
222+ then tryGetInteger("total_lastCheckInterest")
223+ else throw("farming is not launched, yet")
224+
225+
226+func calcAssetRewardDelta (address,assetId,assetFarmingPower) = {
227+ let lastCheckAssetInterest = tryGetInteger((((("address_" + address) + "_asset_") + assetId) + "_lastCheckInterest"))
228+ let currentInterest = getCurrentInterest()
229+ (assetFarmingPower * (currentInterest - lastCheckAssetInterest))
230+ }
231+
232+
233+func addAssetIdToGenEntry (assetId,assetGen) = {
234+ let currentValue = tryGetString((("assets_" + assetGen) + "_locked"))
235+ if ((currentValue == ""))
236+ then assetId
237+ else ((currentValue + ",") + assetId)
238+ }
239+
240+
241+func getStakeResult (address,assetId,assetFarmingPower,unstaker) = {
242+ let asset = toBase58String(assetId)
243+[IntegerEntry("total_farmingPower", (tryGetInteger("total_farmingPower") + assetFarmingPower)), IntegerEntry("total_lastCheckInterest", getCurrentInterest()), IntegerEntry("total_lastCheckInterestHeight", height), StringEntry((("asset_" + asset) + "_owner"), address), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_farmingPower"), assetFarmingPower), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_lastCheckInterest"), getCurrentInterest()), StringEntry((((("address_" + address) + "_asset_") + asset) + "_unstaker"), unstaker)]
244+ }
245+
246+
247+func getUnstakeResult (address,assetId,color,caller,realCaller,claimEggs) = {
248+ let locked = isLocked()
249+ if ((locked == locked))
250+ then {
251+ let asset = toBase58String(assetId)
252+ let unstaker = tryGetString((((("address_" + address) + "_asset_") + asset) + "_unstaker"))
253+ if (if ((unstaker != ""))
254+ then (unstaker != realCaller)
255+ else false)
256+ then throw("FUN: It seems duck was staked throuh a dapp, not directly, please unstake through dapp!")
257+ else {
258+ let assetFarmingPower = getLastKnownAssetFarmingPower(address, asset)
259+ if (!((assetFarmingPower > 0)))
260+ then throw("FGU: Asset farming power not bigger then 0")
261+ else {
262+ let assetRewardDelta = calcAssetRewardDelta(address, asset, assetFarmingPower)
263+ let farmedAmount = (assetRewardDelta + tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount")))
264+ let withdrawnAmount = tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"))
265+ let reward = ((farmedAmount - withdrawnAmount) / (scale * 100))
266+ let isWithoutPerch = tryGetBoolean((((("address_" + address) + "_asset_") + asset) + "_without_perch"))
267+ let rewardAfterSickNess = reward
268+ let appendPerches = if (isWithoutPerch)
269+ then [DeleteEntry((((("address_" + address) + "_asset_") + asset) + "_without_perch"))]
270+ else [IntegerEntry(((("address_" + address) + "_perchesAvailable_") + color), (tryGetInteger(((("address_" + address) + "_perchesAvailable_") + color)) + 1))]
271+ let sendTx = if (claimEggs)
272+ then $Tuple2([ScriptTransfer(caller, (rewardAfterSickNess * 1000000), getEggAssetId())], (rewardAfterSickNess * 1000000))
273+ else $Tuple2(nil, 0)
274+ $Tuple2(((([IntegerEntry("total_farmingPower", (tryGetInteger("total_farmingPower") - assetFarmingPower)), IntegerEntry("total_lastCheckInterest", getCurrentInterest()), IntegerEntry("total_lastCheckInterestHeight", height), DeleteEntry((("asset_" + asset) + "_owner")), DeleteEntry((((("address_" + address) + "_asset_") + asset) + "_unstaker")), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_farmingPower"), 0), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_lastCheckInterest"), getCurrentInterest()), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"), (withdrawnAmount + (rewardAfterSickNess * scale2))), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount"), (tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount")) + assetRewardDelta))] ++ appendPerches) ++ [ScriptTransfer(caller, 1, assetId)]) ++ sendTx._1), sendTx._2)
275+ }
276+ }
277+ }
278+ else throw("Strict value is not equal to itself.")
279+ }
280+
281+
255282 func calculatePerchPrice (address) = {
256283 let hasArtefactStaked = tryGetStringExternal(getAccBoosterAddress(), (("ART-XMISTL_" + address) + "_owner"))
257- let perchPrice = getIntegerValue(getOracle(), staticKey_perchFee())
258284 if ((hasArtefactStaked == ""))
259285 then perchPrice
260286 else ((perchPrice / 10) * 9)
261287 }
262288
263289
264290 func isProxyStakingSc (address) = {
265291 let allowedContracts = getProxyStaking()
266292 let allowedContractsList = split(allowedContracts, ";")
267293 (indexOf(allowedContractsList, address) != unit)
268294 }
269295
270296
297+func unstakeNFTInternal (asset,i,claimEgg) = {
298+ let assetId = fromBase58String(asset)
299+ let realCaller = toString(i.caller)
300+ let address = if (isProxyStakingSc(toString(i.caller)))
301+ then toString(i.originCaller)
302+ else realCaller
303+ let color = takeRight(value(assetInfo(assetId)).name, 1)
304+ if ((color == "U"))
305+ then throw("FUN: use another function to unstake Jackpot NFT")
306+ else {
307+ let result = getUnstakeResult(address, assetId, color, i.caller, realCaller, claimEgg)
308+ result
309+ }
310+ }
311+
312+
313+func unstakeJackpotInternal (asset,i,claimEgg) = {
314+ let assetId = fromBase58String(asset)
315+ let realCaller = toString(i.caller)
316+ let address = if (isProxyStakingSc(toString(i.caller)))
317+ then toString(i.originCaller)
318+ else realCaller
319+ let color = tryGetString((((("address_" + address) + "_asset_") + asset) + "_perchColor"))
320+ if ((takeRight(value(value(assetInfo(assetId)).name), 1) != "U"))
321+ then throw("jackpot only")
322+ else {
323+ let result = getUnstakeResult(address, assetId, color, i.caller, realCaller, claimEgg)
324+ result
325+ }
326+ }
327+
328+
329+func getBool (key) = match getBoolean(this, key) {
330+ case b: Boolean =>
331+ b
332+ case _ =>
333+ false
334+}
335+
336+
337+func isTestEnv () = getBool("TESTENV")
338+
339+
271340 @Callable(i)
272-func calculateFarmPower (assetId) = if (!(if ((value(assetInfo(fromBase58String(assetId))).issuer == getBreederAddress()))
273- then true
274- else (value(assetInfo(fromBase58String(assetId))).issuer == getIncubatorAddress())))
275- then throw("This does not seem like a valid Duck!")
276- else {
277- let assetName = value(assetInfo(fromBase58String(assetId))).name
278- let gen = takeRight(assetName, 1)
279- let isJackpot = (takeRight(assetName, 1) == "U")
280- let rarity = getAssetRarityComplete(isJackpot, assetName)
281- let genotype = split(dropRight(drop(assetName, 5), 3), "")
282- func uniqueArrayFilter (accum,nextGen) = if (!(containsElement(accum, nextGen)))
283- then (accum :+ nextGen)
284- else accum
285-
286- let uniqueList = {
287- let $l = genotype
288- let $s = size($l)
289- let $acc0 = nil
290- func $f0_1 ($a,$i) = if (($i >= $s))
291- then $a
292- else uniqueArrayFilter($a, $l[$i])
293-
294- func $f0_2 ($a,$i) = if (($i >= $s))
295- then $a
296- else throw("List size exceeds 8")
297-
298- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8)
299- }
300- let totalGenes = if ((gen == "U"))
301- then 8
302- else size(uniqueList)
303- let power = pow(15, 1, totalGenes, 0, 2, DOWN)
304- let multiplier = (((height - 3750000) * 100) / (((60 * 24) * 30) * 3))
305- let basePower = tryGetInteger((assetId + "_basePower"))
306- let finalPower = if ((basePower > 0))
307- then basePower
308- else ((power * multiplier) / 100)
309- let finalPowerRarity = ((finalPower * rarity) / 100)
310- let farmBoost = asInt(invoke(getItemsAddress(), "calculateFarmingPowerBoost", [assetId, toString(i.originCaller)], nil))
311- if ((farmBoost == farmBoost))
312- then {
313- let finalPowerRarityBoost = (finalPowerRarity + ((finalPowerRarity * farmBoost) / 100))
314- $Tuple2([IntegerEntry(("DEBUG_" + assetName), finalPower), IntegerEntry(("DEBUG_RARITY" + assetName), rarity), IntegerEntry(("DEBUG_FPRARITY_" + assetName), finalPowerRarity), IntegerEntry(("DEBUG_FARMBOOST_" + assetName), farmBoost), IntegerEntry(("DEBUG_FPRARITYBOOST_" + assetName), finalPowerRarityBoost), IntegerEntry(("DEBUG_POWER_" + assetName), power), IntegerEntry(("DEBUG_BASEPOWER_" + assetName), basePower), IntegerEntry(("DEBUG_COEFFICIENT_" + assetName), multiplier), IntegerEntry(("DEBUG_BOOST_" + assetName), farmBoost)], $Tuple2(finalPowerRarityBoost, finalPower))
315- }
316- else throw("Strict value is not equal to itself.")
317- }
341+func removePerches (address) = if ((i.caller != getNewFarmingAddress()))
342+ then throw("FRP: admin only")
343+ else [IntegerEntry((("address_" + address) + "_perchesAvailable_R"), 0), IntegerEntry((("address_" + address) + "_perchesAvailable_G"), 0), IntegerEntry((("address_" + address) + "_perchesAvailable_B"), 0), IntegerEntry((("address_" + address) + "_perchesAvailable_U"), 0)]
318344
319345
320346
321347 @Callable(i)
322348 func configureOracle (oracle) = if ((i.caller != this))
323349 then throw("FCO: admin only")
324350 else [StringEntry(staticKey_oracleAddress(), oracle)]
325351
326352
327353
328354 @Callable(i)
329-func buyPerch (colorI,refererAddress) = {
330- let validPayment = checkAdditionalPayment(i.payments[0])
355+func init () = if ((i.caller != this))
356+ then throw("FI: admin only")
357+ else [IntegerEntry("total_startHeight", height)]
358+
359+
360+
361+@Callable(i)
362+func buyPerch (colorI,refererAddress) = throw("FBN: function is disabled, migration to new sc ongoing")
363+
364+
365+
366+@Callable(i)
367+func addFreePerch (address,color) = throw("FBN: function is disabled, migration to new sc ongoing")
368+
369+
370+
371+@Callable(i)
372+func stakeNFT () = throw("FBN: function is disabled, migration to new sc ongoing")
373+
374+
375+
376+@Callable(i)
377+func stakeNFTWithoutPerch () = throw("FBN: function is disabled, migration to new sc ongoing")
378+
379+
380+
381+@Callable(i)
382+func unstakeNFT (asset) = {
383+ let validPayment = if ((i.caller == getMetaraceAddress()))
384+ then nil
385+ else checkAdditionalPayment(i.payments[0])
331386 if ((validPayment == validPayment))
332387 then {
333- let color = if ((colorI == "U"))
334- then "B"
335- else colorI
336- if ((0 > value(indexOf(["B", "R", "G", "Y"], color))))
337- then throw("you need to set color properly")
338- else {
339- let exactPrice = calculatePerchPrice(toString(i.caller))
340- let leftToPay = if ((i.originCaller == i.caller))
341- then {
342- let amountPaidByCoupons = asInt(invoke(getCouponsAddress(), "useCoupons", [exactPrice], nil))
343- if ((amountPaidByCoupons == amountPaidByCoupons))
344- then (exactPrice - amountPaidByCoupons)
345- else throw("Strict value is not equal to itself.")
346- }
347- else exactPrice
348- let firstPayment = if ((size(i.payments) == 2))
349- then value(i.payments[1])
350- else value(i.payments[0])
351- if ((firstPayment.assetId != getEggAssetId()))
352- then throw(("FBP: You can attach only EGG tokens with the following asset id: " + toBase58String(getEggAssetId())))
353- else if ((firstPayment.amount != leftToPay))
354- then throw(((("FBP: To buy a perch you currently need the following amount of EGGlets: " + toString(leftToPay)) + " ") + toString(i.caller)))
355- else {
356- let refererRewardForPerch = fraction(leftToPay, 5, 100)
357- let refCall = asBoolean(invoke(getRefContractAddress(), "refPayment", [refererAddress], [AttachedPayment(getEggAssetId(), refererRewardForPerch)]))
358- if ((refCall == refCall))
359- then {
360- let toBurn = if (refCall)
361- then (leftToPay - refererRewardForPerch)
362- else leftToPay
363- let burnCall = invoke(getBurnAddress(), "burnAttachedPayments", nil, [AttachedPayment(getEggAssetId(), toBurn)])
364- if ((burnCall == burnCall))
365- then {
366- let perchAmountKey = ((("address_" + toString(i.caller)) + "_perchesAvailable_") + color)
367- let perchAmount = tryGetInteger(perchAmountKey)
368- ([IntegerEntry(perchAmountKey, (perchAmount + 1))] ++ validPayment)
369- }
370- else throw("Strict value is not equal to itself.")
371- }
372- else throw("Strict value is not equal to itself.")
373- }
374- }
388+ let result = unstakeNFTInternal(asset, i, true)
389+ $Tuple2((result._1 ++ validPayment), result._2)
375390 }
376391 else throw("Strict value is not equal to itself.")
377392 }
378393
379394
380395
381396 @Callable(i)
382-func addFreePerch (address,color,amount) = if ((0 > value(indexOf(["B", "R", "G", "Y"], color))))
383- then throw("you need to set color properly")
384- else if (if (if ((i.caller != getRebirthAddress()))
385- then (i.caller != getTurtleRebirthAddress())
386- else false)
387- then (i.caller != this)
388- else false)
389- then throw("rebirth and admin only")
390- else {
391- let perchAmountKey = ((("address_" + address) + "_perchesAvailable_") + color)
392- let perchAmount = tryGetInteger(perchAmountKey)
393- $Tuple2([IntegerEntry(perchAmountKey, (perchAmount + amount))], "")
394- }
397+func unstakeNFTWithoutClaim (asset) = unstakeNFTInternal(asset, i, false)
395398
396399
397400
398401 @Callable(i)
399-func migratePerches (address) = {
400- let oldFarming = addressFromStringValue(tryGetStringExternal(getOracle(), "static_farmingAddress"))
401- func tryGetIntegerOldFarming (key) = match getInteger(oldFarming, key) {
402- case b: Int =>
403- b
404- case _ =>
405- 0
406- }
407-
408- let perchAmountB = tryGetIntegerOldFarming((("address_" + address) + "_perchesAvailable_B"))
409- let perchAmountR = tryGetIntegerOldFarming((("address_" + address) + "_perchesAvailable_R"))
410- let perchAmountG = tryGetIntegerOldFarming((("address_" + address) + "_perchesAvailable_G"))
411- let perchAmountY = tryGetIntegerOldFarming((("address_" + address) + "_perchesAvailable_Y"))
412- let perchAmountBInvoke = invoke(this, "addFreePerch", [address, "B", perchAmountB], nil)
413- let perchAmountRInvoke = invoke(this, "addFreePerch", [address, "R", perchAmountR], nil)
414- let perchAmountGInvoke = invoke(this, "addFreePerch", [address, "G", perchAmountG], nil)
415- let perchAmountYInvoke = invoke(this, "addFreePerch", [address, "Y", perchAmountY], nil)
416- let invokePerchesDelete = invoke(oldFarming, "removePerches", [address], nil)
417- nil
418- }
402+func stakeJackpot (color) = throw("FBN: function is disabled, migration to new sc ongoing")
419403
420404
421405
422406 @Callable(i)
423-func stakeNFT (jColor,usePerchOrigin,stakeWithoutPerch) = if (true)
424- then throw("Staking is disabled")
425- else if (if (stakeWithoutPerch)
426- then !(isProxyStakingSc(toString(i.caller)))
427- else false)
428- then throw("You can't stake without a perch")
429- else {
430- let validPayment = checkAdditionalPayment(i.payments[0])
431- if ((validPayment == validPayment))
432- then {
433- let pmt = value(i.payments[1])
434- let assetId = value(pmt.assetId)
435- let assetName = value(value(assetInfo(assetId)).name)
436- let isJackpot = (takeRight(assetName, 1) == "U")
437- let address = toString(i.caller)
438- let perchAddress = if (usePerchOrigin)
439- then toString(i.originCaller)
440- else address
441- let rarity = getAssetRarityComplete(isJackpot, assetName)
442- let perches = if (stakeWithoutPerch)
443- then nil
444- else {
445- let color = if (isJackpot)
446- then jColor
447- else takeRight(assetName, 1)
448- let availablePerches = tryGetInteger(((("address_" + perchAddress) + "_perchesAvailable_") + color))
449- if ((0 >= availablePerches))
450- then throw(("no perches available for the color " + color))
451- else [IntegerEntry(((("address_" + perchAddress) + "_perchesAvailable_") + color), (availablePerches - 1)), StringEntry((((("address_" + address) + "_asset_") + toBase58String(assetId)) + "_perchColor"), color)]
452- }
453- if ((perches == perches))
454- then if ((pmt.amount != 1))
455- then throw("NFT is not attached")
456- else {
457- let farmingPower = asIntTuple(invoke(this, "calculateFarmPower", [toBase58String(assetId)], nil))
458- if ((farmingPower == farmingPower))
459- then {
460- let result = claimStakingResult(address, toBase58String(assetId), false)
461- if ((result == result))
462- then ((([IntegerEntry(totalStakedKey(), (tryGetInteger(totalStakedKey()) + farmingPower._1)), IntegerEntry(totalStakedUserKey(address), (tryGetInteger(totalStakedUserKey(address)) + farmingPower._1)), StringEntry((toBase58String(assetId) + "_owner"), address), BooleanEntry((toBase58String(assetId) + "_use_origin"), usePerchOrigin), StringEntry((toBase58String(assetId) + "_original_caller"), toString(i.originCaller)), IntegerEntry(assetFarmingPower(address, toBase58String(assetId)), farmingPower._1), IntegerEntry((toBase58String(assetId) + "_basePower"), farmingPower._2), BooleanEntry((toBase58String(assetId) + "_without_perch"), stakeWithoutPerch)] ++ validPayment) ++ perches) ++ result._1)
463- else throw("Strict value is not equal to itself.")
464- }
465- else throw("Strict value is not equal to itself.")
466- }
467- else throw("Strict value is not equal to itself.")
468- }
469- else throw("Strict value is not equal to itself.")
470- }
471-
472-
473-
474-@Callable(i)
475-func unstakeNFT (asset) = {
476- let address = toString(i.caller)
477- let result = claimStakingResult(address, asset, false)
478- if ((result == result))
407+func unstakeJackpot (asset) = {
408+ let validPayment = checkAdditionalPayment(i.payments[0])
409+ if ((validPayment == validPayment))
479410 then {
480- let validPayment = checkAdditionalPayment(i.payments[0])
481- if ((validPayment == validPayment))
482- then {
483- let color = tryGetString((((("address_" + address) + "_asset_") + asset) + "_perchColor"))
484- let withoutPerch = tryGetBoolean((asset + "_without_perch"))
485- let perches = if (withoutPerch)
486- then nil
487- else {
488- let usePerchOrigin = tryGetBoolean((asset + "_use_origin"))
489- let perchOwner = if (usePerchOrigin)
490- then toString(i.originCaller)
491- else address
492-[IntegerEntry(((("address_" + address) + "_perchesAvailable_") + color), (tryGetInteger(((("address_" + address) + "_perchesAvailable_") + color)) + 1))]
493- }
494- if ((perches == perches))
495- then {
496- let assetFP = tryGetInteger(assetFarmingPower(address, asset))
497- if ((assetFP == assetFP))
498- then $Tuple2(((([IntegerEntry(totalStakedKey(), (tryGetInteger(totalStakedKey()) - assetFP)), IntegerEntry(totalStakedUserKey(address), (tryGetInteger(totalStakedUserKey(address)) - assetFP)), DeleteEntry((asset + "_owner")), DeleteEntry(assetFarmingPower(address, asset)), DeleteEntry((((("address_" + address) + "_asset_") + asset) + "_perchColor")), DeleteEntry((asset + "_original_caller")), DeleteEntry((asset + "_use_origin")), DeleteEntry((asset + "_without_perch")), ScriptTransfer(Address(fromBase58String(address)), 1, fromBase58String(asset))] ++ validPayment) ++ perches) ++ result._1), result._2)
499- else throw("Strict value is not equal to itself.")
500- }
501- else throw("Strict value is not equal to itself.")
502- }
503- else throw("Strict value is not equal to itself.")
411+ let result = unstakeJackpotInternal(asset, i, true)
412+ $Tuple2((result._1 ++ validPayment), result._2)
504413 }
505414 else throw("Strict value is not equal to itself.")
506415 }
507416
508417
509418
510419 @Callable(i)
511-func topUpReward () = {
512- let firstPayment = value(i.payments[0])
513- if ((firstPayment.assetId != getEggAssetId()))
514- then throw(("FBP: You can attach only EGG tokens with the following asset id: " + toBase58String(getEggAssetId())))
515- else {
516- let resHandleStaking = handleStakingTopUp(firstPayment.amount)
517- $Tuple2(resHandleStaking, true)
518- }
519- }
420+func unstakeJackpotWithoutClaimEgg (asset) = unstakeJackpotInternal(asset, i, false)
520421
521422
522423
523424 @Callable(i)
524-func claimReward (assetId) = {
525- let validPayment = checkAdditionalPayment(i.payments[0])
526- if ((validPayment == validPayment))
527- then if ((tryGetString((assetId + "_owner")) != toString(i.caller)))
528- then throw("You don't own this duck!!")
529- else if ((size(i.payments) > 1))
530- then throw("Please don't add extra payments")
531- else {
532- let result = claimStakingResult(toString(i.caller), assetId, true)
533- $Tuple2((validPayment ++ result._1), result._2)
425+func claimReward (asset) = {
426+ let locked = isLocked()
427+ if ((locked == locked))
428+ then {
429+ let validPayment = if ((i.originCaller == getCfMasterAddress()))
430+ then nil
431+ else checkAdditionalPayment(i.payments[0])
432+ if ((validPayment == validPayment))
433+ then {
434+ let address = if ((i.originCaller == getCfMasterAddress()))
435+ then toString(i.caller)
436+ else toString(i.originCaller)
437+ let assetId = fromBase58String(asset)
438+ let assetFarmingPower = getLastKnownAssetFarmingPower(address, asset)
439+ let assetRewardDelta = calcAssetRewardDelta(address, asset, assetFarmingPower)
440+ let farmedAmount = (assetRewardDelta + tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount")))
441+ let withdrawnAmount = tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"))
442+ let reward = ((farmedAmount - withdrawnAmount) / (scale * 100))
443+ if ((0 >= reward))
444+ then throw("FCR: you have no EGGs to withdraw")
445+ else $Tuple2(([IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"), (tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount")) + (reward * scale2))), ScriptTransfer(Address(fromBase58String(address)), (reward * 1000000), getEggAssetId())] ++ validPayment), (reward * 1000000))
534446 }
447+ else throw("Strict value is not equal to itself.")
448+ }
535449 else throw("Strict value is not equal to itself.")
536450 }
537451
538452

github/deemru/w8io/6500d08 
103.86 ms