tx · 6vYJqpd2jaTMbX9Je6K8FFHPceyRrGrt3GLUbrg1Ah1Z

3PAETTtuW7aSiyKtn9GuML3RgtV1xdq1mQW:  -0.02300000 Waves

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

{ "type": 13, "id": "6vYJqpd2jaTMbX9Je6K8FFHPceyRrGrt3GLUbrg1Ah1Z", "fee": 2300000, "feeAssetId": null, "timestamp": 1713374285049, "version": 2, "chainId": 87, "sender": "3PAETTtuW7aSiyKtn9GuML3RgtV1xdq1mQW", "senderPublicKey": "DSNxHVyf38CbPoz2oSJ1b4FWqRvqFsAphCzdtrPeWPHa", "proofs": [ "2mPTDx2ga39ZywY9GoEuhmn9MhCYfZJU584Hk1wTYAzmv9jnViHiCyVnTvyENTXDzKi8FpaMB3P6qMNxfaRQW9ap" ], "script": "base64:AAIFAAAAAAAAADEIAhIDCgEIEgMKAQgSBAoCCAgSBQoDCAgBEgMKAQgSBQoDCAQEEgMKAQgSABIDCgEIAAAANwAAAAAFU2NhbGUAAAAAAAX14QABAAAAFHRyeUdldFN0cmluZ0V4dGVybmFsAAAAAgAAAAdhZGRyZXNzAAAAA2tleQQAAAAHJG1hdGNoMAkABB0AAAACBQAAAAdhZGRyZXNzBQAAAANrZXkDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABlN0cmluZwQAAAABYQUAAAAHJG1hdGNoMAUAAAABYQIAAAAAAQAAAAx0cnlHZXRTdHJpbmcAAAABAAAAA2tleQkBAAAAFHRyeUdldFN0cmluZ0V4dGVybmFsAAAAAgUAAAAEdGhpcwUAAAADa2V5AQAAABxzdGF0aWNLZXlfcmVmQ29udHJhY3RBZGRyZXNzAAAAAAIAAAAZc3RhdGljX3JlZkNvbnRyYWN0QWRkcmVzcwAAAAAVa2V5R2xvYmFsTGFzdEludGVyZXN0AgAAABlnbG9iYWxfbGFzdENoZWNrX2ludGVyZXN0AQAAABdzdGF0aWNLZXlfb3JhY2xlQWRkcmVzcwAAAAACAAAAFHN0YXRpY19vcmFjbGVBZGRyZXNzAQAAABRzdGF0aWNLZXlfZWdnQXNzZXRJZAAAAAACAAAAEXN0YXRpY19lZ2dBc3NldElkAQAAABpzdGF0aWNLZXlfaW5jdWJhdG9yQWRkcmVzcwAAAAACAAAAF3N0YXRpY19pbmN1YmF0b3JBZGRyZXNzAQAAABhzdGF0aWNLZXlfYnJlZWRlckFkZHJlc3MAAAAAAgAAABVzdGF0aWNfYnJlZWRlckFkZHJlc3MBAAAAG3N0YXRpY0tleV9hY2NCb29zdGVyQWRkcmVzcwAAAAACAAAAGHN0YXRpY19hY2NCb29zdGVyQWRkcmVzcwEAAAAYc3RhdGljS2V5X2NvdXBvbnNBZGRyZXNzAAAAAAIAAAAVc3RhdGljX2NvdXBvbnNBZGRyZXNzAQAAABVzdGF0aWNLZXlfYnVybkFkZHJlc3MAAAAAAgAAABJzdGF0aWNfYnVybkFkZHJlc3MBAAAAEnN0YXRpY0tleV9leHRyYUZlZQAAAAACAAAAD3N0YXRpY19leHRyYUZlZQEAAAAXc3RhdGljS2V5X2ZlZUFnZ3JlZ2F0b3IAAAAAAgAAABRzdGF0aWNfZmVlQWdncmVnYXRvcgAAAAAPa2V5R2xvYmFsRWFybmVkAgAAAA9nbG9iYWxfZWFybmluZ3MBAAAAEnN0YXRpY0tleV9wZXJjaEZlZQAAAAACAAAAD3N0YXRpY19wZXJjaEZlZQEAAAAYc3RhdGljS2V5X3JlYmlydGhBZGRyZXNzAAAAAAIAAAAVc3RhdGljX3JlYmlydGhBZGRyZXNzAQAAAB5zdGF0aWNLZXlfdHVydGxlUmViaXJ0aEFkZHJlc3MAAAAAAgAAABtzdGF0aWNfdHVydGxlUmViaXJ0aEFkZHJlc3MBAAAAFnN0YXRpY0tleV9pdGVtc0FkZHJlc3MAAAAAAgAAABNzdGF0aWNfaXRlbXNBZGRyZXNzAQAAAA50b3RhbFN0YWtlZEtleQAAAAACAAAADHRvdGFsX3N0YWtlZAEAAAAfc3RhdGljS2V5X3Byb3h5U3Rha2luZ0NvbnRyYWN0cwAAAAACAAAAHHN0YXRpY19wcm94eVN0YWtpbmdDb250cmFjdHMBAAAACWdldE9yYWNsZQAAAAAJAQAAAAdBZGRyZXNzAAAAAQkAAlkAAAABCQEAAAAMdHJ5R2V0U3RyaW5nAAAAAQkBAAAAF3N0YXRpY0tleV9vcmFjbGVBZGRyZXNzAAAAAAEAAAARZ2V0UmViaXJ0aEFkZHJlc3MAAAAACQEAAAAHQWRkcmVzcwAAAAEJAAJZAAAAAQkBAAAAFHRyeUdldFN0cmluZ0V4dGVybmFsAAAAAgkBAAAACWdldE9yYWNsZQAAAAAJAQAAABhzdGF0aWNLZXlfcmViaXJ0aEFkZHJlc3MAAAAAAQAAAA1nZXRFZ2dBc3NldElkAAAAAAkAAlkAAAABCQEAAAAUdHJ5R2V0U3RyaW5nRXh0ZXJuYWwAAAACCQEAAAAJZ2V0T3JhY2xlAAAAAAkBAAAAFHN0YXRpY0tleV9lZ2dBc3NldElkAAAAAAEAAAATZ2V0SW5jdWJhdG9yQWRkcmVzcwAAAAAJAQAAAAdBZGRyZXNzAAAAAQkAAlkAAAABCQEAAAAUdHJ5R2V0U3RyaW5nRXh0ZXJuYWwAAAACCQEAAAAJZ2V0T3JhY2xlAAAAAAkBAAAAGnN0YXRpY0tleV9pbmN1YmF0b3JBZGRyZXNzAAAAAAEAAAARZ2V0QnJlZWRlckFkZHJlc3MAAAAACQEAAAAHQWRkcmVzcwAAAAEJAAJZAAAAAQkBAAAAFHRyeUdldFN0cmluZ0V4dGVybmFsAAAAAgkBAAAACWdldE9yYWNsZQAAAAAJAQAAABhzdGF0aWNLZXlfYnJlZWRlckFkZHJlc3MAAAAAAQAAABRnZXRBY2NCb29zdGVyQWRkcmVzcwAAAAAJAQAAAAdBZGRyZXNzAAAAAQkAAlkAAAABCQEAAAAUdHJ5R2V0U3RyaW5nRXh0ZXJuYWwAAAACCQEAAAAJZ2V0T3JhY2xlAAAAAAkBAAAAG3N0YXRpY0tleV9hY2NCb29zdGVyQWRkcmVzcwAAAAABAAAAEWdldENvdXBvbnNBZGRyZXNzAAAAAAkBAAAAB0FkZHJlc3MAAAABCQACWQAAAAEJAQAAABR0cnlHZXRTdHJpbmdFeHRlcm5hbAAAAAIJAQAAAAlnZXRPcmFjbGUAAAAACQEAAAAYc3RhdGljS2V5X2NvdXBvbnNBZGRyZXNzAAAAAAEAAAAOZ2V0QnVybkFkZHJlc3MAAAAACQEAAAAHQWRkcmVzcwAAAAEJAAJZAAAAAQkBAAAAFHRyeUdldFN0cmluZ0V4dGVybmFsAAAAAgkBAAAACWdldE9yYWNsZQAAAAAJAQAAABVzdGF0aWNLZXlfYnVybkFkZHJlc3MAAAAAAQAAABBnZXRGZWVBZ2dyZWdhdG9yAAAAAAkBAAAAB0FkZHJlc3MAAAABCQACWQAAAAEJAQAAABR0cnlHZXRTdHJpbmdFeHRlcm5hbAAAAAIJAQAAAAlnZXRPcmFjbGUAAAAACQEAAAAXc3RhdGljS2V5X2ZlZUFnZ3JlZ2F0b3IAAAAAAQAAABVnZXRSZWZDb250cmFjdEFkZHJlc3MAAAAACQEAAAAHQWRkcmVzcwAAAAEJAAJZAAAAAQkBAAAAFHRyeUdldFN0cmluZ0V4dGVybmFsAAAAAgkBAAAACWdldE9yYWNsZQAAAAAJAQAAABxzdGF0aWNLZXlfcmVmQ29udHJhY3RBZGRyZXNzAAAAAAEAAAAXZ2V0VHVydGxlUmViaXJ0aEFkZHJlc3MAAAAACQEAAAAHQWRkcmVzcwAAAAEJAAJZAAAAAQkBAAAAFHRyeUdldFN0cmluZ0V4dGVybmFsAAAAAgkBAAAACWdldE9yYWNsZQAAAAAJAQAAAB5zdGF0aWNLZXlfdHVydGxlUmViaXJ0aEFkZHJlc3MAAAAAAQAAAA9nZXRJdGVtc0FkZHJlc3MAAAAACQEAAAAHQWRkcmVzcwAAAAEJAAJZAAAAAQkBAAAAFHRyeUdldFN0cmluZ0V4dGVybmFsAAAAAgkBAAAACWdldE9yYWNsZQAAAAAJAQAAABZzdGF0aWNLZXlfaXRlbXNBZGRyZXNzAAAAAAEAAAAPZ2V0UHJveHlTdGFraW5nAAAAAAkBAAAAFHRyeUdldFN0cmluZ0V4dGVybmFsAAAAAgkBAAAACWdldE9yYWNsZQAAAAAJAQAAAB9zdGF0aWNLZXlfcHJveHlTdGFraW5nQ29udHJhY3RzAAAAAAEAAAAUa2V5TGFzdENoZWNrSW50ZXJlc3QAAAACAAAAB2FkZHJlc3MAAAAFYXNzZXQJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAIYWRkcmVzc18FAAAAB2FkZHJlc3MCAAAAB19hc3NldF8FAAAABWFzc2V0AgAAABJfbGFzdENoZWNrSW50ZXJlc3QBAAAAEWFzc2V0RmFybWluZ1Bvd2VyAAAAAgAAAAdhZGRyZXNzAAAABWFzc2V0CQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAACGFkZHJlc3NfBQAAAAdhZGRyZXNzAgAAAAdfYXNzZXRfBQAAAAVhc3NldAIAAAANX2Zhcm1pbmdQb3dlcgEAAAAQcmV3YXJkQ2xhaW1lZEtleQAAAAIAAAAHYWRkcmVzcwAAAAVhc3NldAkAASwAAAACCQABLAAAAAIJAAEsAAAAAgUAAAAHYWRkcmVzcwIAAAAHX2Fzc2V0XwUAAAAFYXNzZXQCAAAACF9jbGFpbWVkAQAAABJ0b3RhbFN0YWtlZFVzZXJLZXkAAAABAAAAB2FkZHJlc3MJAAEsAAAAAgIAAAANdG90YWxfc3Rha2VkXwUAAAAHYWRkcmVzcwAAAAANUmVmZXJlclJld2FyZAAAAAAAAAAABQEAAAAWY2hlY2tBZGRpdGlvbmFsUGF5bWVudAAAAAEAAAAHcGF5bWVudAMJAQAAAAlpc0RlZmluZWQAAAABCAUAAAAHcGF5bWVudAAAAAdhc3NldElkCQAAAgAAAAECAAAAGUZDQVA6IFBsZWFzZSBhdHRhY2ggd2F2ZXMEAAAACWZlZUFtb3VudAkBAAAAEUBleHRyTmF0aXZlKDEwNTApAAAAAgkBAAAACWdldE9yYWNsZQAAAAAJAQAAABJzdGF0aWNLZXlfZXh0cmFGZWUAAAAAAwkBAAAAAiE9AAAAAggFAAAAB3BheW1lbnQAAAAGYW1vdW50BQAAAAlmZWVBbW91bnQJAAACAAAAAQkAASwAAAACCQABLAAAAAICAAAAHEZDQVA6IFBsZWFzZSBhdHRhY2ggZXhhY3RseSAJAAGkAAAAAQUAAAAJZmVlQW1vdW50AgAAABMgYW1vdW50IG9mIHdhdmVsZXRzCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMJAQAAABBnZXRGZWVBZ2dyZWdhdG9yAAAAAAUAAAAJZmVlQW1vdW50BQAAAAR1bml0BQAAAANuaWwBAAAADXRyeUdldEludGVnZXIAAAABAAAAA2tleQQAAAAHJG1hdGNoMAkABBoAAAACBQAAAAR0aGlzBQAAAANrZXkDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAA0ludAQAAAABYgUAAAAHJG1hdGNoMAUAAAABYgAAAAAAAAAAAAEAAAAFYXNJbnQAAAABAAAABXZhbHVlBAAAAAckbWF0Y2gwBQAAAAV2YWx1ZQMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAADSW50BAAAAANpbnQFAAAAByRtYXRjaDAFAAAAA2ludAkAAAIAAAABAgAAAB5GQUk6IHdyb25nIHR5cGUsIGV4cGVjdGVkOiBJbnQBAAAACmFzSW50VHVwbGUAAAABAAAABXZhbHVlBAAAAAckbWF0Y2gwBQAAAAV2YWx1ZQMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAKKEludCwgSW50KQQAAAADaW50BQAAAAckbWF0Y2gwBQAAAANpbnQJAAACAAAAAQIAAAAkRkFJOiB3cm9uZyB0eXBlLCBleHBlY3RlZDogKEludCxJbnQpAQAAABJoYW5kbGVTdGFraW5nVG9wVXAAAAABAAAABmFtb3VudAQAAAAPY3VycmVudEludGVyZXN0CQEAAAANdHJ5R2V0SW50ZWdlcgAAAAEFAAAAFWtleUdsb2JhbExhc3RJbnRlcmVzdAQAAAARdG90YWxTdGFrZWRBbW91bnQJAQAAAA10cnlHZXRJbnRlZ2VyAAAAAQkBAAAADnRvdGFsU3Rha2VkS2V5AAAAAAQAAAANaW50ZXJlc3REZWx0YQMJAABmAAAAAgUAAAARdG90YWxTdGFrZWRBbW91bnQAAAAAAAAAAAAJAABrAAAAAwUAAAAGYW1vdW50BQAAAAVTY2FsZQUAAAARdG90YWxTdGFrZWRBbW91bnQAAAAAAAAAAAAJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAD2tleUdsb2JhbEVhcm5lZAkAAGQAAAACCQEAAAANdHJ5R2V0SW50ZWdlcgAAAAEFAAAAD2tleUdsb2JhbEVhcm5lZAUAAAAGYW1vdW50CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABVrZXlHbG9iYWxMYXN0SW50ZXJlc3QJAABkAAAAAgUAAAAPY3VycmVudEludGVyZXN0BQAAAA1pbnRlcmVzdERlbHRhBQAAAANuaWwBAAAACGFzU3RyaW5nAAAAAQAAAAV2YWx1ZQQAAAAHJG1hdGNoMAUAAAAFdmFsdWUDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABlN0cmluZwQAAAAGc3RyaW5nBQAAAAckbWF0Y2gwBQAAAAZzdHJpbmcJAAACAAAAAQIAAAAhRkFTOiB3cm9uZyB0eXBlLCBleHBlY3RlZDogU3RyaW5nAQAAAA10cnlHZXRCb29sZWFuAAAAAQAAAANrZXkEAAAAByRtYXRjaDAJAAQbAAAAAgUAAAAEdGhpcwUAAAADa2V5AwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAAdCb29sZWFuBAAAAAFiBQAAAAckbWF0Y2gwBQAAAAFiBwEAAAAVdHJ5R2V0Qm9vbGVhbkV4dGVybmFsAAAAAgAAAAdhZGRyZXNzAAAAA2tleQQAAAAHJG1hdGNoMAkABBsAAAACBQAAAAdhZGRyZXNzBQAAAANrZXkDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAB0Jvb2xlYW4EAAAAAWIFAAAAByRtYXRjaDAFAAAAAWIHAQAAAA5nZXRBc3NldE9yaWdpbgAAAAEAAAAKZ2VuZXJhdGlvbgMJAAAAAAAAAgUAAAAKZ2VuZXJhdGlvbgIAAAABRwkBAAAAE2dldEluY3ViYXRvckFkZHJlc3MAAAAACQEAAAARZ2V0QnJlZWRlckFkZHJlc3MAAAAAAQAAAA5nZXRBc3NldFJhcml0eQAAAAIAAAAIZ2Vub3R5cGUAAAAKZ2VuZXJhdGlvbgQAAAAIcXVhbnRpdHkJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACCQEAAAAOZ2V0QXNzZXRPcmlnaW4AAAABBQAAAApnZW5lcmF0aW9uCQABLAAAAAIJAAEsAAAAAgIAAAAGc3RhdHNfBQAAAAhnZW5vdHlwZQIAAAAJX3F1YW50aXR5CQABLAAAAAIJAAEsAAAAAgIAAAAGc3RhdHNfBQAAAAhnZW5vdHlwZQIAAAATX3F1YW50aXR5IG5vdCBmb3VuZAQAAAAFcG93ZXIJAABsAAAABgkAAGkAAAACAAAAAAAAACcQBQAAAAhxdWFudGl0eQAAAAAAAAAABAAAAAAAAAAABQAAAAAAAAAAAQAAAAAAAAAAAgUAAAAFRkxPT1IDCQAAZgAAAAIFAAAABXBvd2VyAAAAAAAAAAAABQAAAAVwb3dlcgAAAAAAAAAAAgEAAAAWZ2V0QXNzZXRSYXJpdHlDb21wbGV0ZQAAAAIAAAAJaXNKYWNrcG90AAAACWFzc2V0TmFtZQQAAAAGcmFyaXR5AwUAAAAJaXNKYWNrcG90AAAAAAAAAABkBAAAAApnZW5lcmF0aW9uCQABLwAAAAIJAQAAAAl0YWtlUmlnaHQAAAACBQAAAAlhc3NldE5hbWUAAAAAAAAAAAIAAAAAAAAAAAEEAAAAB2Zhcm1HZW4JAQAAAAhhc1N0cmluZwAAAAEJAAP8AAAABAkBAAAAEWdldEJyZWVkZXJBZGRyZXNzAAAAAAIAAAAOZ2V0R2VuRnJvbU5hbWUJAARMAAAAAgUAAAAJYXNzZXROYW1lBQAAAANuaWwFAAAAA25pbAMJAAAAAAAAAgUAAAAHZmFybUdlbgUAAAAHZmFybUdlbgkBAAAADmdldEFzc2V0UmFyaXR5AAAAAgUAAAAHZmFybUdlbgUAAAAKZ2VuZXJhdGlvbgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FAAAABnJhcml0eQEAAAASdXBkYXRlRmFybWluZ1Bvd2VyAAAAAgAAAAdhZGRyZXNzAAAABWFzc2V0BAAAAAt0b3RhbFN0YWtlZAkBAAAADXRyeUdldEludGVnZXIAAAABCQEAAAAOdG90YWxTdGFrZWRLZXkAAAAABAAAAA90b3RhbFN0YWtlZFVzZXIJAQAAAA10cnlHZXRJbnRlZ2VyAAAAAQkBAAAAEnRvdGFsU3Rha2VkVXNlcktleQAAAAEFAAAAB2FkZHJlc3MEAAAACWN1cnJlbnRGUAkBAAAADXRyeUdldEludGVnZXIAAAABCQEAAAARYXNzZXRGYXJtaW5nUG93ZXIAAAACBQAAAAdhZGRyZXNzBQAAAAVhc3NldAQAAAAFbmV3RlAJAQAAAAphc0ludFR1cGxlAAAAAQkAA/wAAAAEBQAAAAR0aGlzAgAAABJjYWxjdWxhdGVGYXJtUG93ZXIJAARMAAAAAgUAAAAFYXNzZXQFAAAAA25pbAUAAAADbmlsAwkBAAAAAiE9AAAAAgUAAAAJY3VycmVudEZQAAAAAAAAAAAACQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAAOdG90YWxTdGFrZWRLZXkAAAAACQAAZAAAAAIJAABlAAAAAgUAAAALdG90YWxTdGFrZWQFAAAACWN1cnJlbnRGUAgFAAAABW5ld0ZQAAAAAl8xCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAASdG90YWxTdGFrZWRVc2VyS2V5AAAAAQUAAAAHYWRkcmVzcwkAAGQAAAACCQAAZQAAAAIFAAAAD3RvdGFsU3Rha2VkVXNlcgUAAAAJY3VycmVudEZQCAUAAAAFbmV3RlAAAAACXzEJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAABFhc3NldEZhcm1pbmdQb3dlcgAAAAIFAAAAB2FkZHJlc3MFAAAABWFzc2V0CAUAAAAFbmV3RlAAAAACXzEJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAICAAAAD0RFQlVHX2N1cnJlbnRGUAUAAAAJY3VycmVudEZQCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACAgAAAAtERUJVR19uZXdGUAgFAAAABW5ld0ZQAAAAAl8xBQAAAANuaWwFAAAAA25pbAEAAAASY2xhaW1TdGFraW5nUmVzdWx0AAAAAwAAAAdhZGRyZXNzAAAABWFzc2V0AAAABnJlY2FsYwQAAAAPY3VycmVudEludGVyZXN0CQEAAAANdHJ5R2V0SW50ZWdlcgAAAAEFAAAAFWtleUdsb2JhbExhc3RJbnRlcmVzdAQAAAARbGFzdENoZWNrSW50ZXJlc3QJAQAAAA10cnlHZXRJbnRlZ2VyAAAAAQkBAAAAFGtleUxhc3RDaGVja0ludGVyZXN0AAAAAgUAAAAHYWRkcmVzcwUAAAAFYXNzZXQEAAAADHN0YWtlZEFtb3VudAkBAAAADXRyeUdldEludGVnZXIAAAABCQEAAAARYXNzZXRGYXJtaW5nUG93ZXIAAAACBQAAAAdhZGRyZXNzBQAAAAVhc3NldAQAAAAIZnBVcGRhdGUDBQAAAAZyZWNhbGMJAQAAABJ1cGRhdGVGYXJtaW5nUG93ZXIAAAACBQAAAAdhZGRyZXNzBQAAAAVhc3NldAUAAAADbmlsAwkAAAAAAAACBQAAAAhmcFVwZGF0ZQUAAAAIZnBVcGRhdGUEAAAABnJld2FyZAMJAABmAAAAAgUAAAARbGFzdENoZWNrSW50ZXJlc3QAAAAAAAAAAAAJAABrAAAAAwkAAGUAAAACBQAAAA9jdXJyZW50SW50ZXJlc3QFAAAAEWxhc3RDaGVja0ludGVyZXN0BQAAAAxzdGFrZWRBbW91bnQFAAAABVNjYWxlAAAAAAAAAAAACQAFFAAAAAIJAAROAAAAAgkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCQEAAAAHQWRkcmVzcwAAAAEJAAJZAAAAAQUAAAAHYWRkcmVzcwUAAAAGcmV3YXJkCQEAAAANZ2V0RWdnQXNzZXRJZAAAAAAJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAABRrZXlMYXN0Q2hlY2tJbnRlcmVzdAAAAAIFAAAAB2FkZHJlc3MFAAAABWFzc2V0BQAAAA9jdXJyZW50SW50ZXJlc3QJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAABByZXdhcmRDbGFpbWVkS2V5AAAAAgUAAAAHYWRkcmVzcwUAAAAFYXNzZXQJAABkAAAAAgkBAAAADXRyeUdldEludGVnZXIAAAABCQEAAAAQcmV3YXJkQ2xhaW1lZEtleQAAAAIFAAAAB2FkZHJlc3MFAAAABWFzc2V0BQAAAAZyZXdhcmQFAAAAA25pbAUAAAAIZnBVcGRhdGUFAAAABnJld2FyZAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAAAACWFzQm9vbGVhbgAAAAEAAAAFdmFsdWUEAAAAByRtYXRjaDAFAAAABXZhbHVlAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAAdCb29sZWFuBAAAAAdib29sZWFuBQAAAAckbWF0Y2gwBQAAAAdib29sZWFuCQAAAgAAAAECAAAAIkZBQjogd3JvbmcgdHlwZSwgZXhwZWN0ZWQ6IEJvb2xlYW4BAAAAE2NhbGN1bGF0ZVBlcmNoUHJpY2UAAAABAAAAB2FkZHJlc3MEAAAAEWhhc0FydGVmYWN0U3Rha2VkCQEAAAAUdHJ5R2V0U3RyaW5nRXh0ZXJuYWwAAAACCQEAAAAUZ2V0QWNjQm9vc3RlckFkZHJlc3MAAAAACQABLAAAAAIJAAEsAAAAAgIAAAALQVJULVhNSVNUTF8FAAAAB2FkZHJlc3MCAAAABl9vd25lcgQAAAAKcGVyY2hQcmljZQkBAAAAEUBleHRyTmF0aXZlKDEwNTApAAAAAgkBAAAACWdldE9yYWNsZQAAAAAJAQAAABJzdGF0aWNLZXlfcGVyY2hGZWUAAAAAAwkAAAAAAAACBQAAABFoYXNBcnRlZmFjdFN0YWtlZAIAAAAABQAAAApwZXJjaFByaWNlCQAAaAAAAAIJAABpAAAAAgUAAAAKcGVyY2hQcmljZQAAAAAAAAAACgAAAAAAAAAACQEAAAAQaXNQcm94eVN0YWtpbmdTYwAAAAEAAAAHYWRkcmVzcwQAAAAQYWxsb3dlZENvbnRyYWN0cwkBAAAAD2dldFByb3h5U3Rha2luZwAAAAAEAAAAFGFsbG93ZWRDb250cmFjdHNMaXN0CQAEtQAAAAIFAAAAEGFsbG93ZWRDb250cmFjdHMCAAAAATsJAQAAAAIhPQAAAAIJAARPAAAAAgUAAAAUYWxsb3dlZENvbnRyYWN0c0xpc3QFAAAAB2FkZHJlc3MFAAAABHVuaXQA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cmF0ZVBlcmNoZXMAAAABAAAAB2FkZHJlc3MEAAAACm9sZEZhcm1pbmcJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEJAQAAABR0cnlHZXRTdHJpbmdFeHRlcm5hbAAAAAIJAQAAAAlnZXRPcmFjbGUAAAAAAgAAABVzdGF0aWNfZmFybWluZ0FkZHJlc3MKAQAAABd0cnlHZXRJbnRlZ2VyT2xkRmFybWluZwAAAAEAAAADa2V5BAAAAAckbWF0Y2gwCQAEGgAAAAIFAAAACm9sZEZhcm1pbmcFAAAAA2tleQMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAADSW50BAAAAAFiBQAAAAckbWF0Y2gwBQAAAAFiAAAAAAAAAAAABAAAAAxwZXJjaEFtb3VudEIJAQAAABd0cnlHZXRJbnRlZ2VyT2xkRmFybWluZwAAAAEJAAEsAAAAAgkAASwAAAACAgAAAAhhZGRyZXNzXwUAAAAHYWRkcmVzcwIAAAATX3BlcmNoZXNBdmFpbGFibGVfQgQAAAAMcGVyY2hBbW91bnRSCQEAAAAXdHJ5R2V0SW50ZWdlck9sZEZhcm1pbmcAAAABCQABLAAAAAIJAAEsAAAAAgIAAAAIYWRkcmVzc18FAAAAB2FkZHJlc3MCAAAAE19wZXJjaGVzQXZhaWxhYmxlX1IEAAAADHBlcmNoQW1vdW50RwkBAAAAF3RyeUdldEludGVnZXJPbGRGYXJtaW5nAAAAAQkAASwAAAACCQABLAAAAAICAAAACGFkZHJlc3NfBQAAAAdhZGRyZXNzAgAAABNfcGVyY2hlc0F2YWlsYWJsZV9HBAAAAAxwZXJjaEFtb3VudFkJAQAAABd0cnlHZXRJbnRlZ2VyT2xkRmFybWluZwAAAAEJAAEsAAAAAgkAASwAAAACAgAAAAhhZGRyZXNzXwUAAAAHYWRkcmVzcwIAAAATX3BlcmNoZXNBdmFpbGFibGVfWQQAAAAScGVyY2hBbW91bnRCSW52b2tlCQAD/AAAAAQFAAAABHRoaXMCAAAADGFkZEZyZWVQZXJjaAkABEwAAAACBQAAAAdhZGRyZXNzCQAETAAAAAICAAAAAUIJAARMAAAAAgUAAAAMcGVyY2hBbW91bnRCBQAAAANuaWwFAAAAA25pbAQAAAAScGVyY2hBbW91bnRSSW52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", "height": 4133016, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 2AuCXttd91WxsqvrxXRWLmSX17ymvWagemYTQ7Zcw4H8 Next: B41BtyqVQJRVEVfKnNSqX17thSsfg4kKXLxRUdyymEQd Diff:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let perchPrice = (100 * 1000000)
5-
6-let scale = 10000
7-
8-let scale2 = 1000000
4+let Scale = 100000000
95
106 func tryGetStringExternal (address,key) = match getString(address, key) {
117 case a: String =>
1713
1814 func tryGetString (key) = tryGetStringExternal(this, key)
1915
16+
17+func staticKey_refContractAddress () = "static_refContractAddress"
18+
19+
20+let keyGlobalLastInterest = "global_lastCheck_interest"
2021
2122 func staticKey_oracleAddress () = "static_oracleAddress"
2223
3031 func staticKey_breederAddress () = "static_breederAddress"
3132
3233
33-func staticKey_itemsAddress () = "static_itemsAddress"
34-
35-
36-func staticKey_metaRaceAddress () = "static_metaRaceAddress"
37-
38-
3934 func staticKey_accBoosterAddress () = "static_accBoosterAddress"
4035
4136
42-func staticKey_proxyStakingContracts () = "static_proxyStakingContracts"
37+func staticKey_couponsAddress () = "static_couponsAddress"
4338
4439
45-func staticKey_maintenance () = "static_maintenance"
46-
47-
48-func staticKey_cfMasterAddress () = "static_cfMasterAddress"
40+func staticKey_burnAddress () = "static_burnAddress"
4941
5042
5143 func staticKey_extraFee () = "static_extraFee"
5446 func staticKey_feeAggregator () = "static_feeAggregator"
5547
5648
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"
67+
68+
5769 func getOracle () = Address(fromBase58String(tryGetString(staticKey_oracleAddress())))
70+
71+
72+func getRebirthAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_rebirthAddress())))
5873
5974
6075 func getEggAssetId () = fromBase58String(tryGetStringExternal(getOracle(), staticKey_eggAssetId()))
6681 func getBreederAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_breederAddress())))
6782
6883
69-func getItemsAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_itemsAddress())))
84+func getAccBoosterAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_accBoosterAddress())))
7085
7186
72-func getMetaraceAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_metaRaceAddress())))
87+func getCouponsAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_couponsAddress())))
7388
7489
75-func getAccBoosterAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_accBoosterAddress())))
90+func getBurnAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_burnAddress())))
91+
92+
93+func getFeeAggregator () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_feeAggregator())))
94+
95+
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())))
76103
77104
78105 func getProxyStaking () = tryGetStringExternal(getOracle(), staticKey_proxyStakingContracts())
79106
80107
81-func getMaintenance () = tryGetStringExternal(getOracle(), staticKey_maintenance())
108+func keyLastCheckInterest (address,asset) = (((("address_" + address) + "_asset_") + asset) + "_lastCheckInterest")
82109
83110
84-func getCfMasterAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_cfMasterAddress())))
111+func assetFarmingPower (address,asset) = (((("address_" + address) + "_asset_") + asset) + "_farmingPower")
85112
86113
87-func getFeeAggregator () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_feeAggregator())))
114+func rewardClaimedKey (address,asset) = (((address + "_asset_") + asset) + "_claimed")
115+
116+
117+func totalStakedUserKey (address) = ("total_staked_" + address)
88118
89119
90120 let RefererReward = 5
99129 }
100130
101131
102-func getRewardPerBlock () = 0
103-
104-
105-func isLocked () = if ((getMaintenance() != ""))
106- then throw(getMaintenance())
107- else 0
108-
109-
110132 func tryGetInteger (key) = match getInteger(this, key) {
111133 case b: Int =>
112134 b
113135 case _ =>
114136 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")
115171 }
116172
117173
145201 }
146202
147203
148-func asString (value) = match value {
149- case string: String =>
150- string
151- case _ =>
152- throw("FAS: wrong type, expected: String")
153-}
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+ }
154216
155217
156-func asInt (value) = match value {
157- case int: Int =>
158- int
159- case _ =>
160- throw("FAI: wrong type, expected: Int")
161-}
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+ }
162245
163246
164247 func asBoolean (value) = match value {
169252 }
170253
171254
172-func getAssetFarmingPower (assetId,address) = if (if ((value(assetInfo(assetId)).issuer == getBreederAddress()))
173- then true
174- else (value(assetInfo(assetId)).issuer == getIncubatorAddress()))
175- then {
176- let farmBoost = asInt(invoke(getItemsAddress(), "calculateFarmingPowerBoost", [toBase58String(assetId), address], nil))
177- if ((farmBoost == farmBoost))
178- then {
179- let assetName = value(assetInfo(assetId)).name
180- let isJackpot = (takeRight(value(assetName), 1) == "U")
181- let farmGen = if (isJackpot)
182- then ""
183- else asString(invoke(getBreederAddress(), "getGenFromName", [assetName], nil))
184- if ((farmGen == farmGen))
185- then {
186- let rarity = if (isJackpot)
187- then 100
188- else {
189- let generation = take(takeRight(assetName, 2), 1)
190- getAssetRarity(farmGen, generation)
191- }
192- let totalFarmingPower = (rarity + fraction(rarity, farmBoost, 100))
193- $Tuple2(farmGen, totalFarmingPower)
194- }
195- else throw("Strict value is not equal to itself.")
196- }
197- else throw("Strict value is not equal to itself.")
198- }
199- else throw("not valid NFT")
200-
201-
202-func getLastKnownAssetFarmingPower (address,assetId) = tryGetInteger((((("address_" + address) + "_asset_") + assetId) + "_farmingPower"))
203-
204-
205-func calcInterest (previousInterest,previousInterestHeight,totalFarmingPower) = (previousInterest + (((scale * getRewardPerBlock()) * (height - previousInterestHeight)) / totalFarmingPower))
206-
207-
208-func getCurrentInterest () = if ((tryGetInteger("total_farmingPower") > 0))
209- then {
210- let previousInterest = tryGetInteger("total_lastCheckInterest")
211- let previousInterestHeight = tryGetInteger("total_lastCheckInterestHeight")
212- let totalFarmingPower = tryGetInteger("total_farmingPower")
213- calcInterest(previousInterest, previousInterestHeight, totalFarmingPower)
214- }
215- else if ((tryGetInteger("total_startHeight") != 0))
216- then tryGetInteger("total_lastCheckInterest")
217- else throw("farming is not launched, yet")
218-
219-
220-func calcAssetRewardDelta (address,assetId,assetFarmingPower) = {
221- let lastCheckAssetInterest = tryGetInteger((((("address_" + address) + "_asset_") + assetId) + "_lastCheckInterest"))
222- let currentInterest = getCurrentInterest()
223- (assetFarmingPower * (currentInterest - lastCheckAssetInterest))
224- }
225-
226-
227-func addAssetIdToGenEntry (assetId,assetGen) = {
228- let currentValue = tryGetString((("assets_" + assetGen) + "_locked"))
229- if ((currentValue == ""))
230- then assetId
231- else ((currentValue + ",") + assetId)
232- }
233-
234-
235-func getStakeResult (address,assetId,assetFarmingPower,unstaker) = {
236- let asset = toBase58String(assetId)
237-[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)]
238- }
239-
240-
241-func getUnstakeResult (address,assetId,color,caller,realCaller,claimEggs) = {
242- let locked = isLocked()
243- if ((locked == locked))
244- then {
245- let asset = toBase58String(assetId)
246- let unstaker = tryGetString((((("address_" + address) + "_asset_") + asset) + "_unstaker"))
247- if (if ((unstaker != ""))
248- then (unstaker != realCaller)
249- else false)
250- then throw("FUN: It seems duck was staked throuh a dapp, not directly, please unstake through dapp!")
251- else {
252- let assetFarmingPower = getLastKnownAssetFarmingPower(address, asset)
253- if (!((assetFarmingPower > 0)))
254- then throw("FGU: Asset farming power not bigger then 0")
255- else {
256- let assetRewardDelta = calcAssetRewardDelta(address, asset, assetFarmingPower)
257- let farmedAmount = (assetRewardDelta + tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount")))
258- let withdrawnAmount = tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"))
259- let reward = ((farmedAmount - withdrawnAmount) / (scale * 100))
260- let isWithoutPerch = tryGetBoolean((((("address_" + address) + "_asset_") + asset) + "_without_perch"))
261- let rewardAfterSickNess = reward
262- let appendPerches = if (isWithoutPerch)
263- then [DeleteEntry((((("address_" + address) + "_asset_") + asset) + "_without_perch"))]
264- else [IntegerEntry(((("address_" + address) + "_perchesAvailable_") + color), (tryGetInteger(((("address_" + address) + "_perchesAvailable_") + color)) + 1))]
265- let sendTx = if (claimEggs)
266- then $Tuple2([ScriptTransfer(caller, (rewardAfterSickNess * 1000000), getEggAssetId())], (rewardAfterSickNess * 1000000))
267- else $Tuple2(nil, 0)
268- $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)
269- }
270- }
271- }
272- else throw("Strict value is not equal to itself.")
273- }
274-
275-
276255 func calculatePerchPrice (address) = {
277256 let hasArtefactStaked = tryGetStringExternal(getAccBoosterAddress(), (("ART-XMISTL_" + address) + "_owner"))
257+ let perchPrice = getIntegerValue(getOracle(), staticKey_perchFee())
278258 if ((hasArtefactStaked == ""))
279259 then perchPrice
280260 else ((perchPrice / 10) * 9)
288268 }
289269
290270
291-func unstakeNFTInternal (asset,i,claimEgg) = {
292- let assetId = fromBase58String(asset)
293- let realCaller = toString(i.caller)
294- let address = if (isProxyStakingSc(toString(i.caller)))
295- then toString(i.originCaller)
296- else realCaller
297- let color = takeRight(value(assetInfo(assetId)).name, 1)
298- if ((color == "U"))
299- then throw("FUN: use another function to unstake Jackpot NFT")
300- else {
301- let result = getUnstakeResult(address, assetId, color, i.caller, realCaller, claimEgg)
302- result
271+@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)
303299 }
304- }
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+ }
305318
306-
307-func unstakeJackpotInternal (asset,i,claimEgg) = {
308- let assetId = fromBase58String(asset)
309- let realCaller = toString(i.caller)
310- let address = if (isProxyStakingSc(toString(i.caller)))
311- then toString(i.originCaller)
312- else realCaller
313- let color = tryGetString((((("address_" + address) + "_asset_") + asset) + "_perchColor"))
314- if ((takeRight(value(value(assetInfo(assetId)).name), 1) != "U"))
315- then throw("jackpot only")
316- else {
317- let result = getUnstakeResult(address, assetId, color, i.caller, realCaller, claimEgg)
318- result
319- }
320- }
321-
322-
323-func getBool (key) = match getBoolean(this, key) {
324- case b: Boolean =>
325- b
326- case _ =>
327- false
328-}
329-
330-
331-func isTestEnv () = getBool("TESTENV")
332319
333320
334321 @Callable(i)
339326
340327
341328 @Callable(i)
342-func init () = if ((i.caller != this))
343- then throw("FI: admin only")
344- else [IntegerEntry("total_startHeight", height)]
345-
346-
347-
348-@Callable(i)
349-func buyPerch (colorI,refererAddress) = throw("FBN: function is disabled, migration to new sc ongoing")
350-
351-
352-
353-@Callable(i)
354-func addFreePerch (address,color) = throw("FBN: function is disabled, migration to new sc ongoing")
355-
356-
357-
358-@Callable(i)
359-func stakeNFT () = throw("FBN: function is disabled, migration to new sc ongoing")
360-
361-
362-
363-@Callable(i)
364-func stakeNFTWithoutPerch () = throw("FBN: function is disabled, migration to new sc ongoing")
365-
366-
367-
368-@Callable(i)
369-func unstakeNFT (asset) = {
370- let validPayment = if ((i.caller == getMetaraceAddress()))
371- then nil
372- else checkAdditionalPayment(i.payments[0])
329+func buyPerch (colorI,refererAddress) = {
330+ let validPayment = checkAdditionalPayment(i.payments[0])
373331 if ((validPayment == validPayment))
374332 then {
375- let result = unstakeNFTInternal(asset, i, true)
376- $Tuple2((result._1 ++ validPayment), result._2)
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+ }
377375 }
378376 else throw("Strict value is not equal to itself.")
379377 }
381379
382380
383381 @Callable(i)
384-func unstakeNFTWithoutClaim (asset) = unstakeNFTInternal(asset, i, false)
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+ }
385395
386396
387397
388398 @Callable(i)
389-func stakeJackpot (color) = throw("FBN: function is disabled, migration to new sc ongoing")
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+ }
390419
391420
392421
393422 @Callable(i)
394-func unstakeJackpot (asset) = {
395- let validPayment = checkAdditionalPayment(i.payments[0])
396- if ((validPayment == validPayment))
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))
397479 then {
398- let result = unstakeJackpotInternal(asset, i, true)
399- $Tuple2((result._1 ++ validPayment), result._2)
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.")
400504 }
401505 else throw("Strict value is not equal to itself.")
402506 }
404508
405509
406510 @Callable(i)
407-func unstakeJackpotWithoutClaimEgg (asset) = unstakeJackpotInternal(asset, i, false)
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+ }
408520
409521
410522
411523 @Callable(i)
412-func claimReward (asset) = {
413- let locked = isLocked()
414- if ((locked == locked))
415- then {
416- let validPayment = if ((i.originCaller == getCfMasterAddress()))
417- then nil
418- else checkAdditionalPayment(i.payments[0])
419- if ((validPayment == validPayment))
420- then {
421- let address = if ((i.originCaller == getCfMasterAddress()))
422- then toString(i.caller)
423- else toString(i.originCaller)
424- let assetId = fromBase58String(asset)
425- let assetFarmingPower = getLastKnownAssetFarmingPower(address, asset)
426- let assetRewardDelta = calcAssetRewardDelta(address, asset, assetFarmingPower)
427- let farmedAmount = (assetRewardDelta + tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount")))
428- let withdrawnAmount = tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"))
429- let reward = ((farmedAmount - withdrawnAmount) / (scale * 100))
430- if ((0 >= reward))
431- then throw("FCR: you have no EGGs to withdraw")
432- 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))
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)
433534 }
434- else throw("Strict value is not equal to itself.")
435- }
436535 else throw("Strict value is not equal to itself.")
437536 }
438537
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let perchPrice = (100 * 1000000)
5-
6-let scale = 10000
7-
8-let scale2 = 1000000
4+let Scale = 100000000
95
106 func tryGetStringExternal (address,key) = match getString(address, key) {
117 case a: String =>
128 a
139 case _ =>
1410 ""
1511 }
1612
1713
1814 func tryGetString (key) = tryGetStringExternal(this, key)
1915
16+
17+func staticKey_refContractAddress () = "static_refContractAddress"
18+
19+
20+let keyGlobalLastInterest = "global_lastCheck_interest"
2021
2122 func staticKey_oracleAddress () = "static_oracleAddress"
2223
2324
2425 func staticKey_eggAssetId () = "static_eggAssetId"
2526
2627
2728 func staticKey_incubatorAddress () = "static_incubatorAddress"
2829
2930
3031 func staticKey_breederAddress () = "static_breederAddress"
3132
3233
33-func staticKey_itemsAddress () = "static_itemsAddress"
34-
35-
36-func staticKey_metaRaceAddress () = "static_metaRaceAddress"
37-
38-
3934 func staticKey_accBoosterAddress () = "static_accBoosterAddress"
4035
4136
42-func staticKey_proxyStakingContracts () = "static_proxyStakingContracts"
37+func staticKey_couponsAddress () = "static_couponsAddress"
4338
4439
45-func staticKey_maintenance () = "static_maintenance"
46-
47-
48-func staticKey_cfMasterAddress () = "static_cfMasterAddress"
40+func staticKey_burnAddress () = "static_burnAddress"
4941
5042
5143 func staticKey_extraFee () = "static_extraFee"
5244
5345
5446 func staticKey_feeAggregator () = "static_feeAggregator"
5547
5648
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"
67+
68+
5769 func getOracle () = Address(fromBase58String(tryGetString(staticKey_oracleAddress())))
70+
71+
72+func getRebirthAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_rebirthAddress())))
5873
5974
6075 func getEggAssetId () = fromBase58String(tryGetStringExternal(getOracle(), staticKey_eggAssetId()))
6176
6277
6378 func getIncubatorAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_incubatorAddress())))
6479
6580
6681 func getBreederAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_breederAddress())))
6782
6883
69-func getItemsAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_itemsAddress())))
84+func getAccBoosterAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_accBoosterAddress())))
7085
7186
72-func getMetaraceAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_metaRaceAddress())))
87+func getCouponsAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_couponsAddress())))
7388
7489
75-func getAccBoosterAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_accBoosterAddress())))
90+func getBurnAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_burnAddress())))
91+
92+
93+func getFeeAggregator () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_feeAggregator())))
94+
95+
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())))
76103
77104
78105 func getProxyStaking () = tryGetStringExternal(getOracle(), staticKey_proxyStakingContracts())
79106
80107
81-func getMaintenance () = tryGetStringExternal(getOracle(), staticKey_maintenance())
108+func keyLastCheckInterest (address,asset) = (((("address_" + address) + "_asset_") + asset) + "_lastCheckInterest")
82109
83110
84-func getCfMasterAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_cfMasterAddress())))
111+func assetFarmingPower (address,asset) = (((("address_" + address) + "_asset_") + asset) + "_farmingPower")
85112
86113
87-func getFeeAggregator () = Address(fromBase58String(tryGetStringExternal(getOracle(), staticKey_feeAggregator())))
114+func rewardClaimedKey (address,asset) = (((address + "_asset_") + asset) + "_claimed")
115+
116+
117+func totalStakedUserKey (address) = ("total_staked_" + address)
88118
89119
90120 let RefererReward = 5
91121
92122 func checkAdditionalPayment (payment) = if (isDefined(payment.assetId))
93123 then throw("FCAP: Please attach waves")
94124 else {
95125 let feeAmount = getIntegerValue(getOracle(), staticKey_extraFee())
96126 if ((payment.amount != feeAmount))
97127 then throw((("FCAP: Please attach exactly " + toString(feeAmount)) + " amount of wavelets"))
98128 else [ScriptTransfer(getFeeAggregator(), feeAmount, unit)]
99129 }
100130
101131
102-func getRewardPerBlock () = 0
103-
104-
105-func isLocked () = if ((getMaintenance() != ""))
106- then throw(getMaintenance())
107- else 0
108-
109-
110132 func tryGetInteger (key) = match getInteger(this, key) {
111133 case b: Int =>
112134 b
113135 case _ =>
114136 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")
115171 }
116172
117173
118174 func tryGetBoolean (key) = match getBoolean(this, key) {
119175 case b: Boolean =>
120176 b
121177 case _ =>
122178 false
123179 }
124180
125181
126182 func tryGetBooleanExternal (address,key) = match getBoolean(address, key) {
127183 case b: Boolean =>
128184 b
129185 case _ =>
130186 false
131187 }
132188
133189
134190 func getAssetOrigin (generation) = if ((generation == "G"))
135191 then getIncubatorAddress()
136192 else getBreederAddress()
137193
138194
139195 func getAssetRarity (genotype,generation) = {
140196 let quantity = valueOrErrorMessage(getInteger(getAssetOrigin(generation), (("stats_" + genotype) + "_quantity")), (("stats_" + genotype) + "_quantity not found"))
141197 let power = pow((10000 / quantity), 4, 5, 1, 2, FLOOR)
142198 if ((power > 0))
143199 then power
144200 else 2
145201 }
146202
147203
148-func asString (value) = match value {
149- case string: String =>
150- string
151- case _ =>
152- throw("FAS: wrong type, expected: String")
153-}
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+ }
154216
155217
156-func asInt (value) = match value {
157- case int: Int =>
158- int
159- case _ =>
160- throw("FAI: wrong type, expected: Int")
161-}
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+ }
162245
163246
164247 func asBoolean (value) = match value {
165248 case boolean: Boolean =>
166249 boolean
167250 case _ =>
168251 throw("FAB: wrong type, expected: Boolean")
169252 }
170253
171254
172-func getAssetFarmingPower (assetId,address) = if (if ((value(assetInfo(assetId)).issuer == getBreederAddress()))
173- then true
174- else (value(assetInfo(assetId)).issuer == getIncubatorAddress()))
175- then {
176- let farmBoost = asInt(invoke(getItemsAddress(), "calculateFarmingPowerBoost", [toBase58String(assetId), address], nil))
177- if ((farmBoost == farmBoost))
178- then {
179- let assetName = value(assetInfo(assetId)).name
180- let isJackpot = (takeRight(value(assetName), 1) == "U")
181- let farmGen = if (isJackpot)
182- then ""
183- else asString(invoke(getBreederAddress(), "getGenFromName", [assetName], nil))
184- if ((farmGen == farmGen))
185- then {
186- let rarity = if (isJackpot)
187- then 100
188- else {
189- let generation = take(takeRight(assetName, 2), 1)
190- getAssetRarity(farmGen, generation)
191- }
192- let totalFarmingPower = (rarity + fraction(rarity, farmBoost, 100))
193- $Tuple2(farmGen, totalFarmingPower)
194- }
195- else throw("Strict value is not equal to itself.")
196- }
197- else throw("Strict value is not equal to itself.")
198- }
199- else throw("not valid NFT")
200-
201-
202-func getLastKnownAssetFarmingPower (address,assetId) = tryGetInteger((((("address_" + address) + "_asset_") + assetId) + "_farmingPower"))
203-
204-
205-func calcInterest (previousInterest,previousInterestHeight,totalFarmingPower) = (previousInterest + (((scale * getRewardPerBlock()) * (height - previousInterestHeight)) / totalFarmingPower))
206-
207-
208-func getCurrentInterest () = if ((tryGetInteger("total_farmingPower") > 0))
209- then {
210- let previousInterest = tryGetInteger("total_lastCheckInterest")
211- let previousInterestHeight = tryGetInteger("total_lastCheckInterestHeight")
212- let totalFarmingPower = tryGetInteger("total_farmingPower")
213- calcInterest(previousInterest, previousInterestHeight, totalFarmingPower)
214- }
215- else if ((tryGetInteger("total_startHeight") != 0))
216- then tryGetInteger("total_lastCheckInterest")
217- else throw("farming is not launched, yet")
218-
219-
220-func calcAssetRewardDelta (address,assetId,assetFarmingPower) = {
221- let lastCheckAssetInterest = tryGetInteger((((("address_" + address) + "_asset_") + assetId) + "_lastCheckInterest"))
222- let currentInterest = getCurrentInterest()
223- (assetFarmingPower * (currentInterest - lastCheckAssetInterest))
224- }
225-
226-
227-func addAssetIdToGenEntry (assetId,assetGen) = {
228- let currentValue = tryGetString((("assets_" + assetGen) + "_locked"))
229- if ((currentValue == ""))
230- then assetId
231- else ((currentValue + ",") + assetId)
232- }
233-
234-
235-func getStakeResult (address,assetId,assetFarmingPower,unstaker) = {
236- let asset = toBase58String(assetId)
237-[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)]
238- }
239-
240-
241-func getUnstakeResult (address,assetId,color,caller,realCaller,claimEggs) = {
242- let locked = isLocked()
243- if ((locked == locked))
244- then {
245- let asset = toBase58String(assetId)
246- let unstaker = tryGetString((((("address_" + address) + "_asset_") + asset) + "_unstaker"))
247- if (if ((unstaker != ""))
248- then (unstaker != realCaller)
249- else false)
250- then throw("FUN: It seems duck was staked throuh a dapp, not directly, please unstake through dapp!")
251- else {
252- let assetFarmingPower = getLastKnownAssetFarmingPower(address, asset)
253- if (!((assetFarmingPower > 0)))
254- then throw("FGU: Asset farming power not bigger then 0")
255- else {
256- let assetRewardDelta = calcAssetRewardDelta(address, asset, assetFarmingPower)
257- let farmedAmount = (assetRewardDelta + tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount")))
258- let withdrawnAmount = tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"))
259- let reward = ((farmedAmount - withdrawnAmount) / (scale * 100))
260- let isWithoutPerch = tryGetBoolean((((("address_" + address) + "_asset_") + asset) + "_without_perch"))
261- let rewardAfterSickNess = reward
262- let appendPerches = if (isWithoutPerch)
263- then [DeleteEntry((((("address_" + address) + "_asset_") + asset) + "_without_perch"))]
264- else [IntegerEntry(((("address_" + address) + "_perchesAvailable_") + color), (tryGetInteger(((("address_" + address) + "_perchesAvailable_") + color)) + 1))]
265- let sendTx = if (claimEggs)
266- then $Tuple2([ScriptTransfer(caller, (rewardAfterSickNess * 1000000), getEggAssetId())], (rewardAfterSickNess * 1000000))
267- else $Tuple2(nil, 0)
268- $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)
269- }
270- }
271- }
272- else throw("Strict value is not equal to itself.")
273- }
274-
275-
276255 func calculatePerchPrice (address) = {
277256 let hasArtefactStaked = tryGetStringExternal(getAccBoosterAddress(), (("ART-XMISTL_" + address) + "_owner"))
257+ let perchPrice = getIntegerValue(getOracle(), staticKey_perchFee())
278258 if ((hasArtefactStaked == ""))
279259 then perchPrice
280260 else ((perchPrice / 10) * 9)
281261 }
282262
283263
284264 func isProxyStakingSc (address) = {
285265 let allowedContracts = getProxyStaking()
286266 let allowedContractsList = split(allowedContracts, ";")
287267 (indexOf(allowedContractsList, address) != unit)
288268 }
289269
290270
291-func unstakeNFTInternal (asset,i,claimEgg) = {
292- let assetId = fromBase58String(asset)
293- let realCaller = toString(i.caller)
294- let address = if (isProxyStakingSc(toString(i.caller)))
295- then toString(i.originCaller)
296- else realCaller
297- let color = takeRight(value(assetInfo(assetId)).name, 1)
298- if ((color == "U"))
299- then throw("FUN: use another function to unstake Jackpot NFT")
300- else {
301- let result = getUnstakeResult(address, assetId, color, i.caller, realCaller, claimEgg)
302- result
271+@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)
303299 }
304- }
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+ }
305318
306-
307-func unstakeJackpotInternal (asset,i,claimEgg) = {
308- let assetId = fromBase58String(asset)
309- let realCaller = toString(i.caller)
310- let address = if (isProxyStakingSc(toString(i.caller)))
311- then toString(i.originCaller)
312- else realCaller
313- let color = tryGetString((((("address_" + address) + "_asset_") + asset) + "_perchColor"))
314- if ((takeRight(value(value(assetInfo(assetId)).name), 1) != "U"))
315- then throw("jackpot only")
316- else {
317- let result = getUnstakeResult(address, assetId, color, i.caller, realCaller, claimEgg)
318- result
319- }
320- }
321-
322-
323-func getBool (key) = match getBoolean(this, key) {
324- case b: Boolean =>
325- b
326- case _ =>
327- false
328-}
329-
330-
331-func isTestEnv () = getBool("TESTENV")
332319
333320
334321 @Callable(i)
335322 func configureOracle (oracle) = if ((i.caller != this))
336323 then throw("FCO: admin only")
337324 else [StringEntry(staticKey_oracleAddress(), oracle)]
338325
339326
340327
341328 @Callable(i)
342-func init () = if ((i.caller != this))
343- then throw("FI: admin only")
344- else [IntegerEntry("total_startHeight", height)]
345-
346-
347-
348-@Callable(i)
349-func buyPerch (colorI,refererAddress) = throw("FBN: function is disabled, migration to new sc ongoing")
350-
351-
352-
353-@Callable(i)
354-func addFreePerch (address,color) = throw("FBN: function is disabled, migration to new sc ongoing")
355-
356-
357-
358-@Callable(i)
359-func stakeNFT () = throw("FBN: function is disabled, migration to new sc ongoing")
360-
361-
362-
363-@Callable(i)
364-func stakeNFTWithoutPerch () = throw("FBN: function is disabled, migration to new sc ongoing")
365-
366-
367-
368-@Callable(i)
369-func unstakeNFT (asset) = {
370- let validPayment = if ((i.caller == getMetaraceAddress()))
371- then nil
372- else checkAdditionalPayment(i.payments[0])
329+func buyPerch (colorI,refererAddress) = {
330+ let validPayment = checkAdditionalPayment(i.payments[0])
373331 if ((validPayment == validPayment))
374332 then {
375- let result = unstakeNFTInternal(asset, i, true)
376- $Tuple2((result._1 ++ validPayment), result._2)
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+ }
377375 }
378376 else throw("Strict value is not equal to itself.")
379377 }
380378
381379
382380
383381 @Callable(i)
384-func unstakeNFTWithoutClaim (asset) = unstakeNFTInternal(asset, i, false)
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+ }
385395
386396
387397
388398 @Callable(i)
389-func stakeJackpot (color) = throw("FBN: function is disabled, migration to new sc ongoing")
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+ }
390419
391420
392421
393422 @Callable(i)
394-func unstakeJackpot (asset) = {
395- let validPayment = checkAdditionalPayment(i.payments[0])
396- if ((validPayment == validPayment))
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))
397479 then {
398- let result = unstakeJackpotInternal(asset, i, true)
399- $Tuple2((result._1 ++ validPayment), result._2)
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.")
400504 }
401505 else throw("Strict value is not equal to itself.")
402506 }
403507
404508
405509
406510 @Callable(i)
407-func unstakeJackpotWithoutClaimEgg (asset) = unstakeJackpotInternal(asset, i, false)
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+ }
408520
409521
410522
411523 @Callable(i)
412-func claimReward (asset) = {
413- let locked = isLocked()
414- if ((locked == locked))
415- then {
416- let validPayment = if ((i.originCaller == getCfMasterAddress()))
417- then nil
418- else checkAdditionalPayment(i.payments[0])
419- if ((validPayment == validPayment))
420- then {
421- let address = if ((i.originCaller == getCfMasterAddress()))
422- then toString(i.caller)
423- else toString(i.originCaller)
424- let assetId = fromBase58String(asset)
425- let assetFarmingPower = getLastKnownAssetFarmingPower(address, asset)
426- let assetRewardDelta = calcAssetRewardDelta(address, asset, assetFarmingPower)
427- let farmedAmount = (assetRewardDelta + tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount")))
428- let withdrawnAmount = tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"))
429- let reward = ((farmedAmount - withdrawnAmount) / (scale * 100))
430- if ((0 >= reward))
431- then throw("FCR: you have no EGGs to withdraw")
432- 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))
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)
433534 }
434- else throw("Strict value is not equal to itself.")
435- }
436535 else throw("Strict value is not equal to itself.")
437536 }
438537
439538

github/deemru/w8io/3ef1775 
88.56 ms