tx · 5q1z9XkgMREj4uSPoFtLQZPaNBHEBoG5Pf4uFbEjtsRf

3N7dQeENwSgKPp9Ki4aEHhRWWKVjn1DE9Qg:  -0.00900000 Waves

2024.09.12 19:18 [3280652] smart account 3N7dQeENwSgKPp9Ki4aEHhRWWKVjn1DE9Qg > SELF 0.00000000 Waves

{ "type": 13, "id": "5q1z9XkgMREj4uSPoFtLQZPaNBHEBoG5Pf4uFbEjtsRf", "fee": 900000, "feeAssetId": null, "timestamp": 1726157945650, "version": 2, "chainId": 84, "sender": "3N7dQeENwSgKPp9Ki4aEHhRWWKVjn1DE9Qg", "senderPublicKey": "5BN6FQeKuMm2XJYToUZvbBX4UELGpE3Z47P4q6sP46PG", "proofs": [ "3BjwZpStr3kefmvaD51Ln7XhHoU27NPmBK1YbxRRs4GrwxntCg9j9jTBvF6EgMNehuoCtGob9RRavbKZjAGGw9bv" ], "script": "base64:BgIeCAISBAoCCAESBAoCAQgSAwoBCBIECgIBCBIDCgEIMQAFY2hhaW4JAMkBAgkAygECCAUEdGhpcwVieXRlcwABAAEAFWRlZmF1bHRSZXN0QWRkcmVzc1N0cgQHJG1hdGNoMAUFY2hhaW4DCQAAAgEBVwUHJG1hdGNoMAIjM1BRQ3V2RmJ2aDRMa1BVbnJuVTF6M2puYkExcDltM1dOaHYDCQAAAgEBVAUHJG1hdGNoMAIjM011bWtHR3p0Q0tBWHBXRHF4a2Rkb2ZxWFNVYnFRa3ZTSnkJAAIBAg1Vbmtub3duIGNoYWluABBhY3JlczJBZGRyZXNzU3RyBAckbWF0Y2gwBQVjaGFpbgMJAAACAQFXBQckbWF0Y2gwAiMzUDRVSDNUOW5YcE1OcFVtU21RalBtRXozRzg1dDN6bjZlQQMJAAACAQFUBQckbWF0Y2gwAiMzTkJQeDFGY2l1M0pRTkVHWjIxalNuVGR1dExOR0dCVVNYaAkAAgECDVVua25vd24gY2hhaW4AA1NFUAICX18ABU1VTFQ4AIDC1y8BD2dldFN0cmluZ09yRmFpbAIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQdhZGRyZXNzBQNrZXkJALkJAgkAzAgCAgptYW5kYXRvcnkgCQDMCAIJAKUIAQUHYWRkcmVzcwkAzAgCAgEuCQDMCAIFA2tleQkAzAgCAg8gaXMgbm90IGRlZmluZWQFA25pbAIAABFJZHhDZmdTdGFraW5nRGFwcAABABFJZHhDZmdFY29ub215RGFwcAACAA1JZHhDZmdXbGdEYXBwAAQAD0lkeENmZ0FjcmVzRGFwcAAIAQprZXlSZXN0Q2ZnAAIOJXNfX3Jlc3RDb25maWcBDmtleVJlc3RBZGRyZXNzAAIMJXNfX3Jlc3RBZGRyARFyZWFkUmVzdENmZ09yRmFpbAEEcmVzdAkAvAkCCQEPZ2V0U3RyaW5nT3JGYWlsAgUEcmVzdAkBCmtleVJlc3RDZmcABQNTRVABGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIHcmVzdENmZwNpZHgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIFB3Jlc3RDZmcFA2lkeAkArAICAipSZXN0IGNmZyBkb2Vzbid0IGNvbnRhaW4gYWRkcmVzcyBhdCBpbmRleCAJAKQDAQUDaWR4AAxyZXN0Q29udHJhY3QJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwkBDmtleVJlc3RBZGRyZXNzAAUVZGVmYXVsdFJlc3RBZGRyZXNzU3RyAAdyZXN0Q2ZnCQERcmVhZFJlc3RDZmdPckZhaWwBBQxyZXN0Q29udHJhY3QAD3N0YWtpbmdDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFB3Jlc3RDZmcFEUlkeENmZ1N0YWtpbmdEYXBwAA9lY29ub215Q29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQdyZXN0Q2ZnBRFJZHhDZmdFY29ub215RGFwcAALd2xnQ29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQdyZXN0Q2ZnBQ1JZHhDZmdXbGdEYXBwAA1hY3Jlc0NvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUHcmVzdENmZwUPSWR4Q2ZnQWNyZXNEYXBwABRhY3Jlc0lzc3VlZEFtb3VudEtleQIRYWNyZXNJc3N1ZWRBbW91bnQAD2FjcmVzQXNzZXRJZEtleQIMYWNyZXNBc3NldElkAAxhY3Jlc0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnAgCBQ1hY3Jlc0NvbnRyYWN0BQ9hY3Jlc0Fzc2V0SWRLZXkCF0FDUkVTIGlzIG5vdCBpc3N1ZWQgeWV0ARhrZXlBY3Jlc1N0YWtlZFRpbWVCeVVzZXIBBGFkZHIJAKwCAgIWYWNyZXNTdGFrZWRUaW1lQnlVc2VyXwUEYWRkcgALSWR4RWZmVG90YWwAAAERa2V5UmVzUHJvcG9ydGlvbnMAAhNyZXNUeXBlc1Byb3BvcnRpb25zARZrZXlTdGFrZWRQaWVjZXNCeU93bmVyAQlvd25lckFkZHIJAKwCAgIUc3Rha2VkUGllY2VzQnlPd25lcl8FCW93bmVyQWRkcgEFYXNJbnQBAXYEByRtYXRjaDAFAXYDCQABAgUHJG1hdGNoMAIDSW50BAFuBQckbWF0Y2gwBQFuCQACAQIVZmFpbCB0byBjYXN0IGludG8gSW50AQ5hc1R3b0ludHNUdXBsZQEDdmFsBAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIKKEludCwgSW50KQQCdDIFByRtYXRjaDAFAnQyCQACAQIcZmFpbCB0byBjYXN0IGludG8gKEludCwgSW50KQEOZ2V0Vm90aW5nUG93ZXIBEnVzZXJBZGRyU3RyT3JFbXB0eQQFcHJvcHMJALUJAgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJARFrZXlSZXNQcm9wb3J0aW9ucwACCzBfMF8wXzBfMF8wAgFfCgEFYWRkZXICA2FjYwRpdGVtCQBkAgUDYWNjCQENcGFyc2VJbnRWYWx1ZQEFBGl0ZW0ECnRvdGFsUG93ZXIKAAIkbAUFcHJvcHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBBWFkZGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGBAp1c2Vyc1Bvd2VyCQELdmFsdWVPckVsc2UCCQCaCAIFD3N0YWtpbmdDb250cmFjdAkBFmtleVN0YWtlZFBpZWNlc0J5T3duZXIBBRJ1c2VyQWRkclN0ck9yRW1wdHkAAAkAzAgCBQp0b3RhbFBvd2VyCQDMCAIFCnVzZXJzUG93ZXIFA25pbAEKZml4ZWRQb2ludAIDdmFsCGRlY2ltYWxzBAZ0ZW5Qb3cJAGwGAAoAAAUIZGVjaW1hbHMAAAAABQRET1dOBAdsb3dQYXJ0CQCkAwEJAGoCBQN2YWwFBnRlblBvdwQGemVyb2VzCQCwAgIJAKQDAQUGdGVuUG93CQBkAgABCQCxAgEFB2xvd1BhcnQJAKwCAgkArAICCQCsAgIJAKQDAQkAaQIFA3ZhbAUGdGVuUG93AgEuBQZ6ZXJvZXMFB2xvd1BhcnQBCWZpbmFsVGltZQAJAJcDAQkAzAgCCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCAJjQgaukMgUDbmlsAA9EQUlMWVJFU0JZUElFQ0UAgPjSAQAVVVNEVDJBQ1JFU19NVUxUSVBMSUVSAAoACE1JTExJT042AICA6YOx3hYACURBWU1JTExJUwCAuJkpARprZXlBY3Jlc1N0YWtlZEFtb3VudEJ5VXNlcgEEYWRkcgkArAICAhhhY3Jlc1N0YWtlZEFtb3VudEJ5VXNlcl8FBGFkZHIBGmtleUFjcmVzTG9ja2VkQW1vdW50QnlVc2VyAQRhZGRyCQCsAgICGGFjcmVzTG9ja2VkQW1vdW50QnlVc2VyXwUEYWRkcgEXa2V5QWNyZXNMb2NrZWRFdGFCeVVzZXIBBGFkZHIJAKwCAgIVYWNyZXNMb2NrZWRFdGFCeVVzZXJfBQRhZGRyABNhY3Jlc1N0YWtlZFRvdGFsS2V5AhZhY3Jlc1N0YWtlZEFtb3VudFRvdGFsAAxCTEFDS0xJU1RFRDEC3wYzUDJOR1g0UTVuZ2UxTUNhdXdRVzVhcVlMZGtjY1NHajFFcF8zUDJ4RkFIVzl5aHlOb2hZb3pXZDRIRmhFWFp1M2JzTlNvUl8zUDJ5S2FaMmd2bjlYZTV0dGk4MWE3UDlMWmhIZ2p2VG9WOV8zUDM3elEzY2YyZWN1NTVSbUpxRWlHU2l2ZHpOOWF2dDNtOV8zUDRhejZkdHpzdkdDV0ZBeGE5NFVkZXZLelh5RXd4RWlGR18zUDRrWlU2WDNUVExGY1NVZTU1SlN5OEJ5U3FpdGNQZ01Cel8zUDVoQ3hCRWgzTmdOaXpaaE5CcmV5QlNxdGJoSllMa0tQRF8zUDdITHZ1Y3kxMXl4eU1KVXdqelhGSEhLTUVEd2kxRXdmQ18zUDhKdWFxSDlQVFFBdjhENUhCR2dRZkthdUxUWXQyTlFmdF8zUDlnVERCNHJ0REVWYnBYM2FzVTYzSDRaaW5oMkVuVG1aRV8zUDlpTjNxcnRmSmljVVZ5N2FtWmVWc2V0VkQzdlVNazhiZV8zUENhMkJzQWE2SkJMaXJzelFmVjVyOWZKcnVqZmh3dHdmUF8zUEQzaTRYTjhLdHlnY0Z4NHJ5NU03VUdxZGZIOFZZdnRSVF8zUERFTW5uSk5jMmt4OWNQRW12VnZoWFVyOFN2aEFOS2hzYV8zUERHRTl0S1FpemFlWkZlRERxNWFZU3Y4OW53WWJmaXJwWl8zUERNS1FUQ3JVUFpFQ1ZYRUpKOG0xc0h0dXRTdTFuYVNmMV8zUEdoMlF1Nll2eDhHVENSUlZOdkJVVlpMZGFpZFlTYXhvNV8zUEtrbUF0YlNLNUQyaFFkbzFSZkVnOGVYeU1iRGNSVWM5Ml8zUExNbmJ4enNzUDhXOEU4WGpKMVJMQkJnOFVaTDhDejNQMl8zUE11eG80UENBb3g5czRhN1IxZXN6aDRpcXF1OGdTN2pIdl8zUE5yTXRFUUNodzg3V1pVMUpBSjdhR0h5a0NhOFRqbkROS18zUFB1QlhmV29CeTNFRW9yeTdjN3ZnaTlVc2prYTdvNXRCal8zUFF3eWV5RWhUNFk2YUdBTDZ0ZzczYVFXSnRWMXpSdDNuUl8zUFJHRFNodU1HYjg0TUp0VEp2dFRnOHFEZnN3a1lXY20zZQANUFJPTU8xX0FNT1VOVADCra8CABdQUk9NT18yX1NUQVJUX1RJTUVTVEFNUAQHJG1hdGNoMAUFY2hhaW4DCQAAAgEBVwUHJG1hdGNoMACA8LT5vjEDCQAAAgEBVAUHJG1hdGNoMACA59DHvjEJAAIBAg1Vbmtub3duIGNoYWluABVQUk9NT18yX0VORF9USU1FU1RBTVAEByRtYXRjaDAFBWNoYWluAwkAAAIBAVcFByRtYXRjaDAA/7/N8MAxAwkAAAIBAVQFByRtYXRjaDAAgIjX674xCQACAQINVW5rbm93biBjaGFpbgETaXNCbGFja2xpc3RlZFByb21vMQEEYWRkcgkBCGNvbnRhaW5zAgUMQkxBQ0tMSVNURUQxBQRhZGRyARJjbGFpbUFjcmVzSW50ZXJuYWwDBGFkZHILYWNyZXNBbW91bnQNbGFzdENsYWltVGltZQQJZGVsdGFUaW1lCQBlAgkBCWZpbmFsVGltZQAFDWxhc3RDbGFpbVRpbWUECGF2YWlsUmVzCQBrAwUJZGVsdGFUaW1lCQBoAgUPREFJTFlSRVNCWVBJRUNFBQthY3Jlc0Ftb3VudAkAaAIFCURBWU1JTExJUwUFTVVMVDgECmNhbkdldFVzZHQJAQVhc0ludAEJAPwHBAUPZWNvbm9teUNvbnRyYWN0AhpzZWxsUmVzb3VyY2VzV29ybGRSRUFET05MWQkAzAgCBQhhdmFpbFJlcwUDbmlsBQNuaWwEB2dvdFVzZHQJAJYDAQkAzAgCAAAJAMwIAgUKY2FuR2V0VXNkdAUDbmlsCQBoAgUHZ290VXNkdAUVVVNEVDJBQ1JFU19NVUxUSVBMSUVSAQ1jbGFpbUludGVybmFsAwRhZGRyC2FjcmVzQW1vdW50DWxhc3RDbGFpbVRpbWUECWRlbHRhVGltZQkAZQIJAQlmaW5hbFRpbWUABQ1sYXN0Q2xhaW1UaW1lAwkAZgIAAAUJZGVsdGFUaW1lCQACAQkArAICCQCsAgIJAKwCAgImU2F2ZWQgdGltZXN0YW1wIGlzIGluIGZ1dHVyZSwgc2F2ZWQgPSAJAKQDAQUNbGFzdENsYWltVGltZQIKLCBmaW5hbCA9IAkApAMBCQEJZmluYWxUaW1lAAQIYXZhaWxSZXMJAGsDBQlkZWx0YVRpbWUJAGgCBQ9EQUlMWVJFU0JZUElFQ0UFC2FjcmVzQW1vdW50CQBoAgUJREFZTUlMTElTBQVNVUxUOAQKY2FuR2V0VXNkdAkBBWFzSW50AQkA/AcEBQ9lY29ub215Q29udHJhY3QCGnNlbGxSZXNvdXJjZXNXb3JsZFJFQURPTkxZCQDMCAIFCGF2YWlsUmVzBQNuaWwFA25pbAQHZ290VXNkdAMJAGcCAAAFCmNhbkdldFVzZHQAAAgJAQ5hc1R3b0ludHNUdXBsZQEJAPwHBAUPZWNvbm9teUNvbnRyYWN0AhJzZWxsUmVzb3VyY2VzV29ybGQJAMwIAgUEYWRkcgkAzAgCBQhhdmFpbFJlcwUDbmlsBQNuaWwCXzEJAGgCBQdnb3RVc2R0BRVVU0RUMkFDUkVTX01VTFRJUExJRVIBDnVuc3Rha2VBY3Jlc1JPAgZhbW91bnQHYWRkcmVzcwQHdGltZUtleQkBGGtleUFjcmVzU3Rha2VkVGltZUJ5VXNlcgEFB2FkZHJlc3MEDGNsYWltZWRBY3JlcwkBEmNsYWltQWNyZXNJbnRlcm5hbAMFB2FkZHJlc3MFBmFtb3VudAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQd0aW1lS2V5AAAJAGQCBQZhbW91bnQFDGNsYWltZWRBY3JlcwEUdW5zdGFrZUFjcmVzSW50ZXJuYWwCBmFtb3VudAdhZGRyZXNzAwkAZwIAAAUGYW1vdW50CQACAQIZQW1vdW50IHNob3VsZCBiZSBwb3NpdGl2ZQQHdGltZUtleQkBGGtleUFjcmVzU3Rha2VkVGltZUJ5VXNlcgEFB2FkZHJlc3MECWFtb3VudEtleQkBGmtleUFjcmVzU3Rha2VkQW1vdW50QnlVc2VyAQUHYWRkcmVzcwQOb2xkQWNyZXNBbW91bnQJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJYW1vdW50S2V5AAADCQBmAgUGYW1vdW50BQ5vbGRBY3Jlc0Ftb3VudAkAAgEJAKwCAgkArAICCQCsAgICDllvdSBoYXZlIG9ubHkgCQEKZml4ZWRQb2ludAIFDm9sZEFjcmVzQW1vdW50AAgCICBBQ1JFUyBzdGFrZWQsIHRyaWVkIHRvIHVuc3Rha2UgCQEKZml4ZWRQb2ludAIFBmFtb3VudAAIBAxsb2NrZWRBbW91bnQJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBGmtleUFjcmVzTG9ja2VkQW1vdW50QnlVc2VyAQUHYWRkcmVzcwAABAlsb2NrZWRFVEEJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBF2tleUFjcmVzTG9ja2VkRXRhQnlVc2VyAQUHYWRkcmVzcwAABANub3cIBQlsYXN0QmxvY2sJdGltZXN0YW1wAwMJAGcCBQNub3cFF1BST01PXzJfU1RBUlRfVElNRVNUQU1QCQBnAgUVUFJPTU9fMl9FTkRfVElNRVNUQU1QBQNub3cHCQACAQImWW91IGNhbm5vdCB1bnN0YWtlIEFDUkVTIGR1cmluZyBQcm9tbzIEEHVuc3Rha2FibGVBbW91bnQDCQETaXNCbGFja2xpc3RlZFByb21vMQEFB2FkZHJlc3MJAGUCCQBlAgUOb2xkQWNyZXNBbW91bnQFDGxvY2tlZEFtb3VudAUNUFJPTU8xX0FNT1VOVAkAZQIFDm9sZEFjcmVzQW1vdW50BQxsb2NrZWRBbW91bnQDAwkAZgIFCWxvY2tlZEVUQQUDbm93CQBmAgUGYW1vdW50BRB1bnN0YWthYmxlQW1vdW50BwkAAgEJAKwCAgkArAICCQCsAgICBU9ubHkgCQEKZml4ZWRQb2ludAIFEHVuc3Rha2FibGVBbW91bnQACAInIEFDUkVTIGNhbiBiZSB1bnN0YWtlZCBub3csIHdhaXQgdW50aWwgCQCkAwEFCWxvY2tlZEVUQQQIb2xkVG90YWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUTYWNyZXNTdGFrZWRUb3RhbEtleQAABAl3bGdSZXN1bHQJAPwHBAULd2xnQ29udHJhY3QCEm9uU3Rha2VVbnN0YWtlTGFuZAkAzAgCBQdhZGRyZXNzBQNuaWwFA25pbAQMY2xhaW1lZEFjcmVzCQENY2xhaW1JbnRlcm5hbAMFB2FkZHJlc3MFDm9sZEFjcmVzQW1vdW50CQELdmFsdWVPckVsc2UCCQCfCAEFB3RpbWVLZXkAAAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQd0aW1lS2V5CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQEMSW50ZWdlckVudHJ5AgUJYW1vdW50S2V5CQBlAgUOb2xkQWNyZXNBbW91bnQFBmFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgUTYWNyZXNTdGFrZWRUb3RhbEtleQkAZQIFCG9sZFRvdGFsBQZhbW91bnQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwkBEUBleHRyTmF0aXZlKDEwNjIpAQUHYWRkcmVzcwkAZAIFBmFtb3VudAUMY2xhaW1lZEFjcmVzBQxhY3Jlc0Fzc2V0SWQFA25pbAkAlAoCCQBkAgUGYW1vdW50BQxjbGFpbWVkQWNyZXMFCXdsZ1Jlc3VsdAUBaQENY29uc3RydWN0b3JWMQIIcmVzdEFkZHIOdW5zdGFrZWRQaWVjZXMDCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAMJAQlpc0RlZmluZWQBCQChCAEFD2FjcmVzQXNzZXRJZEtleQkAAgECE0FscmVhZHkgaW5pdGlhbGl6ZWQECG5mdEFjcmVzCQBkAgkAkQMCCQEOZ2V0Vm90aW5nUG93ZXIBAgAFC0lkeEVmZlRvdGFsBQ51bnN0YWtlZFBpZWNlcwQMaXNzdWVkQW1vdW50CQBlAgUITUlMTElPTjYJAGgCBQhuZnRBY3JlcwUFTVVMVDgEBWlzc3VlCQDDCAcCBUFDUkVTAiZXYXZlc0xhbmRzIGxhbmQgYWNyZXMgaW52ZXN0bWVudCB0b2tlbgUMaXNzdWVkQW1vdW50AAgHBQR1bml0AAAEB2Fzc2V0SWQJALgIAQUFaXNzdWUJAMwIAgUFaXNzdWUJAMwIAgkBDEludGVnZXJFbnRyeQIFFGFjcmVzSXNzdWVkQW1vdW50S2V5BQxpc3N1ZWRBbW91bnQJAMwIAgkBC0JpbmFyeUVudHJ5AgUPYWNyZXNBc3NldElkS2V5BQdhc3NldElkCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ5rZXlSZXN0QWRkcmVzcwAFCHJlc3RBZGRyBQNuaWwBaQEUdW5zdGFrZUFjcmVzQ2FsbGJhY2sCBmFtb3VudAdhZGRyZXNzAwkBAiE9AgkApQgBCAUBaQZjYWxsZXIFEGFjcmVzMkFkZHJlc3NTdHIJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAkBFHVuc3Rha2VBY3Jlc0ludGVybmFsAgUGYW1vdW50BQdhZGRyZXNzAWkBF3Vuc3Rha2VBbGxBY3Jlc1JFQURPTkxZAQdhZGRyZXNzBAZhbW91bnQJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBGmtleUFjcmVzU3Rha2VkQW1vdW50QnlVc2VyAQUHYWRkcmVzcwAABBN1bnN0YWtlZFdpdGhDbGFpbWVkCQEOdW5zdGFrZUFjcmVzUk8CBQZhbW91bnQFB2FkZHJlc3MJAJQKAgUDbmlsBRN1bnN0YWtlZFdpdGhDbGFpbWVkAWkBFHJlcXVlc3RBY3Jlc0NhbGxiYWNrAgZhbW91bnQHYWRkcmVzcwMJAQIhPQIJAKUIAQgFAWkGY2FsbGVyBRBhY3JlczJBZGRyZXNzU3RyCQACAQIRUGVybWlzc2lvbiBkZW5pZWQJAJQKAgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCQERQGV4dHJOYXRpdmUoMTA2MikBBQdhZGRyZXNzBQZhbW91bnQFDGFjcmVzQXNzZXRJZAUDbmlsBQZhbW91bnQBaQESY2xhaW1BY3Jlc1JFQURPTkxZAQdhZGRyZXNzBAd0aW1lS2V5CQEYa2V5QWNyZXNTdGFrZWRUaW1lQnlVc2VyAQUHYWRkcmVzcwQJYW1vdW50S2V5CQEaa2V5QWNyZXNTdGFrZWRBbW91bnRCeVVzZXIBBQdhZGRyZXNzBAthY3Jlc0Ftb3VudAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlhbW91bnRLZXkAAAQIbGFzdFRpbWUJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUHdGltZUtleQAABAxjbGFpbWVkQWNyZXMJARJjbGFpbUFjcmVzSW50ZXJuYWwDBQdhZGRyZXNzBQthY3Jlc0Ftb3VudAUIbGFzdFRpbWUJAJQKAgUDbmlsCQDMCAIFDGNsYWltZWRBY3JlcwkAzAgCBQhsYXN0VGltZQUDbmlsAPCwPKI=", "height": 3280652, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: B7rSLVnk7Tbfvz5SN81iVfcCjqekinxBH9Ydt7E7EkEp Next: 95ubc5EYtRyPPJgZokfyZ1SMfA8MXfRCn9XuJDXWckAh Diff:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let MILLION6 = 100000000000000
5-
6-let DAYMILLIS = 86400000
7-
8-func keyAcresStakedAmountByUser (addr) = ("acresStakedAmountByUser_" + addr)
9-
10-
11-func keyAcresLockedAmountByUser (addr) = ("acresLockedAmountByUser_" + addr)
12-
13-
14-func keyAcresLockedEtaByUser (addr) = ("acresLockedEtaByUser_" + addr)
15-
16-
17-let acresStakedTotalKey = "acresStakedAmountTotal"
18-
19-let xpNewSLand = 5000000
20-
21-let DAILYRESBYPIECE = 3456000
22-
23-let USDT2ACRES_MULTIPLIER = 10
24-
25-func keyIsAwardedByPromoAndUser (promoId,addr) = makeString(["%s%d%s__isAwardedByPromoAndUser", toString(promoId), addr], "__")
26-
27-
28-func keyTicketsTotalByPromo (promoId) = ("%s%d__ticketsTotalByPromo__" + toString(promoId))
29-
30-
31-func keyTicketsTotalByPromoAndRound (promoId,roundId) = makeString(["%s%d%d__ticketsTotalByPromoAndRound", toString(promoId), toString(roundId)], "__")
32-
33-
344 let chain = take(drop(this.bytes, 1), 1)
35-
36-let usdtAssetId = match chain {
37- case _ =>
38- if ((base58'2W' == $match0))
39- then base58'9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi'
40- else if ((base58'2T' == $match0))
41- then base58'6mWwf9mZBjVgkC54idpyaZLQfAosD914wT8fGf2iiY63'
42- else throw("Unknown chain")
43-}
445
456 let defaultRestAddressStr = match chain {
467 case _ =>
5112 else throw("Unknown chain")
5213 }
5314
54-let promo2MapKey = "promo2Map"
55-
56-func keyPromo2MapForRound (roundId) = ("promo2MapForRound__" + toString(roundId))
57-
58-
59-func keyPromo4MapForRound (roundId) = ("promo4MapForRound__" + toString(roundId))
60-
15+let acres2AddressStr = match chain {
16+ case _ =>
17+ if ((base58'2W' == $match0))
18+ then "3P4UH3T9nXpMNpUmSmQjPmEz3G85t3zn6eA"
19+ else if ((base58'2T' == $match0))
20+ then "3NBPx1Fciu3JQNEGZ21jSnTdutLNGGBUSXh"
21+ else throw("Unknown chain")
22+}
6123
6224 let SEP = "__"
6325
64-let MULT6 = 1000000
65-
6626 let MULT8 = 100000000
67-
68-let ITER6 = [0, 1, 2, 3, 4, 5]
6927
7028 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
7129
11371
11472 let IdxEffTotal = 0
11573
116-let randomDelay = 2
117-
118-func keyCommit (address) = ("finishBlockFor_" + address)
119-
120-
12174 func keyResProportions () = "resTypesProportions"
12275
12376
13891 case _ =>
13992 throw("fail to cast into (Int, Int)")
14093 }
141-
142-
143-func keyLastTxIdByUser (addr) = ("lastTxIdByUser_" + addr)
14494
14595
14696 func getVotingPower (userAddrStrOrEmpty) = {
174124 }
175125
176126
177-func padL (val,len) = {
178- let valS = toString(val)
179- let zeroes = drop(toString(pow(10, 0, (len - size(valS)), 0, 0, DOWN)), 1)
180- (zeroes + valS)
181- }
127+func finalTime () = min([lastBlock.timestamp, 1727740799000])
182128
183129
184-func getRandomNumber (maxValue,salt,entropy) = if ((0 >= maxValue))
185- then throw("maxValue should be > 0")
186- else {
187- let randomHash = sha256((salt + entropy))
188- (toInt(randomHash) % maxValue)
189- }
130+let DAILYRESBYPIECE = 3456000
131+
132+let USDT2ACRES_MULTIPLIER = 10
133+
134+let MILLION6 = 100000000000000
135+
136+let DAYMILLIS = 86400000
137+
138+func keyAcresStakedAmountByUser (addr) = ("acresStakedAmountByUser_" + addr)
190139
191140
192-let MIN_ACRES_AMOUNT_DURING_PROMO = 10000000
141+func keyAcresLockedAmountByUser (addr) = ("acresLockedAmountByUser_" + addr)
142+
143+
144+func keyAcresLockedEtaByUser (addr) = ("acresLockedEtaByUser_" + addr)
145+
146+
147+let acresStakedTotalKey = "acresStakedAmountTotal"
193148
194149 let BLACKLISTED1 = "3P2NGX4Q5nge1MCauwQW5aqYLdkccSGj1Ep_3P2xFAHW9yhyNohYozWd4HFhEXZu3bsNSoR_3P2yKaZ2gvn9Xe5tti81a7P9LZhHgjvToV9_3P37zQ3cf2ecu55RmJqEiGSivdzN9avt3m9_3P4az6dtzsvGCWFAxa94UdevKzXyEwxEiFG_3P4kZU6X3TTLFcSUe55JSy8BySqitcPgMBz_3P5hCxBEh3NgNizZhNBreyBSqtbhJYLkKPD_3P7HLvucy11yxyMJUwjzXFHHKMEDwi1EwfC_3P8JuaqH9PTQAv8D5HBGgQfKauLTYt2NQft_3P9gTDB4rtDEVbpX3asU63H4Zinh2EnTmZE_3P9iN3qrtfJicUVy7amZeVsetVD3vUMk8be_3PCa2BsAa6JBLirszQfV5r9fJrujfhwtwfP_3PD3i4XN8KtygcFx4ry5M7UGqdfH8VYvtRT_3PDEMnnJNc2kx9cPEmvVvhXUr8SvhANKhsa_3PDGE9tKQizaeZFeDDq5aYSv89nwYbfirpZ_3PDMKQTCrUPZECVXEJJ8m1sHtutSu1naSf1_3PGh2Qu6Yvx8GTCRRVNvBUVZLdaidYSaxo5_3PKkmAtbSK5D2hQdo1RfEg8eXyMbDcRUc92_3PLMnbxzssP8W8E8XjJ1RLBBg8UZL8Cz3P2_3PMuxo4PCAox9s4a7R1eszh4iqqu8gS7jHv_3PNrMtEQChw87WZU1JAJ7aGHykCa8TjnDNK_3PPuBXfWoBy3EEory7c7vgi9Usjka7o5tBj_3PQwyeyEhT4Y6aGAL6tg73aQWJtV1zRt3nR_3PRGDShuMGb84MJtTJvtTg8qDfswkYWcm3e"
195150
213168 else throw("Unknown chain")
214169 }
215170
216-let PROMO_2_DISTRIBUTION_FUND = 1000000000
217-
218-let promo4NumPrizesPerRound = [1, 5]
219-
220-let promo4AwardPerRound = [500000000, 100000000]
221-
222171 func isBlacklistedPromo1 (addr) = contains(BLACKLISTED1, addr)
223172
224173
225-func prolog () = asInt(reentrantInvoke(stakingContract, "saveLastTx", nil, nil))
226-
227-
228174 func claimAcresInternal (addr,acresAmount,lastClaimTime) = {
229- let deltaTime = (lastBlock.timestamp - lastClaimTime)
175+ let deltaTime = (finalTime() - lastClaimTime)
230176 let availRes = fraction(deltaTime, (DAILYRESBYPIECE * acresAmount), (DAYMILLIS * MULT8))
231177 let canGetUsdt = asInt(invoke(economyContract, "sellResourcesWorldREADONLY", [availRes], nil))
232178 let gotUsdt = max([0, canGetUsdt])
235181
236182
237183 func claimInternal (addr,acresAmount,lastClaimTime) = {
238- let deltaTime = (lastBlock.timestamp - lastClaimTime)
184+ let deltaTime = (finalTime() - lastClaimTime)
239185 if ((0 > deltaTime))
240- then throw(((("Saved timestamp is in future, saved = " + toString(lastClaimTime)) + ", current = ") + toString(lastBlock.timestamp)))
186+ then throw(((("Saved timestamp is in future, saved = " + toString(lastClaimTime)) + ", final = ") + toString(finalTime())))
241187 else {
242188 let availRes = fraction(deltaTime, (DAILYRESBYPIECE * acresAmount), (DAYMILLIS * MULT8))
243189 let canGetUsdt = asInt(invoke(economyContract, "sellResourcesWorldREADONLY", [availRes], nil))
249195 }
250196
251197
252-func mergeLocked (oldAmount,oldETA,newAmount,newETA) = {
253- let now = lastBlock.timestamp
254- let dt1 = max([0, (oldETA - now)])
255- let dt2 = max([0, (newETA - now)])
256- let sum = (oldAmount + newAmount)
257- let dt = if ((sum == 0))
258- then 0
259- else (fraction(dt1, oldAmount, sum) + fraction(dt2, newAmount, sum))
260- (now + dt)
198+func unstakeAcresRO (amount,address) = {
199+ let timeKey = keyAcresStakedTimeByUser(address)
200+ let claimedAcres = claimAcresInternal(address, amount, valueOrElse(getInteger(timeKey), 0))
201+ (amount + claimedAcres)
261202 }
203+
204+
205+func unstakeAcresInternal (amount,address) = if ((0 >= amount))
206+ then throw("Amount should be positive")
207+ else {
208+ let timeKey = keyAcresStakedTimeByUser(address)
209+ let amountKey = keyAcresStakedAmountByUser(address)
210+ let oldAcresAmount = valueOrElse(getInteger(amountKey), 0)
211+ if ((amount > oldAcresAmount))
212+ then throw(((("You have only " + fixedPoint(oldAcresAmount, 8)) + " ACRES staked, tried to unstake ") + fixedPoint(amount, 8)))
213+ else {
214+ let lockedAmount = valueOrElse(getInteger(keyAcresLockedAmountByUser(address)), 0)
215+ let lockedETA = valueOrElse(getInteger(keyAcresLockedEtaByUser(address)), 0)
216+ let now = lastBlock.timestamp
217+ if (if ((now >= PROMO_2_START_TIMESTAMP))
218+ then (PROMO_2_END_TIMESTAMP >= now)
219+ else false)
220+ then throw("You cannot unstake ACRES during Promo2")
221+ else {
222+ let unstakableAmount = if (isBlacklistedPromo1(address))
223+ then ((oldAcresAmount - lockedAmount) - PROMO1_AMOUNT)
224+ else (oldAcresAmount - lockedAmount)
225+ if (if ((lockedETA > now))
226+ then (amount > unstakableAmount)
227+ else false)
228+ then throw(((("Only " + fixedPoint(unstakableAmount, 8)) + " ACRES can be unstaked now, wait until ") + toString(lockedETA)))
229+ else {
230+ let oldTotal = valueOrElse(getInteger(acresStakedTotalKey), 0)
231+ let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [address], nil)
232+ let claimedAcres = claimInternal(address, oldAcresAmount, valueOrElse(getInteger(timeKey), 0))
233+ $Tuple2([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(amountKey, (oldAcresAmount - amount)), IntegerEntry(acresStakedTotalKey, (oldTotal - amount)), ScriptTransfer(addressFromStringValue(address), (amount + claimedAcres), acresAssetId)], $Tuple2((amount + claimedAcres), wlgResult))
234+ }
235+ }
236+ }
237+ }
262238
263239
264240 @Callable(i)
277253
278254
279255 @Callable(i)
280-func unstakeAcres (amount) = {
281- let prologResult = prolog()
282- if ((prologResult == prologResult))
283- then if ((0 >= amount))
284- then throw("Amount should be positive")
285- else {
286- let address = toString(i.caller)
287- if ((size(i.payments) != 0))
288- then throw("No payments required")
289- else {
290- let timeKey = keyAcresStakedTimeByUser(address)
291- let amountKey = keyAcresStakedAmountByUser(address)
292- let oldAcresAmount = valueOrElse(getInteger(amountKey), 0)
293- if ((amount > oldAcresAmount))
294- then throw(((("You have only " + fixedPoint(oldAcresAmount, 8)) + " ACRES staked, tried to unstake ") + fixedPoint(amount, 8)))
295- else {
296- let lockedAmount = valueOrElse(getInteger(keyAcresLockedAmountByUser(address)), 0)
297- let lockedETA = valueOrElse(getInteger(keyAcresLockedEtaByUser(address)), 0)
298- let now = lastBlock.timestamp
299- if (if ((now >= PROMO_2_START_TIMESTAMP))
300- then (PROMO_2_END_TIMESTAMP >= now)
301- else false)
302- then throw("You cannot unstake ACRES during Promo2")
303- else {
304- let unstakableAmount = if (isBlacklistedPromo1(address))
305- then ((oldAcresAmount - lockedAmount) - PROMO1_AMOUNT)
306- else (oldAcresAmount - lockedAmount)
307- if (if ((lockedETA > now))
308- then (amount > unstakableAmount)
309- else false)
310- then throw(((("Only " + fixedPoint(unstakableAmount, 8)) + " ACRES can be unstaked now, wait until ") + toString(lockedETA)))
311- else {
312- let oldTotal = valueOrElse(getInteger(acresStakedTotalKey), 0)
313- let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [address], nil)
314- let claimedAcres = claimInternal(address, oldAcresAmount, valueOrElse(getInteger(timeKey), 0))
315- $Tuple2([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(amountKey, (oldAcresAmount - amount)), IntegerEntry(acresStakedTotalKey, (oldTotal - amount)), ScriptTransfer(i.caller, (amount + claimedAcres), acresAssetId)], $Tuple2(prologResult, wlgResult))
316- }
317- }
318- }
319- }
320- }
321- else throw("Strict value is not equal to itself.")
256+func unstakeAcresCallback (amount,address) = if ((toString(i.caller) != acres2AddressStr))
257+ then throw("Permission denied")
258+ else unstakeAcresInternal(amount, address)
259+
260+
261+
262+@Callable(i)
263+func unstakeAllAcresREADONLY (address) = {
264+ let amount = valueOrElse(getInteger(keyAcresStakedAmountByUser(address)), 0)
265+ let unstakedWithClaimed = unstakeAcresRO(amount, address)
266+ $Tuple2(nil, unstakedWithClaimed)
322267 }
323268
324269
325270
326271 @Callable(i)
327-func stakeAcres () = {
328- let prologResult = prolog()
329- if ((prologResult == prologResult))
330- then {
331- let address = toString(i.caller)
332- if ((size(i.payments) != 1))
333- then throw("exactly 1 payment must be attached")
334- else {
335- let pmt = i.payments[0]
336- let amt = pmt.amount
337- if (if (!(isDefined(pmt.assetId)))
338- then true
339- else (value(pmt.assetId) != acresAssetId))
340- then throw("ACRES payments only!")
341- else {
342- let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [address], nil)
343- if ((wlgResult == wlgResult))
344- then {
345- let now = lastBlock.timestamp
346- if (if ((PROMO_2_START_TIMESTAMP > now))
347- then true
348- else (now > PROMO_2_END_TIMESTAMP))
349- then {
350- let timeKey = keyAcresStakedTimeByUser(address)
351- let amountKey = keyAcresStakedAmountByUser(address)
352- let oldAcresAmount = valueOrElse(getInteger(amountKey), 0)
353- let oldTotal = valueOrElse(getInteger(acresStakedTotalKey), 0)
354- let claimedAcres = claimInternal(address, oldAcresAmount, valueOrElse(getInteger(timeKey), 0))
355- $Tuple2(((((if ((claimedAcres == 0))
356- then nil
357- else [ScriptTransfer(i.caller, claimedAcres, acresAssetId)]) :+ IntegerEntry(timeKey, lastBlock.timestamp)) :+ IntegerEntry(amountKey, (oldAcresAmount + amt))) :+ IntegerEntry(acresStakedTotalKey, (oldTotal + amt))), $Tuple2(prologResult, wlgResult))
358- }
359- else if ((MIN_ACRES_AMOUNT_DURING_PROMO > amt))
360- then throw((("Min staked amount during promo action should be at least " + fixedPoint(MIN_ACRES_AMOUNT_DURING_PROMO, 8)) + " ACRES"))
361- else {
362- let stakeResult = invoke(this, "sendLockedAcres", [address, amt, 30], nil)
363- let promo2Map = valueOrElse(getString(promo2MapKey), "")
364- let newMap2 = if (contains(promo2Map, address))
365- then {
366- let parts = split_51C(promo2Map, address)
367- let oldAmount = parseIntValue(take(drop(parts[1], 1), 14))
368- ((((parts[0] + address) + ":") + padL((oldAmount + amt), 14)) + drop(parts[1], 15))
369- }
370- else {
371- let finalPart = ((address + ":") + padL(amt, 14))
372- if ((promo2Map == ""))
373- then finalPart
374- else ((promo2Map + "_") + finalPart)
375- }
376- $Tuple2([StringEntry(promo2MapKey, newMap2)], $Tuple3(prologResult, wlgResult, stakeResult))
377- }
378- }
379- else throw("Strict value is not equal to itself.")
380- }
381- }
382- }
383- else throw("Strict value is not equal to itself.")
384- }
385-
386-
387-
388-@Callable(i)
389-func buyAcres () = {
390- let prologResult = prolog()
391- if ((prologResult == prologResult))
392- then {
393- let address = toString(i.caller)
394- if ((size(i.payments) != 1))
395- then throw("exactly 1 payment must be attached")
396- else {
397- let pmt = i.payments[0]
398- let amt = pmt.amount
399- if (if (!(isDefined(pmt.assetId)))
400- then true
401- else (value(pmt.assetId) != usdtAssetId))
402- then throw("USDT payments only!")
403- else if ((MULT6 > amt))
404- then throw((("Min payment should be " + fixedPoint(MULT6, 6)) + " USDT"))
405- else {
406- let acresAmount = (amt * USDT2ACRES_MULTIPLIER)
407- let accStatsResult = asInt(invoke(stakingContract, "updateAccStats", [address, fraction(xpNewSLand, acresAmount, (25 * MULT8))], nil))
408- $Tuple2([ScriptTransfer(economyContract, amt, usdtAssetId), ScriptTransfer(i.caller, acresAmount, acresAssetId)], $Tuple2(prologResult, accStatsResult))
409- }
410- }
411- }
412- else throw("Strict value is not equal to itself.")
413- }
414-
415-
416-
417-@Callable(i)
418-func sendAcres (addr,amount) = if ((i.caller != economyContract))
272+func requestAcresCallback (amount,address) = if ((toString(i.caller) != acres2AddressStr))
419273 then throw("Permission denied")
420- else $Tuple2([ScriptTransfer(addressFromStringValue(addr), amount, acresAssetId)], amount)
421-
422-
423-
424-@Callable(i)
425-func sendLockedAcres (addr,amount,lockDays) = if (if ((i.caller != this))
426- then (i.caller != restContract)
427- else false)
428- then throw("Permission denied")
429- else {
430- let now = lastBlock.timestamp
431- let timeKey = keyAcresStakedTimeByUser(addr)
432- let amountKey = keyAcresStakedAmountByUser(addr)
433- let oldAcresAmount = valueOrElse(getInteger(amountKey), 0)
434- let oldTotal = valueOrElse(getInteger(acresStakedTotalKey), 0)
435- let timeAction = if (isDefined(getInteger(timeKey)))
436- then nil
437- else [IntegerEntry(timeKey, now)]
438- let etaKey = keyAcresLockedEtaByUser(addr)
439- let lockedAmountKey = keyAcresLockedAmountByUser(addr)
440- let oldLockedAmount = valueOrElse(getInteger(lockedAmountKey), 0)
441- let oldLockedETA = valueOrElse(getInteger(etaKey), 0)
442- let mergedETA = mergeLocked(oldLockedAmount, oldLockedETA, amount, (now + (lockDays * DAYMILLIS)))
443- $Tuple2(((((timeAction :+ IntegerEntry(amountKey, (oldAcresAmount + amount))) :+ IntegerEntry(acresStakedTotalKey, (oldTotal + amount))) :+ IntegerEntry(etaKey, mergedETA)) :+ IntegerEntry(lockedAmountKey, (oldLockedAmount + amount))), amount)
444- }
445-
446-
447-
448-@Callable(i)
449-func burnAcres (amount) = if ((i.caller != stakingContract))
450- then throw("Permission denied")
451- else {
452- let amountLeft = (valueOrElse(getInteger(acresIssuedAmountKey), 0) - amount)
453- if ((0 > amountLeft))
454- then throw("Attempt to burn more ACRES, than exists")
455- else $Tuple2([Burn(acresAssetId, amount), IntegerEntry(acresIssuedAmountKey, amountLeft)], amount)
456- }
457-
458-
459-
460-@Callable(i)
461-func claimAcres () = {
462- let prologResult = prolog()
463- if ((prologResult == prologResult))
464- then {
465- let address = toString(i.caller)
466- if ((size(i.payments) != 0))
467- then throw("No payments required")
468- else {
469- let timeKey = keyAcresStakedTimeByUser(address)
470- let amountKey = keyAcresStakedAmountByUser(address)
471- let acresAmount = valueOrElse(getInteger(amountKey), 0)
472- let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [address], nil)
473- let claimedAcres = claimInternal(address, acresAmount, valueOrElse(getInteger(timeKey), 0))
474- $Tuple2([IntegerEntry(timeKey, lastBlock.timestamp), ScriptTransfer(i.caller, claimedAcres, acresAssetId)], $Tuple2(prologResult, wlgResult))
475- }
476- }
477- else throw("Strict value is not equal to itself.")
478- }
274+ else $Tuple2([ScriptTransfer(addressFromStringValue(address), amount, acresAssetId)], amount)
479275
480276
481277
490286 }
491287
492288
493-
494-@Callable(i)
495-func claimPromo2 () = {
496- let prologResult = prolog()
497- if ((prologResult == prologResult))
498- then {
499- let address = toString(i.caller)
500- if ((size(i.payments) != 0))
501- then throw("No payments required")
502- else {
503- let now = lastBlock.timestamp
504- if ((PROMO_2_END_TIMESTAMP > now))
505- then throw("Promo 2 is not over yet")
506- else {
507- let awardedKey = keyIsAwardedByPromoAndUser(2, address)
508- if (valueOrElse(getBoolean(awardedKey), false))
509- then throw((("Your wallet " + address) + " is already awarded in promo 2"))
510- else {
511- let promo2Map = valueOrElse(getString(promo2MapKey), "")
512- if (!(contains(promo2Map, address)))
513- then throw("You are not participant of promo 2")
514- else {
515- let parts = split_51C(promo2Map, address)
516- let acresAmount = parseIntValue(take(drop(parts[1], 1), 14))
517- let tickets = (acresAmount / MIN_ACRES_AMOUNT_DURING_PROMO)
518- let totalTikets = valueOrElse(getInteger(keyTicketsTotalByPromo(2)), 0)
519- let $t01254712987 = if ((totalTikets == 0))
520- then {
521- func countTickets (acc,el) = (acc + (parseIntValue(split(el, ":")[1]) / MIN_ACRES_AMOUNT_DURING_PROMO))
522-
523- let ticketsCount = {
524- let $l = split_51C(promo2Map, "_")
525- let $s = size($l)
526- let $acc0 = 0
527- func $f0_1 ($a,$i) = if (($i >= $s))
528- then $a
529- else countTickets($a, $l[$i])
530-
531- func $f0_2 ($a,$i) = if (($i >= $s))
532- then $a
533- else throw("List size exceeds 50")
534-
535- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($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), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50)
536- }
537- $Tuple2([IntegerEntry(keyTicketsTotalByPromo(2), ticketsCount), IntegerEntry(keyTicketsTotalByPromoAndRound(2, 1), ticketsCount)], ticketsCount)
538- }
539- else $Tuple2(nil, totalTikets)
540- let ticketsActions = $t01254712987._1
541- let totalCount = $t01254712987._2
542- let award = fraction(PROMO_2_DISTRIBUTION_FUND, tickets, totalCount)
543- let stakeResult = invoke(this, "sendLockedAcres", [address, award, 30], nil)
544- $Tuple2(((ticketsActions :+ BooleanEntry(awardedKey, true)) :+ StringEntry(keyPromo2MapForRound(1), promo2Map)), stakeResult)
545- }
546- }
547- }
548- }
549- }
550- else throw("Strict value is not equal to itself.")
551- }
552-
553-
554-
555-@Callable(i)
556-func initPromo4 (promo4Map) = if ((i.caller != this))
557- then throw("Permission denied")
558- else {
559- func countTickets (acc,el) = (acc + parseIntValue(split(el, ":")[1]))
560-
561- let ticketsTotal = {
562- let $l = split_51C(promo4Map, "_")
563- let $s = size($l)
564- let $acc0 = 0
565- func $f0_1 ($a,$i) = if (($i >= $s))
566- then $a
567- else countTickets($a, $l[$i])
568-
569- func $f0_2 ($a,$i) = if (($i >= $s))
570- then $a
571- else throw("List size exceeds 20")
572-
573- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($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), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20)
574- }
575- $Tuple2([IntegerEntry(keyTicketsTotalByPromoAndRound(4, 1), ticketsTotal), StringEntry(keyPromo4MapForRound(1), promo4Map)], ticketsTotal)
576- }
577-
578-
579-
580-@Callable(i)
581-func commitForPromo4Round (roundId) = if ((i.caller != this))
582- then throw("Permission denied")
583- else if (if ((1 > roundId))
584- then true
585- else (roundId > 2))
586- then throw(("Invalid roundId: " + toString(roundId)))
587- else {
588- let finishBlock = (height + randomDelay)
589- $Tuple2([IntegerEntry(keyCommit(("4_" + toString(roundId))), finishBlock)], finishBlock)
590- }
591-
592-
593-
594-@Callable(i)
595-func drawPromo4Round (roundId) = if ((i.caller != this))
596- then throw("Permission denied")
597- else if (if ((1 > roundId))
598- then true
599- else (roundId > 2))
600- then throw(("Invalid roundId: " + toString(roundId)))
601- else {
602- let finishKey = keyCommit(("4_" + toString(roundId)))
603- let finishBlock = valueOrErrorMessage(getInteger(finishKey), (("You have to commitForPromo4Round(" + toString(roundId)) + ") first!"))
604- if ((finishBlock > height))
605- then throw((((("Random number is not ready yet, wait until height = " + toString(finishBlock)) + " (current height = ") + toString(height)) + ")"))
606- else {
607- let maxValue = valueOrElse(getInteger(keyTicketsTotalByPromoAndRound(4, roundId)), 0)
608- if ((maxValue == 0))
609- then throw("No tickets to draw")
610- else {
611- let entropy = value(value(blockInfoByHeight(finishBlock)).vrf)
612- let salt = i.transactionId
613- let promo4Map = valueOrElse(getString(keyPromo4MapForRound(roundId)), "")
614- func singleDraw (ac,j) = if ((j >= promo4NumPrizesPerRound[(roundId - 1)]))
615- then ac
616- else {
617- let rand = getRandomNumber(ac._1, ac._2, entropy)
618- let promo4List = if ((ac._3 == ""))
619- then nil
620- else split_51C(ac._3, "_")
621- func countTickets (acc,el) = {
622- let parts = split(el, ":")
623- let addr = parts[0]
624- let tickets = parseIntValue(parts[1])
625- let newTotal = (acc._1 + tickets)
626- if (if ((acc._3 == ""))
627- then (newTotal > rand)
628- else false)
629- then $Tuple3(newTotal, tickets, addr)
630- else $Tuple3(newTotal, acc._2, acc._3)
631- }
632-
633- let r = {
634- let $l = promo4List
635- let $s = size($l)
636- let $acc0 = $Tuple3(0, 0, "")
637- func $f0_1 ($a,$i) = if (($i >= $s))
638- then $a
639- else countTickets($a, $l[$i])
640-
641- func $f0_2 ($a,$i) = if (($i >= $s))
642- then $a
643- else throw("List size exceeds 20")
644-
645- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($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), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20)
646- }
647- let winner = r._3
648- if ((winner == ""))
649- then ac
650- else {
651- let mapParts = split_51C(ac._3, winner)
652- let newMap = if ((mapParts[0] == ""))
653- then drop(mapParts[1], 5)
654- else (dropRight(mapParts[0], 1) + drop(mapParts[1], 4))
655- let stakeResult = invoke(this, "sendLockedAcres", [winner, promo4AwardPerRound[(roundId - 1)], 30], nil)
656- let newSalt = fromBase58String(valueOrElse(getString(stakingContract, keyLastTxIdByUser(winner)), "DEFAULT"))
657- $Tuple4((ac._1 - r._2), newSalt, newMap, (ac._4 :+ stakeResult))
658- }
659- }
660-
661- let draws = {
662- let $l = ITER6
663- let $s = size($l)
664- let $acc0 = $Tuple4(maxValue, i.transactionId, promo4Map, nil)
665- func $f0_1 ($a,$i) = if (($i >= $s))
666- then $a
667- else singleDraw($a, $l[$i])
668-
669- func $f0_2 ($a,$i) = if (($i >= $s))
670- then $a
671- else throw("List size exceeds 6")
672-
673- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
674- }
675- $Tuple2([DeleteEntry(finishKey), StringEntry(keyPromo4MapForRound((roundId + 1)), draws._3), IntegerEntry(keyTicketsTotalByPromoAndRound(4, (roundId + 1)), draws._1)], draws._4)
676- }
677- }
678- }
679-
680-
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let MILLION6 = 100000000000000
5-
6-let DAYMILLIS = 86400000
7-
8-func keyAcresStakedAmountByUser (addr) = ("acresStakedAmountByUser_" + addr)
9-
10-
11-func keyAcresLockedAmountByUser (addr) = ("acresLockedAmountByUser_" + addr)
12-
13-
14-func keyAcresLockedEtaByUser (addr) = ("acresLockedEtaByUser_" + addr)
15-
16-
17-let acresStakedTotalKey = "acresStakedAmountTotal"
18-
19-let xpNewSLand = 5000000
20-
21-let DAILYRESBYPIECE = 3456000
22-
23-let USDT2ACRES_MULTIPLIER = 10
24-
25-func keyIsAwardedByPromoAndUser (promoId,addr) = makeString(["%s%d%s__isAwardedByPromoAndUser", toString(promoId), addr], "__")
26-
27-
28-func keyTicketsTotalByPromo (promoId) = ("%s%d__ticketsTotalByPromo__" + toString(promoId))
29-
30-
31-func keyTicketsTotalByPromoAndRound (promoId,roundId) = makeString(["%s%d%d__ticketsTotalByPromoAndRound", toString(promoId), toString(roundId)], "__")
32-
33-
344 let chain = take(drop(this.bytes, 1), 1)
35-
36-let usdtAssetId = match chain {
37- case _ =>
38- if ((base58'2W' == $match0))
39- then base58'9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi'
40- else if ((base58'2T' == $match0))
41- then base58'6mWwf9mZBjVgkC54idpyaZLQfAosD914wT8fGf2iiY63'
42- else throw("Unknown chain")
43-}
445
456 let defaultRestAddressStr = match chain {
467 case _ =>
478 if ((base58'2W' == $match0))
489 then "3PQCuvFbvh4LkPUnrnU1z3jnbA1p9m3WNhv"
4910 else if ((base58'2T' == $match0))
5011 then "3MumkGGztCKAXpWDqxkddofqXSUbqQkvSJy"
5112 else throw("Unknown chain")
5213 }
5314
54-let promo2MapKey = "promo2Map"
55-
56-func keyPromo2MapForRound (roundId) = ("promo2MapForRound__" + toString(roundId))
57-
58-
59-func keyPromo4MapForRound (roundId) = ("promo4MapForRound__" + toString(roundId))
60-
15+let acres2AddressStr = match chain {
16+ case _ =>
17+ if ((base58'2W' == $match0))
18+ then "3P4UH3T9nXpMNpUmSmQjPmEz3G85t3zn6eA"
19+ else if ((base58'2T' == $match0))
20+ then "3NBPx1Fciu3JQNEGZ21jSnTdutLNGGBUSXh"
21+ else throw("Unknown chain")
22+}
6123
6224 let SEP = "__"
6325
64-let MULT6 = 1000000
65-
6626 let MULT8 = 100000000
67-
68-let ITER6 = [0, 1, 2, 3, 4, 5]
6927
7028 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
7129
7230
7331 let IdxCfgStakingDapp = 1
7432
7533 let IdxCfgEconomyDapp = 2
7634
7735 let IdxCfgWlgDapp = 4
7836
7937 let IdxCfgAcresDapp = 8
8038
8139 func keyRestCfg () = "%s__restConfig"
8240
8341
8442 func keyRestAddress () = "%s__restAddr"
8543
8644
8745 func readRestCfgOrFail (rest) = split_4C(getStringOrFail(rest, keyRestCfg()), SEP)
8846
8947
9048 func getContractAddressOrFail (restCfg,idx) = valueOrErrorMessage(addressFromString(restCfg[idx]), ("Rest cfg doesn't contain address at index " + toString(idx)))
9149
9250
9351 let restContract = addressFromStringValue(valueOrElse(getString(this, keyRestAddress()), defaultRestAddressStr))
9452
9553 let restCfg = readRestCfgOrFail(restContract)
9654
9755 let stakingContract = getContractAddressOrFail(restCfg, IdxCfgStakingDapp)
9856
9957 let economyContract = getContractAddressOrFail(restCfg, IdxCfgEconomyDapp)
10058
10159 let wlgContract = getContractAddressOrFail(restCfg, IdxCfgWlgDapp)
10260
10361 let acresContract = getContractAddressOrFail(restCfg, IdxCfgAcresDapp)
10462
10563 let acresIssuedAmountKey = "acresIssuedAmount"
10664
10765 let acresAssetIdKey = "acresAssetId"
10866
10967 let acresAssetId = valueOrErrorMessage(getBinary(acresContract, acresAssetIdKey), "ACRES is not issued yet")
11068
11169 func keyAcresStakedTimeByUser (addr) = ("acresStakedTimeByUser_" + addr)
11270
11371
11472 let IdxEffTotal = 0
11573
116-let randomDelay = 2
117-
118-func keyCommit (address) = ("finishBlockFor_" + address)
119-
120-
12174 func keyResProportions () = "resTypesProportions"
12275
12376
12477 func keyStakedPiecesByOwner (ownerAddr) = ("stakedPiecesByOwner_" + ownerAddr)
12578
12679
12780 func asInt (v) = match v {
12881 case n: Int =>
12982 n
13083 case _ =>
13184 throw("fail to cast into Int")
13285 }
13386
13487
13588 func asTwoIntsTuple (val) = match val {
13689 case t2: (Int, Int) =>
13790 t2
13891 case _ =>
13992 throw("fail to cast into (Int, Int)")
14093 }
141-
142-
143-func keyLastTxIdByUser (addr) = ("lastTxIdByUser_" + addr)
14494
14595
14696 func getVotingPower (userAddrStrOrEmpty) = {
14797 let props = split(valueOrElse(getString(stakingContract, keyResProportions()), "0_0_0_0_0_0"), "_")
14898 func adder (acc,item) = (acc + parseIntValue(item))
14999
150100 let totalPower = {
151101 let $l = props
152102 let $s = size($l)
153103 let $acc0 = 0
154104 func $f0_1 ($a,$i) = if (($i >= $s))
155105 then $a
156106 else adder($a, $l[$i])
157107
158108 func $f0_2 ($a,$i) = if (($i >= $s))
159109 then $a
160110 else throw("List size exceeds 6")
161111
162112 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
163113 }
164114 let usersPower = valueOrElse(getInteger(stakingContract, keyStakedPiecesByOwner(userAddrStrOrEmpty)), 0)
165115 [totalPower, usersPower]
166116 }
167117
168118
169119 func fixedPoint (val,decimals) = {
170120 let tenPow = pow(10, 0, decimals, 0, 0, DOWN)
171121 let lowPart = toString((val % tenPow))
172122 let zeroes = drop(toString(tenPow), (1 + size(lowPart)))
173123 (((toString((val / tenPow)) + ".") + zeroes) + lowPart)
174124 }
175125
176126
177-func padL (val,len) = {
178- let valS = toString(val)
179- let zeroes = drop(toString(pow(10, 0, (len - size(valS)), 0, 0, DOWN)), 1)
180- (zeroes + valS)
181- }
127+func finalTime () = min([lastBlock.timestamp, 1727740799000])
182128
183129
184-func getRandomNumber (maxValue,salt,entropy) = if ((0 >= maxValue))
185- then throw("maxValue should be > 0")
186- else {
187- let randomHash = sha256((salt + entropy))
188- (toInt(randomHash) % maxValue)
189- }
130+let DAILYRESBYPIECE = 3456000
131+
132+let USDT2ACRES_MULTIPLIER = 10
133+
134+let MILLION6 = 100000000000000
135+
136+let DAYMILLIS = 86400000
137+
138+func keyAcresStakedAmountByUser (addr) = ("acresStakedAmountByUser_" + addr)
190139
191140
192-let MIN_ACRES_AMOUNT_DURING_PROMO = 10000000
141+func keyAcresLockedAmountByUser (addr) = ("acresLockedAmountByUser_" + addr)
142+
143+
144+func keyAcresLockedEtaByUser (addr) = ("acresLockedEtaByUser_" + addr)
145+
146+
147+let acresStakedTotalKey = "acresStakedAmountTotal"
193148
194149 let BLACKLISTED1 = "3P2NGX4Q5nge1MCauwQW5aqYLdkccSGj1Ep_3P2xFAHW9yhyNohYozWd4HFhEXZu3bsNSoR_3P2yKaZ2gvn9Xe5tti81a7P9LZhHgjvToV9_3P37zQ3cf2ecu55RmJqEiGSivdzN9avt3m9_3P4az6dtzsvGCWFAxa94UdevKzXyEwxEiFG_3P4kZU6X3TTLFcSUe55JSy8BySqitcPgMBz_3P5hCxBEh3NgNizZhNBreyBSqtbhJYLkKPD_3P7HLvucy11yxyMJUwjzXFHHKMEDwi1EwfC_3P8JuaqH9PTQAv8D5HBGgQfKauLTYt2NQft_3P9gTDB4rtDEVbpX3asU63H4Zinh2EnTmZE_3P9iN3qrtfJicUVy7amZeVsetVD3vUMk8be_3PCa2BsAa6JBLirszQfV5r9fJrujfhwtwfP_3PD3i4XN8KtygcFx4ry5M7UGqdfH8VYvtRT_3PDEMnnJNc2kx9cPEmvVvhXUr8SvhANKhsa_3PDGE9tKQizaeZFeDDq5aYSv89nwYbfirpZ_3PDMKQTCrUPZECVXEJJ8m1sHtutSu1naSf1_3PGh2Qu6Yvx8GTCRRVNvBUVZLdaidYSaxo5_3PKkmAtbSK5D2hQdo1RfEg8eXyMbDcRUc92_3PLMnbxzssP8W8E8XjJ1RLBBg8UZL8Cz3P2_3PMuxo4PCAox9s4a7R1eszh4iqqu8gS7jHv_3PNrMtEQChw87WZU1JAJ7aGHykCa8TjnDNK_3PPuBXfWoBy3EEory7c7vgi9Usjka7o5tBj_3PQwyeyEhT4Y6aGAL6tg73aQWJtV1zRt3nR_3PRGDShuMGb84MJtTJvtTg8qDfswkYWcm3e"
195150
196151 let PROMO1_AMOUNT = 4970178
197152
198153 let PROMO_2_START_TIMESTAMP = match chain {
199154 case _ =>
200155 if ((base58'2W' == $match0))
201156 then 1700524800000
202157 else if ((base58'2T' == $match0))
203158 then 1700420400000
204159 else throw("Unknown chain")
205160 }
206161
207162 let PROMO_2_END_TIMESTAMP = match chain {
208163 case _ =>
209164 if ((base58'2W' == $match0))
210165 then 1701043199999
211166 else if ((base58'2T' == $match0))
212167 then 1700496000000
213168 else throw("Unknown chain")
214169 }
215170
216-let PROMO_2_DISTRIBUTION_FUND = 1000000000
217-
218-let promo4NumPrizesPerRound = [1, 5]
219-
220-let promo4AwardPerRound = [500000000, 100000000]
221-
222171 func isBlacklistedPromo1 (addr) = contains(BLACKLISTED1, addr)
223172
224173
225-func prolog () = asInt(reentrantInvoke(stakingContract, "saveLastTx", nil, nil))
226-
227-
228174 func claimAcresInternal (addr,acresAmount,lastClaimTime) = {
229- let deltaTime = (lastBlock.timestamp - lastClaimTime)
175+ let deltaTime = (finalTime() - lastClaimTime)
230176 let availRes = fraction(deltaTime, (DAILYRESBYPIECE * acresAmount), (DAYMILLIS * MULT8))
231177 let canGetUsdt = asInt(invoke(economyContract, "sellResourcesWorldREADONLY", [availRes], nil))
232178 let gotUsdt = max([0, canGetUsdt])
233179 (gotUsdt * USDT2ACRES_MULTIPLIER)
234180 }
235181
236182
237183 func claimInternal (addr,acresAmount,lastClaimTime) = {
238- let deltaTime = (lastBlock.timestamp - lastClaimTime)
184+ let deltaTime = (finalTime() - lastClaimTime)
239185 if ((0 > deltaTime))
240- then throw(((("Saved timestamp is in future, saved = " + toString(lastClaimTime)) + ", current = ") + toString(lastBlock.timestamp)))
186+ then throw(((("Saved timestamp is in future, saved = " + toString(lastClaimTime)) + ", final = ") + toString(finalTime())))
241187 else {
242188 let availRes = fraction(deltaTime, (DAILYRESBYPIECE * acresAmount), (DAYMILLIS * MULT8))
243189 let canGetUsdt = asInt(invoke(economyContract, "sellResourcesWorldREADONLY", [availRes], nil))
244190 let gotUsdt = if ((0 >= canGetUsdt))
245191 then 0
246192 else asTwoIntsTuple(invoke(economyContract, "sellResourcesWorld", [addr, availRes], nil))._1
247193 (gotUsdt * USDT2ACRES_MULTIPLIER)
248194 }
249195 }
250196
251197
252-func mergeLocked (oldAmount,oldETA,newAmount,newETA) = {
253- let now = lastBlock.timestamp
254- let dt1 = max([0, (oldETA - now)])
255- let dt2 = max([0, (newETA - now)])
256- let sum = (oldAmount + newAmount)
257- let dt = if ((sum == 0))
258- then 0
259- else (fraction(dt1, oldAmount, sum) + fraction(dt2, newAmount, sum))
260- (now + dt)
198+func unstakeAcresRO (amount,address) = {
199+ let timeKey = keyAcresStakedTimeByUser(address)
200+ let claimedAcres = claimAcresInternal(address, amount, valueOrElse(getInteger(timeKey), 0))
201+ (amount + claimedAcres)
261202 }
203+
204+
205+func unstakeAcresInternal (amount,address) = if ((0 >= amount))
206+ then throw("Amount should be positive")
207+ else {
208+ let timeKey = keyAcresStakedTimeByUser(address)
209+ let amountKey = keyAcresStakedAmountByUser(address)
210+ let oldAcresAmount = valueOrElse(getInteger(amountKey), 0)
211+ if ((amount > oldAcresAmount))
212+ then throw(((("You have only " + fixedPoint(oldAcresAmount, 8)) + " ACRES staked, tried to unstake ") + fixedPoint(amount, 8)))
213+ else {
214+ let lockedAmount = valueOrElse(getInteger(keyAcresLockedAmountByUser(address)), 0)
215+ let lockedETA = valueOrElse(getInteger(keyAcresLockedEtaByUser(address)), 0)
216+ let now = lastBlock.timestamp
217+ if (if ((now >= PROMO_2_START_TIMESTAMP))
218+ then (PROMO_2_END_TIMESTAMP >= now)
219+ else false)
220+ then throw("You cannot unstake ACRES during Promo2")
221+ else {
222+ let unstakableAmount = if (isBlacklistedPromo1(address))
223+ then ((oldAcresAmount - lockedAmount) - PROMO1_AMOUNT)
224+ else (oldAcresAmount - lockedAmount)
225+ if (if ((lockedETA > now))
226+ then (amount > unstakableAmount)
227+ else false)
228+ then throw(((("Only " + fixedPoint(unstakableAmount, 8)) + " ACRES can be unstaked now, wait until ") + toString(lockedETA)))
229+ else {
230+ let oldTotal = valueOrElse(getInteger(acresStakedTotalKey), 0)
231+ let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [address], nil)
232+ let claimedAcres = claimInternal(address, oldAcresAmount, valueOrElse(getInteger(timeKey), 0))
233+ $Tuple2([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(amountKey, (oldAcresAmount - amount)), IntegerEntry(acresStakedTotalKey, (oldTotal - amount)), ScriptTransfer(addressFromStringValue(address), (amount + claimedAcres), acresAssetId)], $Tuple2((amount + claimedAcres), wlgResult))
234+ }
235+ }
236+ }
237+ }
262238
263239
264240 @Callable(i)
265241 func constructorV1 (restAddr,unstakedPieces) = if ((i.caller != this))
266242 then throw("Permission denied")
267243 else if (isDefined(getBinary(acresAssetIdKey)))
268244 then throw("Already initialized")
269245 else {
270246 let nftAcres = (getVotingPower("")[IdxEffTotal] + unstakedPieces)
271247 let issuedAmount = (MILLION6 - (nftAcres * MULT8))
272248 let issue = Issue("ACRES", "WavesLands land acres investment token", issuedAmount, 8, false, unit, 0)
273249 let assetId = calculateAssetId(issue)
274250 [issue, IntegerEntry(acresIssuedAmountKey, issuedAmount), BinaryEntry(acresAssetIdKey, assetId), StringEntry(keyRestAddress(), restAddr)]
275251 }
276252
277253
278254
279255 @Callable(i)
280-func unstakeAcres (amount) = {
281- let prologResult = prolog()
282- if ((prologResult == prologResult))
283- then if ((0 >= amount))
284- then throw("Amount should be positive")
285- else {
286- let address = toString(i.caller)
287- if ((size(i.payments) != 0))
288- then throw("No payments required")
289- else {
290- let timeKey = keyAcresStakedTimeByUser(address)
291- let amountKey = keyAcresStakedAmountByUser(address)
292- let oldAcresAmount = valueOrElse(getInteger(amountKey), 0)
293- if ((amount > oldAcresAmount))
294- then throw(((("You have only " + fixedPoint(oldAcresAmount, 8)) + " ACRES staked, tried to unstake ") + fixedPoint(amount, 8)))
295- else {
296- let lockedAmount = valueOrElse(getInteger(keyAcresLockedAmountByUser(address)), 0)
297- let lockedETA = valueOrElse(getInteger(keyAcresLockedEtaByUser(address)), 0)
298- let now = lastBlock.timestamp
299- if (if ((now >= PROMO_2_START_TIMESTAMP))
300- then (PROMO_2_END_TIMESTAMP >= now)
301- else false)
302- then throw("You cannot unstake ACRES during Promo2")
303- else {
304- let unstakableAmount = if (isBlacklistedPromo1(address))
305- then ((oldAcresAmount - lockedAmount) - PROMO1_AMOUNT)
306- else (oldAcresAmount - lockedAmount)
307- if (if ((lockedETA > now))
308- then (amount > unstakableAmount)
309- else false)
310- then throw(((("Only " + fixedPoint(unstakableAmount, 8)) + " ACRES can be unstaked now, wait until ") + toString(lockedETA)))
311- else {
312- let oldTotal = valueOrElse(getInteger(acresStakedTotalKey), 0)
313- let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [address], nil)
314- let claimedAcres = claimInternal(address, oldAcresAmount, valueOrElse(getInteger(timeKey), 0))
315- $Tuple2([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(amountKey, (oldAcresAmount - amount)), IntegerEntry(acresStakedTotalKey, (oldTotal - amount)), ScriptTransfer(i.caller, (amount + claimedAcres), acresAssetId)], $Tuple2(prologResult, wlgResult))
316- }
317- }
318- }
319- }
320- }
321- else throw("Strict value is not equal to itself.")
256+func unstakeAcresCallback (amount,address) = if ((toString(i.caller) != acres2AddressStr))
257+ then throw("Permission denied")
258+ else unstakeAcresInternal(amount, address)
259+
260+
261+
262+@Callable(i)
263+func unstakeAllAcresREADONLY (address) = {
264+ let amount = valueOrElse(getInteger(keyAcresStakedAmountByUser(address)), 0)
265+ let unstakedWithClaimed = unstakeAcresRO(amount, address)
266+ $Tuple2(nil, unstakedWithClaimed)
322267 }
323268
324269
325270
326271 @Callable(i)
327-func stakeAcres () = {
328- let prologResult = prolog()
329- if ((prologResult == prologResult))
330- then {
331- let address = toString(i.caller)
332- if ((size(i.payments) != 1))
333- then throw("exactly 1 payment must be attached")
334- else {
335- let pmt = i.payments[0]
336- let amt = pmt.amount
337- if (if (!(isDefined(pmt.assetId)))
338- then true
339- else (value(pmt.assetId) != acresAssetId))
340- then throw("ACRES payments only!")
341- else {
342- let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [address], nil)
343- if ((wlgResult == wlgResult))
344- then {
345- let now = lastBlock.timestamp
346- if (if ((PROMO_2_START_TIMESTAMP > now))
347- then true
348- else (now > PROMO_2_END_TIMESTAMP))
349- then {
350- let timeKey = keyAcresStakedTimeByUser(address)
351- let amountKey = keyAcresStakedAmountByUser(address)
352- let oldAcresAmount = valueOrElse(getInteger(amountKey), 0)
353- let oldTotal = valueOrElse(getInteger(acresStakedTotalKey), 0)
354- let claimedAcres = claimInternal(address, oldAcresAmount, valueOrElse(getInteger(timeKey), 0))
355- $Tuple2(((((if ((claimedAcres == 0))
356- then nil
357- else [ScriptTransfer(i.caller, claimedAcres, acresAssetId)]) :+ IntegerEntry(timeKey, lastBlock.timestamp)) :+ IntegerEntry(amountKey, (oldAcresAmount + amt))) :+ IntegerEntry(acresStakedTotalKey, (oldTotal + amt))), $Tuple2(prologResult, wlgResult))
358- }
359- else if ((MIN_ACRES_AMOUNT_DURING_PROMO > amt))
360- then throw((("Min staked amount during promo action should be at least " + fixedPoint(MIN_ACRES_AMOUNT_DURING_PROMO, 8)) + " ACRES"))
361- else {
362- let stakeResult = invoke(this, "sendLockedAcres", [address, amt, 30], nil)
363- let promo2Map = valueOrElse(getString(promo2MapKey), "")
364- let newMap2 = if (contains(promo2Map, address))
365- then {
366- let parts = split_51C(promo2Map, address)
367- let oldAmount = parseIntValue(take(drop(parts[1], 1), 14))
368- ((((parts[0] + address) + ":") + padL((oldAmount + amt), 14)) + drop(parts[1], 15))
369- }
370- else {
371- let finalPart = ((address + ":") + padL(amt, 14))
372- if ((promo2Map == ""))
373- then finalPart
374- else ((promo2Map + "_") + finalPart)
375- }
376- $Tuple2([StringEntry(promo2MapKey, newMap2)], $Tuple3(prologResult, wlgResult, stakeResult))
377- }
378- }
379- else throw("Strict value is not equal to itself.")
380- }
381- }
382- }
383- else throw("Strict value is not equal to itself.")
384- }
385-
386-
387-
388-@Callable(i)
389-func buyAcres () = {
390- let prologResult = prolog()
391- if ((prologResult == prologResult))
392- then {
393- let address = toString(i.caller)
394- if ((size(i.payments) != 1))
395- then throw("exactly 1 payment must be attached")
396- else {
397- let pmt = i.payments[0]
398- let amt = pmt.amount
399- if (if (!(isDefined(pmt.assetId)))
400- then true
401- else (value(pmt.assetId) != usdtAssetId))
402- then throw("USDT payments only!")
403- else if ((MULT6 > amt))
404- then throw((("Min payment should be " + fixedPoint(MULT6, 6)) + " USDT"))
405- else {
406- let acresAmount = (amt * USDT2ACRES_MULTIPLIER)
407- let accStatsResult = asInt(invoke(stakingContract, "updateAccStats", [address, fraction(xpNewSLand, acresAmount, (25 * MULT8))], nil))
408- $Tuple2([ScriptTransfer(economyContract, amt, usdtAssetId), ScriptTransfer(i.caller, acresAmount, acresAssetId)], $Tuple2(prologResult, accStatsResult))
409- }
410- }
411- }
412- else throw("Strict value is not equal to itself.")
413- }
414-
415-
416-
417-@Callable(i)
418-func sendAcres (addr,amount) = if ((i.caller != economyContract))
272+func requestAcresCallback (amount,address) = if ((toString(i.caller) != acres2AddressStr))
419273 then throw("Permission denied")
420- else $Tuple2([ScriptTransfer(addressFromStringValue(addr), amount, acresAssetId)], amount)
421-
422-
423-
424-@Callable(i)
425-func sendLockedAcres (addr,amount,lockDays) = if (if ((i.caller != this))
426- then (i.caller != restContract)
427- else false)
428- then throw("Permission denied")
429- else {
430- let now = lastBlock.timestamp
431- let timeKey = keyAcresStakedTimeByUser(addr)
432- let amountKey = keyAcresStakedAmountByUser(addr)
433- let oldAcresAmount = valueOrElse(getInteger(amountKey), 0)
434- let oldTotal = valueOrElse(getInteger(acresStakedTotalKey), 0)
435- let timeAction = if (isDefined(getInteger(timeKey)))
436- then nil
437- else [IntegerEntry(timeKey, now)]
438- let etaKey = keyAcresLockedEtaByUser(addr)
439- let lockedAmountKey = keyAcresLockedAmountByUser(addr)
440- let oldLockedAmount = valueOrElse(getInteger(lockedAmountKey), 0)
441- let oldLockedETA = valueOrElse(getInteger(etaKey), 0)
442- let mergedETA = mergeLocked(oldLockedAmount, oldLockedETA, amount, (now + (lockDays * DAYMILLIS)))
443- $Tuple2(((((timeAction :+ IntegerEntry(amountKey, (oldAcresAmount + amount))) :+ IntegerEntry(acresStakedTotalKey, (oldTotal + amount))) :+ IntegerEntry(etaKey, mergedETA)) :+ IntegerEntry(lockedAmountKey, (oldLockedAmount + amount))), amount)
444- }
445-
446-
447-
448-@Callable(i)
449-func burnAcres (amount) = if ((i.caller != stakingContract))
450- then throw("Permission denied")
451- else {
452- let amountLeft = (valueOrElse(getInteger(acresIssuedAmountKey), 0) - amount)
453- if ((0 > amountLeft))
454- then throw("Attempt to burn more ACRES, than exists")
455- else $Tuple2([Burn(acresAssetId, amount), IntegerEntry(acresIssuedAmountKey, amountLeft)], amount)
456- }
457-
458-
459-
460-@Callable(i)
461-func claimAcres () = {
462- let prologResult = prolog()
463- if ((prologResult == prologResult))
464- then {
465- let address = toString(i.caller)
466- if ((size(i.payments) != 0))
467- then throw("No payments required")
468- else {
469- let timeKey = keyAcresStakedTimeByUser(address)
470- let amountKey = keyAcresStakedAmountByUser(address)
471- let acresAmount = valueOrElse(getInteger(amountKey), 0)
472- let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [address], nil)
473- let claimedAcres = claimInternal(address, acresAmount, valueOrElse(getInteger(timeKey), 0))
474- $Tuple2([IntegerEntry(timeKey, lastBlock.timestamp), ScriptTransfer(i.caller, claimedAcres, acresAssetId)], $Tuple2(prologResult, wlgResult))
475- }
476- }
477- else throw("Strict value is not equal to itself.")
478- }
274+ else $Tuple2([ScriptTransfer(addressFromStringValue(address), amount, acresAssetId)], amount)
479275
480276
481277
482278 @Callable(i)
483279 func claimAcresREADONLY (address) = {
484280 let timeKey = keyAcresStakedTimeByUser(address)
485281 let amountKey = keyAcresStakedAmountByUser(address)
486282 let acresAmount = valueOrElse(getInteger(amountKey), 0)
487283 let lastTime = valueOrElse(getInteger(timeKey), 0)
488284 let claimedAcres = claimAcresInternal(address, acresAmount, lastTime)
489285 $Tuple2(nil, [claimedAcres, lastTime])
490286 }
491287
492288
493-
494-@Callable(i)
495-func claimPromo2 () = {
496- let prologResult = prolog()
497- if ((prologResult == prologResult))
498- then {
499- let address = toString(i.caller)
500- if ((size(i.payments) != 0))
501- then throw("No payments required")
502- else {
503- let now = lastBlock.timestamp
504- if ((PROMO_2_END_TIMESTAMP > now))
505- then throw("Promo 2 is not over yet")
506- else {
507- let awardedKey = keyIsAwardedByPromoAndUser(2, address)
508- if (valueOrElse(getBoolean(awardedKey), false))
509- then throw((("Your wallet " + address) + " is already awarded in promo 2"))
510- else {
511- let promo2Map = valueOrElse(getString(promo2MapKey), "")
512- if (!(contains(promo2Map, address)))
513- then throw("You are not participant of promo 2")
514- else {
515- let parts = split_51C(promo2Map, address)
516- let acresAmount = parseIntValue(take(drop(parts[1], 1), 14))
517- let tickets = (acresAmount / MIN_ACRES_AMOUNT_DURING_PROMO)
518- let totalTikets = valueOrElse(getInteger(keyTicketsTotalByPromo(2)), 0)
519- let $t01254712987 = if ((totalTikets == 0))
520- then {
521- func countTickets (acc,el) = (acc + (parseIntValue(split(el, ":")[1]) / MIN_ACRES_AMOUNT_DURING_PROMO))
522-
523- let ticketsCount = {
524- let $l = split_51C(promo2Map, "_")
525- let $s = size($l)
526- let $acc0 = 0
527- func $f0_1 ($a,$i) = if (($i >= $s))
528- then $a
529- else countTickets($a, $l[$i])
530-
531- func $f0_2 ($a,$i) = if (($i >= $s))
532- then $a
533- else throw("List size exceeds 50")
534-
535- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($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), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50)
536- }
537- $Tuple2([IntegerEntry(keyTicketsTotalByPromo(2), ticketsCount), IntegerEntry(keyTicketsTotalByPromoAndRound(2, 1), ticketsCount)], ticketsCount)
538- }
539- else $Tuple2(nil, totalTikets)
540- let ticketsActions = $t01254712987._1
541- let totalCount = $t01254712987._2
542- let award = fraction(PROMO_2_DISTRIBUTION_FUND, tickets, totalCount)
543- let stakeResult = invoke(this, "sendLockedAcres", [address, award, 30], nil)
544- $Tuple2(((ticketsActions :+ BooleanEntry(awardedKey, true)) :+ StringEntry(keyPromo2MapForRound(1), promo2Map)), stakeResult)
545- }
546- }
547- }
548- }
549- }
550- else throw("Strict value is not equal to itself.")
551- }
552-
553-
554-
555-@Callable(i)
556-func initPromo4 (promo4Map) = if ((i.caller != this))
557- then throw("Permission denied")
558- else {
559- func countTickets (acc,el) = (acc + parseIntValue(split(el, ":")[1]))
560-
561- let ticketsTotal = {
562- let $l = split_51C(promo4Map, "_")
563- let $s = size($l)
564- let $acc0 = 0
565- func $f0_1 ($a,$i) = if (($i >= $s))
566- then $a
567- else countTickets($a, $l[$i])
568-
569- func $f0_2 ($a,$i) = if (($i >= $s))
570- then $a
571- else throw("List size exceeds 20")
572-
573- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($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), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20)
574- }
575- $Tuple2([IntegerEntry(keyTicketsTotalByPromoAndRound(4, 1), ticketsTotal), StringEntry(keyPromo4MapForRound(1), promo4Map)], ticketsTotal)
576- }
577-
578-
579-
580-@Callable(i)
581-func commitForPromo4Round (roundId) = if ((i.caller != this))
582- then throw("Permission denied")
583- else if (if ((1 > roundId))
584- then true
585- else (roundId > 2))
586- then throw(("Invalid roundId: " + toString(roundId)))
587- else {
588- let finishBlock = (height + randomDelay)
589- $Tuple2([IntegerEntry(keyCommit(("4_" + toString(roundId))), finishBlock)], finishBlock)
590- }
591-
592-
593-
594-@Callable(i)
595-func drawPromo4Round (roundId) = if ((i.caller != this))
596- then throw("Permission denied")
597- else if (if ((1 > roundId))
598- then true
599- else (roundId > 2))
600- then throw(("Invalid roundId: " + toString(roundId)))
601- else {
602- let finishKey = keyCommit(("4_" + toString(roundId)))
603- let finishBlock = valueOrErrorMessage(getInteger(finishKey), (("You have to commitForPromo4Round(" + toString(roundId)) + ") first!"))
604- if ((finishBlock > height))
605- then throw((((("Random number is not ready yet, wait until height = " + toString(finishBlock)) + " (current height = ") + toString(height)) + ")"))
606- else {
607- let maxValue = valueOrElse(getInteger(keyTicketsTotalByPromoAndRound(4, roundId)), 0)
608- if ((maxValue == 0))
609- then throw("No tickets to draw")
610- else {
611- let entropy = value(value(blockInfoByHeight(finishBlock)).vrf)
612- let salt = i.transactionId
613- let promo4Map = valueOrElse(getString(keyPromo4MapForRound(roundId)), "")
614- func singleDraw (ac,j) = if ((j >= promo4NumPrizesPerRound[(roundId - 1)]))
615- then ac
616- else {
617- let rand = getRandomNumber(ac._1, ac._2, entropy)
618- let promo4List = if ((ac._3 == ""))
619- then nil
620- else split_51C(ac._3, "_")
621- func countTickets (acc,el) = {
622- let parts = split(el, ":")
623- let addr = parts[0]
624- let tickets = parseIntValue(parts[1])
625- let newTotal = (acc._1 + tickets)
626- if (if ((acc._3 == ""))
627- then (newTotal > rand)
628- else false)
629- then $Tuple3(newTotal, tickets, addr)
630- else $Tuple3(newTotal, acc._2, acc._3)
631- }
632-
633- let r = {
634- let $l = promo4List
635- let $s = size($l)
636- let $acc0 = $Tuple3(0, 0, "")
637- func $f0_1 ($a,$i) = if (($i >= $s))
638- then $a
639- else countTickets($a, $l[$i])
640-
641- func $f0_2 ($a,$i) = if (($i >= $s))
642- then $a
643- else throw("List size exceeds 20")
644-
645- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($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), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20)
646- }
647- let winner = r._3
648- if ((winner == ""))
649- then ac
650- else {
651- let mapParts = split_51C(ac._3, winner)
652- let newMap = if ((mapParts[0] == ""))
653- then drop(mapParts[1], 5)
654- else (dropRight(mapParts[0], 1) + drop(mapParts[1], 4))
655- let stakeResult = invoke(this, "sendLockedAcres", [winner, promo4AwardPerRound[(roundId - 1)], 30], nil)
656- let newSalt = fromBase58String(valueOrElse(getString(stakingContract, keyLastTxIdByUser(winner)), "DEFAULT"))
657- $Tuple4((ac._1 - r._2), newSalt, newMap, (ac._4 :+ stakeResult))
658- }
659- }
660-
661- let draws = {
662- let $l = ITER6
663- let $s = size($l)
664- let $acc0 = $Tuple4(maxValue, i.transactionId, promo4Map, nil)
665- func $f0_1 ($a,$i) = if (($i >= $s))
666- then $a
667- else singleDraw($a, $l[$i])
668-
669- func $f0_2 ($a,$i) = if (($i >= $s))
670- then $a
671- else throw("List size exceeds 6")
672-
673- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
674- }
675- $Tuple2([DeleteEntry(finishKey), StringEntry(keyPromo4MapForRound((roundId + 1)), draws._3), IntegerEntry(keyTicketsTotalByPromoAndRound(4, (roundId + 1)), draws._1)], draws._4)
676- }
677- }
678- }
679-
680-

github/deemru/w8io/026f985 
84.48 ms