tx · FmtVFbr79GPrefoRWByCjQuLwHJcYBFS7XZ5CRFnbJij

3MuS6qVvhBR6wSynFRdcE3fVqmGBjoc7Hhx:  -0.01400000 Waves

2023.08.16 13:58 [2713039] smart account 3MuS6qVvhBR6wSynFRdcE3fVqmGBjoc7Hhx > SELF 0.00000000 Waves

{ "type": 13, "id": "FmtVFbr79GPrefoRWByCjQuLwHJcYBFS7XZ5CRFnbJij", "fee": 1400000, "feeAssetId": null, "timestamp": 1692183562964, "version": 2, "chainId": 84, "sender": "3MuS6qVvhBR6wSynFRdcE3fVqmGBjoc7Hhx", "senderPublicKey": "62CHk4MqTdq3LqeUycy7TPnpvwrjgerSa2FqAY2EafXn", "proofs": [ "rvGCDEYE1qcKGQxGiMQM6HkiayRuqpX7pFKLbE4invDod3X5e83CSWWhiGXm4v7g1uC1fzLX65TsgoERJdTxZaT" ], "script": "base64:BwJ5CAISBAoCCAgSBAoCCAESBAoCCAQSBAoCCAISAwoBCBIDCgEBEgMKAQESBQoDAgECEgUKAwIYGBIECgICARIECgICARIFCgMBAQESBQoDAQEBEgASAwoBCBIDCgEYEgASABIDCgEIEgASBAoCCAgSBAoCCBgSAwoBCDEAA1NFUAICX18ABVdBVkVTAgVXQVZFUwAQY29udHJhY3RGaWxlbmFtZQIMZmFjdG9yeS5yaWRlAQd3cmFwRXJyAQFzCQCsAgIJAKwCAgUQY29udHJhY3RGaWxlbmFtZQICOiAFAXMBCHRocm93RXJyAQFzCQACAQkBB3dyYXBFcnIBBQFzAQ9zdHJpbmdUb0Fzc2V0SWQBAXMDCQAAAgUBcwUFV0FWRVMFBHVuaXQJANkEAQUBcwAPQURNSU5fTElTVF9TSVpFAAUABlFVT1JVTQADABFUWElEX0JZVEVTX0xFTkdUSAAgARhrZXlBbGxvd2VkVHhJZFZvdGVQcmVmaXgBBHR4SWQJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgIJYWxsb3dUeElkCQDMCAIFBHR4SWQFA25pbAUDU0VQARBrZXlGdWxsQWRtaW5Wb3RlAgZwcmVmaXgMYWRtaW5BZGRyZXNzCQC5CQIJAMwIAgUGcHJlZml4CQDMCAIFDGFkbWluQWRkcmVzcwUDbmlsBQNTRVABE2tleUFkbWluQWRkcmVzc0xpc3QACQC5CQIJAMwIAgICJXMJAMwIAgIQYWRtaW5BZGRyZXNzTGlzdAUDbmlsBQNTRVABDmtleUFsbG93ZWRUeElkAAkAuQkCCQDMCAICAiVzCQDMCAICBHR4SWQFA25pbAUDU0VQAQxnZXRBZG1pblZvdGUCBnByZWZpeAVhZG1pbgQHdm90ZUtleQkBEGtleUZ1bGxBZG1pblZvdGUCBQZwcmVmaXgFBWFkbWluCQELdmFsdWVPckVsc2UCCQCfCAEFB3ZvdGVLZXkAAAENZ2V0QWRtaW5zTGlzdAAEByRtYXRjaDAJAJ0IAgUEdGhpcwkBE2tleUFkbWluQWRkcmVzc0xpc3QAAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkAtQkCBQFzBQNTRVAFA25pbAENaXNJbkFkbWluTGlzdAEHYWRkcmVzcwkBD2NvbnRhaW5zRWxlbWVudAIJAQ1nZXRBZG1pbnNMaXN0AAUHYWRkcmVzcwESZ2VuVm90ZXNLZXlzSGVscGVyAgFhDGFkbWluQWRkcmVzcwQLJHQwMTM3NTEzOTkFAWEEBnJlc3VsdAgFCyR0MDEzNzUxMzk5Al8xBAZwcmVmaXgIBQskdDAxMzc1MTM5OQJfMgkAlAoCCQDNCAIFBnJlc3VsdAkBEGtleUZ1bGxBZG1pblZvdGUCBQZwcmVmaXgFDGFkbWluQWRkcmVzcwUGcHJlZml4AQxnZW5Wb3Rlc0tleXMBCWtleVByZWZpeAQJYWRtaW5MaXN0CQETa2V5QWRtaW5BZGRyZXNzTGlzdAAECyR0MDE1NDYxNjMwCgACJGwJAQ1nZXRBZG1pbnNMaXN0AAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgUDbmlsBQlrZXlQcmVmaXgKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBEmdlblZvdGVzS2V5c0hlbHBlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNQkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUEBnJlc3VsdAgFCyR0MDE1NDYxNjMwAl8xBAZwcmVmaXgIBQskdDAxNTQ2MTYzMAJfMgUGcmVzdWx0ARBjb3VudFZvdGVzSGVscGVyAgZyZXN1bHQHdm90ZUtleQkAZAIFBnJlc3VsdAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQd2b3RlS2V5AAABCmNvdW50Vm90ZXMBBnByZWZpeAQFdm90ZXMJAQxnZW5Wb3Rlc0tleXMBBQZwcmVmaXgKAAIkbAUFdm90ZXMKAAIkcwkAkAMBBQIkbAoABSRhY2MwAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBEGNvdW50Vm90ZXNIZWxwZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDUJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFARBjbGVhclZvdGVzSGVscGVyAgZyZXN1bHQDa2V5CQDNCAIFBnJlc3VsdAkBC0RlbGV0ZUVudHJ5AQUDa2V5ARNnZXRDbGVhclZvdGVFbnRyaWVzAQZwcmVmaXgEBXZvdGVzCQEMZ2VuVm90ZXNLZXlzAQUGcHJlZml4CgACJGwFBXZvdGVzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARBjbGVhclZvdGVzSGVscGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA1CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQEMdm90ZUlOVEVSTkFMBBNjYWxsZXJBZGRyZXNzU3RyaW5nCWtleVByZWZpeAhtaW5Wb3Rlcwp2b3RlUmVzdWx0BAd2b3RlS2V5CQEQa2V5RnVsbEFkbWluVm90ZQIFCWtleVByZWZpeAUTY2FsbGVyQWRkcmVzc1N0cmluZwQQYWRtaW5DdXJyZW50Vm90ZQkBDGdldEFkbWluVm90ZQIFCWtleVByZWZpeAUTY2FsbGVyQWRkcmVzc1N0cmluZwQDZXJyAwkBASEBCQENaXNJbkFkbWluTGlzdAEFE2NhbGxlckFkZHJlc3NTdHJpbmcJAQh0aHJvd0VycgEJAKwCAgkArAICAglBZGRyZXNzOiAFE2NhbGxlckFkZHJlc3NTdHJpbmcCEiBub3QgaW4gQWRtaW4gbGlzdAMJAAACBRBhZG1pbkN1cnJlbnRWb3RlAAEJAQh0aHJvd0VycgEJAKwCAgUHdm90ZUtleQISIHlvdSBhbHJlYWR5IHZvdGVkBQR1bml0AwkAAAIFA2VycgUDZXJyBAV2b3RlcwkBCmNvdW50Vm90ZXMBBQlrZXlQcmVmaXgDCQBnAgkAZAIFBXZvdGVzAAEFCG1pblZvdGVzBBBjbGVhclZvdGVFbnRyaWVzCQETZ2V0Q2xlYXJWb3RlRW50cmllcwEFCWtleVByZWZpeAkAzggCBRBjbGVhclZvdGVFbnRyaWVzBQp2b3RlUmVzdWx0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQd2b3RlS2V5AAEFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgEUa2V5Q2FsY3VsYXRvckFkZHJlc3MAAg4lc19fY2FsY3VsYXRvcgEXa2V5UHJveHlUcmVhc3VyeUFkZHJlc3MAAhElc19fcHJveHlUcmVhc3VyeQEPa2V5Q2hpbGRBZGRyZXNzAAIJJXNfX2NoaWxkARhrZXlCbG9ja1Byb2Nlc3NpbmdSZXdhcmQAAhklc19fYmxvY2tQcm9jZXNzaW5nUmV3YXJkARVrZXlOZXh0QmxvY2tUb1Byb2Nlc3MAAhYlc19fbmV4dEJsb2NrVG9Qcm9jZXNzAQxrZXlMcEFzc2V0SWQAAg0lc19fbHBBc3NldElkABdjYWxjdWxhdG9yQWRkcmVzc09wdGlvbgQHJG1hdGNoMAkAnQgCBQR0aGlzCQEUa2V5Q2FsY3VsYXRvckFkZHJlc3MAAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkApggBBQFzAwkAAQIFByRtYXRjaDACBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgAXY2FsY3VsYXRvckFkZHJlc3NPckZhaWwJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgUXY2FsY3VsYXRvckFkZHJlc3NPcHRpb24JAQd3cmFwRXJyAQIaaW52YWxpZCBjYWxjdWxhdG9yIGFkZHJlc3MAGnByb3h5VHJlYXN1cnlBZGRyZXNzT3B0aW9uBAckbWF0Y2gwCQCdCAIFBHRoaXMJARdrZXlQcm94eVRyZWFzdXJ5QWRkcmVzcwADCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwCQCmCAEFAXMDCQABAgUHJG1hdGNoMAIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yABpwcm94eVRyZWFzdXJ5QWRkcmVzc09yRmFpbAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCBRpwcm94eVRyZWFzdXJ5QWRkcmVzc09wdGlvbgkBB3dyYXBFcnIBAh5pbnZhbGlkIHByb3h5IHRyZWFzdXJ5IGFkZHJlc3MBEGtleUNvbmZpZ0FkZHJlc3MAAgolc19fY29uZmlnARJrZXlDaGlsZHJlbkFkZHJlc3MAAhFjb250cmFjdF9jaGlsZHJlbgEWa2V5Vm90aW5nUmVzdWx0QWRkcmVzcwACFmNvbnRyYWN0X3ZvdGluZ19yZXN1bHQBGWtleVByb3Bvc2FsQWxsb3dCcm9hZGNhc3QCB2FkZHJlc3MEdHhJZAkArAICCQCsAgIJAKwCAgIZcHJvcG9zYWxfYWxsb3dfYnJvYWRjYXN0XwkApQgBBQdhZGRyZXNzAgFfCQDYBAEFBHR4SWQBEWtleUludmVzdGVkQnlVc2VyAgxjaGlsZEFkZHJlc3MLdXNlckFkZHJlc3MJALkJAgkAzAgCAghpbnZlc3RvcgkAzAgCCQClCAEFDGNoaWxkQWRkcmVzcwkAzAgCCQClCAEFC3VzZXJBZGRyZXNzBQNuaWwCAV8AE2NvbmZpZ0FkZHJlc3NPcHRpb24EByRtYXRjaDAJAJ0IAgUEdGhpcwkBEGtleUNvbmZpZ0FkZHJlc3MAAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkApggBBQFzAwkAAQIFByRtYXRjaDACBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgATY29uZmlnQWRkcmVzc09yRmFpbAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCBRNjb25maWdBZGRyZXNzT3B0aW9uCQEHd3JhcEVycgECFmludmFsaWQgY29uZmlnIGFkZHJlc3MAGXZvdGluZ1Jlc3VsdEFkZHJlc3NPcHRpb24EByRtYXRjaDAFE2NvbmZpZ0FkZHJlc3NPcHRpb24DCQABAgUHJG1hdGNoMAIHQWRkcmVzcwQBYQUHJG1hdGNoMAQHJG1hdGNoMQkAnQgCBQFhCQEWa2V5Vm90aW5nUmVzdWx0QWRkcmVzcwADCQABAgUHJG1hdGNoMQIGU3RyaW5nBAFzBQckbWF0Y2gxCQCmCAEFAXMDCQABAgUHJG1hdGNoMQIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yAwkAAQIFByRtYXRjaDACBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgAZdm90aW5nUmVzdWx0QWRkcmVzc09yRmFpbAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCBRl2b3RpbmdSZXN1bHRBZGRyZXNzT3B0aW9uCQEHd3JhcEVycgECHWludmFsaWQgdm90aW5nIHJlc3VsdCBhZGRyZXNzABVjaGlsZHJlbkFkZHJlc3NPcHRpb24EByRtYXRjaDAFE2NvbmZpZ0FkZHJlc3NPcHRpb24DCQABAgUHJG1hdGNoMAIHQWRkcmVzcwQBYQUHJG1hdGNoMAQHJG1hdGNoMQkAnQgCBQFhCQESa2V5Q2hpbGRyZW5BZGRyZXNzAAMJAAECBQckbWF0Y2gxAgZTdHJpbmcEAXMFByRtYXRjaDEJAKYIAQUBcwMJAAECBQckbWF0Y2gxAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IDCQABAgUHJG1hdGNoMAIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yABVjaGlsZHJlbkFkZHJlc3NPckZhaWwJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgUVY2hpbGRyZW5BZGRyZXNzT3B0aW9uCQEHd3JhcEVycgECGGludmFsaWQgY2hpbGRyZW4gYWRkcmVzcwAPbHBBc3NldElkT3B0aW9uBAckbWF0Y2gwCQCdCAIFBHRoaXMJAQxrZXlMcEFzc2V0SWQAAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkA2QQBBQFzAwkAAQIFByRtYXRjaDACBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgAPbHBBc3NldElkT3JGYWlsCQETdmFsdWVPckVycm9yTWVzc2FnZQIFD2xwQXNzZXRJZE9wdGlvbgkBB3dyYXBFcnIBAhFpbnZhbGlkIGxwQXNzZXRJZAELb25seUFkZHJlc3MCAWkHYWRkcmVzcwMJAAACCAUBaQZjYWxsZXIFB2FkZHJlc3MGCQEIdGhyb3dFcnIBAhFwZXJtaXNzaW9uIGRlbmllZAEIb25seVRoaXMBAWkJAQtvbmx5QWRkcmVzcwIFAWkFBHRoaXMBDm9ubHlDYWxjdWxhdG9yAQFpCQELb25seUFkZHJlc3MCBQFpBRdjYWxjdWxhdG9yQWRkcmVzc09yRmFpbBcBaQELc3RyaW5nRW50cnkCA2tleQN2YWwDCQEOb25seUNhbGN1bGF0b3IBBQFpCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUDa2V5BQN2YWwFA25pbAUDa2V5CQCUCgIFA25pbAUEdW5pdAFpAQxpbnRlZ2VyRW50cnkCA2tleQN2YWwDCQEOb25seUNhbGN1bGF0b3IBBQFpCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIFA2tleQUDdmFsBQNuaWwFA2tleQkAlAoCBQNuaWwFBHVuaXQBaQEMYm9vbGVhbkVudHJ5AgNrZXkDdmFsAwkBDm9ubHlDYWxjdWxhdG9yAQUBaQkAlAoCCQDMCAIJAQxCb29sZWFuRW50cnkCBQNrZXkFA3ZhbAUDbmlsBQNrZXkJAJQKAgUDbmlsBQR1bml0AWkBC2JpbmFyeUVudHJ5AgNrZXkDdmFsAwkBDm9ubHlDYWxjdWxhdG9yAQUBaQkAlAoCCQDMCAIJAQtCaW5hcnlFbnRyeQIFA2tleQUDdmFsBQNuaWwFA2tleQkAlAoCBQNuaWwFBHVuaXQBaQELZGVsZXRlRW50cnkBA2tleQMJAQ5vbmx5Q2FsY3VsYXRvcgEFAWkJAJQKAgkAzAgCCQELRGVsZXRlRW50cnkBBQNrZXkFA25pbAUDa2V5CQCUCgIFA25pbAUEdW5pdAFpAQdyZWlzc3VlAQZhbW91bnQDCQEOb25seUNhbGN1bGF0b3IBBQFpCQCUCgIJAMwIAgkBB1JlaXNzdWUDBQ9scEFzc2V0SWRPckZhaWwFBmFtb3VudAYFA25pbAUGYW1vdW50CQCUCgIFA25pbAUEdW5pdAFpAQRidXJuAQZhbW91bnQDCQEOb25seUNhbGN1bGF0b3IBBQFpCQCUCgIJAMwIAgkBBEJ1cm4CBQ9scEFzc2V0SWRPckZhaWwFBmFtb3VudAUDbmlsBQZhbW91bnQJAJQKAgUDbmlsBQR1bml0AWkBDXRyYW5zZmVyQXNzZXQDDnJlY2VwaWVudEJ5dGVzBmFtb3VudAdhc3NldElkAwkBDm9ubHlDYWxjdWxhdG9yAQUBaQkAlAoCCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMJAQdBZGRyZXNzAQUOcmVjZXBpZW50Qnl0ZXMFBmFtb3VudAUHYXNzZXRJZAUDbmlsBQZhbW91bnQJAJQKAgUDbmlsBQR1bml0AWkBDnRyYW5zZmVyQXNzZXRzAw5yZWNlcGllbnRCeXRlcwphc3NldHNMaXN0C2Ftb3VudHNMaXN0AwkBDm9ubHlDYWxjdWxhdG9yAQUBaQoBDmFkZE5ld1RyYW5zZmVyAgVhY2N1bQtuZXh0QXNzZXRJZAQLJHQwNzQ1Nzc0ODMFBWFjY3VtBAl0cmFuc2ZlcnMIBQskdDA3NDU3NzQ4MwJfMQQBaggFCyR0MDc0NTc3NDgzAl8yBAtuZXdUcmFuc2ZlcgkBDlNjcmlwdFRyYW5zZmVyAwkBB0FkZHJlc3MBBQ5yZWNlcGllbnRCeXRlcwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFC2Ftb3VudHNMaXN0BQFqCQEPc3RyaW5nVG9Bc3NldElkAQkAkQMCBQphc3NldHNMaXN0BQFqBBB1cGRhdGVkVHJhbnNmZXJzCQDNCAIFCXRyYW5zZmVycwULbmV3VHJhbnNmZXIJAJQKAgUQdXBkYXRlZFRyYW5zZmVycwkAZAIFAWoAAQQLJHQwNzc0Mzc4MjQKAAIkbAUKYXNzZXRzTGlzdAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgUDbmlsAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBDmFkZE5ld1RyYW5zZmVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKBA9hc3NldHNUcmFuc2ZlcnMIBQskdDA3NzQzNzgyNAJfMQQKX2xhc3RJbmRleAgFCyR0MDc3NDM3ODI0Al8yCQCUCgIFD2Fzc2V0c1RyYW5zZmVycwUEdW5pdAkAlAoCBQNuaWwFBHVuaXQBaQENdHJhbnNmZXJXYXZlcwIOcmVjZXBpZW50Qnl0ZXMGYW1vdW50AwkBDm9ubHlDYWxjdWxhdG9yAQUBaQkAlAoCCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMJAQdBZGRyZXNzAQUOcmVjZXBpZW50Qnl0ZXMFBmFtb3VudAUEdW5pdAUDbmlsBQZhbW91bnQJAJQKAgUDbmlsBQR1bml0AWkBGXRyYW5zZmVyRnJvbVByb3h5VHJlYXN1cnkCDnJlY2lwaWVudEJ5dGVzDXJld2FyZHNBbW91bnQDCQEOb25seUNhbGN1bGF0b3IBBQFpCQCUCgIFA25pbAkA/AcEBRpwcm94eVRyZWFzdXJ5QWRkcmVzc09yRmFpbAINdHJhbnNmZXJXYXZlcwkAzAgCBQ5yZWNpcGllbnRCeXRlcwkAzAgCBQ1yZXdhcmRzQW1vdW50BQNuaWwFA25pbAkAlAoCBQNuaWwFBHVuaXQBaQEIZmluYWxpemUDGG5ld1RyZWFzdXJ5Vm9sdW1lSW5XYXZlcxdwd3JNYW5hZ2Vyc0JvbnVzSW5XYXZlcyB0cmVhc3VyeVZvbHVtZURpZmZBbGxvY2F0aW9uQ29lZgkAlAoCBQNuaWwJAP0HBAUXY2FsY3VsYXRvckFkZHJlc3NPckZhaWwCCGZpbmFsaXplCQDMCAIICAUBaQZjYWxsZXIFYnl0ZXMJAMwIAgUYbmV3VHJlYXN1cnlWb2x1bWVJbldhdmVzCQDMCAIFF3B3ck1hbmFnZXJzQm9udXNJbldhdmVzCQDMCAIFIHRyZWFzdXJ5Vm9sdW1lRGlmZkFsbG9jYXRpb25Db2VmBQNuaWwIBQFpCHBheW1lbnRzAWkBEGZpbmFsaXplUkVBRE9OTFkDGG5ld1RyZWFzdXJ5Vm9sdW1lSW5XYXZlcxdwd3JNYW5hZ2Vyc0JvbnVzSW5XYXZlcyB0cmVhc3VyeVZvbHVtZURpZmZBbGxvY2F0aW9uQ29lZgkAlAoCBQNuaWwJAP0HBAUXY2FsY3VsYXRvckFkZHJlc3NPckZhaWwCEGZpbmFsaXplUkVBRE9OTFkJAMwIAgUYbmV3VHJlYXN1cnlWb2x1bWVJbldhdmVzCQDMCAIFF3B3ck1hbmFnZXJzQm9udXNJbldhdmVzCQDMCAIFIHRyZWFzdXJ5Vm9sdW1lRGlmZkFsbG9jYXRpb25Db2VmBQNuaWwFA25pbAFpAQdjbGFpbUxQAAkAlAoCBQNuaWwJAP0HBAUXY2FsY3VsYXRvckFkZHJlc3NPckZhaWwCB2NsYWltTFAJAMwIAggIBQFpBmNhbGxlcgVieXRlcwUDbmlsCAUBaQhwYXltZW50cwFpAQ9jbGFpbUNvbGxhdGVyYWwBB3R4SWRTdHIJAJQKAgUDbmlsCQD9BwQFF2NhbGN1bGF0b3JBZGRyZXNzT3JGYWlsAg9jbGFpbUNvbGxhdGVyYWwJAMwIAggIBQFpBmNhbGxlcgVieXRlcwkAzAgCBQd0eElkU3RyBQNuaWwIBQFpCHBheW1lbnRzAWkBE2NsYWltQ29sbGF0ZXJhbEJ1bGsBBXR4SWRzCQCUCgIFA25pbAkA/QcEBRdjYWxjdWxhdG9yQWRkcmVzc09yRmFpbAITY2xhaW1Db2xsYXRlcmFsQnVsawkAzAgCCAgFAWkGY2FsbGVyBWJ5dGVzCQDMCAIFBXR4SWRzBQNuaWwIBQFpCHBheW1lbnRzAWkBBmludmVzdAAJAJQKAgUDbmlsCQD9BwQFF2NhbGN1bGF0b3JBZGRyZXNzT3JGYWlsAgZpbnZlc3QJAMwIAggIBQFpBmNhbGxlcgVieXRlcwUDbmlsCAUBaQhwYXltZW50cwFpAQh3aXRoZHJhdwAJAJQKAgUDbmlsCQD9BwQFF2NhbGN1bGF0b3JBZGRyZXNzT3JGYWlsAgh3aXRoZHJhdwkAzAgCCAgFAWkGY2FsbGVyBWJ5dGVzBQNuaWwIBQFpCHBheW1lbnRzAWkBDmNhbmNlbFdpdGhkcmF3AQd0eElkU3RyCQCUCgIFA25pbAkA/QcEBRdjYWxjdWxhdG9yQWRkcmVzc09yRmFpbAIOY2FuY2VsV2l0aGRyYXcJAMwIAggIBQFpBmNhbGxlcgVieXRlcwkAzAgCCQDZBAEFB3R4SWRTdHIFA25pbAgFAWkIcGF5bWVudHMBaQENcHJvY2Vzc0Jsb2NrcwAJAJQKAgUDbmlsCQD9BwQFF2NhbGN1bGF0b3JBZGRyZXNzT3JGYWlsAg1wcm9jZXNzQmxvY2tzCQDMCAIICAUBaQZjYWxsZXIFYnl0ZXMFA25pbAgFAWkIcGF5bWVudHMBaQEXY2xhaW1Db2xsYXRlcmFsUkVBRE9OTFkCC3VzZXJBZGRyZXNzB3R4SWRTdHIJAJQKAgUDbmlsCQD9BwQFF2NhbGN1bGF0b3JBZGRyZXNzT3JGYWlsAhdjbGFpbUNvbGxhdGVyYWxSRUFET05MWQkAzAgCCQDZBAEFC3VzZXJBZGRyZXNzCQDMCAIFB3R4SWRTdHIFA25pbAUDbmlsAWkBG2NsYWltQ29sbGF0ZXJhbEJ1bGtSRUFET05MWQILdXNlckFkZHJlc3MFdHhJZHMJAJQKAgUDbmlsCQD9BwQFF2NhbGN1bGF0b3JBZGRyZXNzT3JGYWlsAhtjbGFpbUNvbGxhdGVyYWxCdWxrUkVBRE9OTFkJAMwIAgkA2QQBBQt1c2VyQWRkcmVzcwkAzAgCBQV0eElkcwUDbmlsBQNuaWwBaQELdm90ZUZvclR4SWQBBHR4SWQEE2NhbGxlckFkZHJlc3NTdHJpbmcJANgEAQgIBQFpBmNhbGxlcgVieXRlcwQJa2V5UHJlZml4CQEYa2V5QWxsb3dlZFR4SWRWb3RlUHJlZml4AQUEdHhJZAQGcmVzdWx0CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ5rZXlBbGxvd2VkVHhJZAAFBHR4SWQFA25pbAQRYWxsb3dlZFR4SWRPcHRpb24JAJ0IAgUEdGhpcwkBDmtleUFsbG93ZWRUeElkAAQDZXJyCQDMCAIDCQAAAgkAyAEBCQDZBAEFBHR4SWQFEVRYSURfQllURVNfTEVOR1RIBgkBCHRocm93RXJyAQkArAICBQR0eElkAhIgaXMgbm90IHZhbGlkIHR4SWQJAMwIAgMDCQAAAgURYWxsb3dlZFR4SWRPcHRpb24FBHVuaXQGCQECIT0CCQEFdmFsdWUBBRFhbGxvd2VkVHhJZE9wdGlvbgUEdHhJZAYJAQh0aHJvd0VycgEJAKwCAgUEdHhJZAITIGlzIGFscmVhZHkgYWxsb3dlZAUDbmlsAwkAAAIFA2VycgUDZXJyCQEMdm90ZUlOVEVSTkFMBAUTY2FsbGVyQWRkcmVzc1N0cmluZwUJa2V5UHJlZml4BQZRVU9SVU0FBnJlc3VsdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECdHgBBnZlcmlmeQAECmJ5UHJvcG9zYWwEByRtYXRjaDAFGXZvdGluZ1Jlc3VsdEFkZHJlc3NPcHRpb24DCQABAgUHJG1hdGNoMAIHQWRkcmVzcwQPcHJvcG9zYWxBZGRyZXNzBQckbWF0Y2gwCQELdmFsdWVPckVsc2UCCQCbCAIFD3Byb3Bvc2FsQWRkcmVzcwkBGWtleVByb3Bvc2FsQWxsb3dCcm9hZGNhc3QCBQR0aGlzCAUCdHgCaWQHBwQIYnlBZG1pbnMJAAACCAUCdHgCaWQJANkEAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzCQEOa2V5QWxsb3dlZFR4SWQAAgAEB2J5T3duZXIDCQBnAgkAkAMBCQENZ2V0QWRtaW5zTGlzdAAFBlFVT1JVTQcJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAIBQJ0eA9zZW5kZXJQdWJsaWNLZXkDAwUKYnlQcm9wb3NhbAYFCGJ5QWRtaW5zBgUHYnlPd25lcjOTaZg=", "height": 2713039, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 6rZYqRv93Ti1irFpscXvdstUtCWvnDFPVAn9AqD7LcaP Next: 91YTspwf5m6NRyGGsdJj2rmiHdHEY44zmoxDSr9sWL5f Diff:
OldNewDifferences
33 {-# CONTENT_TYPE DAPP #-}
44 let SEP = "__"
55
6-let CONTRACT_NAME = "calculator.ride"
7-
8-let SCALE8 = 100000000
9-
10-let PENDING = "PENDING"
11-
126 let WAVES = "WAVES"
137
14-func wrapErr (s) = ((CONTRACT_NAME + ": ") + s)
8+let contractFilename = "factory.ride"
9+
10+func wrapErr (s) = ((contractFilename + ": ") + s)
1511
1612
1713 func throwErr (s) = throw(wrapErr(s))
18-
19-
20-func assetIdToString (assetId) = match assetId {
21- case b: ByteVector =>
22- toBase58String(b)
23- case _: Unit =>
24- WAVES
25- case _ =>
26- throw("Match error")
27-}
2814
2915
3016 func stringToAssetId (s) = if ((s == WAVES))
3218 else fromBase58String(s)
3319
3420
35-func abs (n) = if ((0 > n))
36- then -(n)
37- else n
21+let ADMIN_LIST_SIZE = 5
22+
23+let QUORUM = 3
24+
25+let TXID_BYTES_LENGTH = 32
26+
27+func keyAllowedTxIdVotePrefix (txId) = makeString(["%s%s%s", "allowTxId", txId], SEP)
3828
3929
40-func keyFactoryAddress () = makeString(["%s", "factory"], SEP)
30+func keyFullAdminVote (prefix,adminAddress) = makeString([prefix, adminAddress], SEP)
4131
4232
43-func keyManagerPublicKey () = makeString(["%s", "managerPublicKey"], SEP)
33+func keyAdminAddressList () = makeString(["%s", "adminAddressList"], SEP)
4434
4535
46-func keyLpAssetId () = makeString(["%s", "lpAssetId"], SEP)
36+func keyAllowedTxId () = makeString(["%s", "txId"], SEP)
4737
4838
49-func keyProxyTreasuryAddress () = makeString(["%s", "proxyTreasury"], SEP)
39+func getAdminVote (prefix,admin) = {
40+ let voteKey = keyFullAdminVote(prefix, admin)
41+ valueOrElse(getInteger(voteKey), 0)
42+ }
5043
5144
52-func keyMainTreasuryAddress () = makeString(["%s", "mainTreasury"], SEP)
45+func getAdminsList () = match getString(this, keyAdminAddressList()) {
46+ case s: String =>
47+ split(s, SEP)
48+ case _ =>
49+ nil
50+}
5351
5452
55-func keyBusinessTreasuryAddress () = makeString(["%s", "businessTreasury"], SEP)
53+func isInAdminList (address) = containsElement(getAdminsList(), address)
5654
5755
58-func keyBusinessTreasuryPart () = makeString(["%s", "businessTreasuryPart"], SEP)
56+func genVotesKeysHelper (a,adminAddress) = {
57+ let $t013751399 = a
58+ let result = $t013751399._1
59+ let prefix = $t013751399._2
60+ $Tuple2((result :+ keyFullAdminVote(prefix, adminAddress)), prefix)
61+ }
5962
6063
61-func keyInvested (assetId) = makeString(["%s%s", "invested", assetIdToString(assetId)], SEP)
64+func genVotesKeys (keyPrefix) = {
65+ let adminList = keyAdminAddressList()
66+ let $t015461630 = {
67+ let $l = getAdminsList()
68+ let $s = size($l)
69+ let $acc0 = $Tuple2(nil, keyPrefix)
70+ func $f0_1 ($a,$i) = if (($i >= $s))
71+ then $a
72+ else genVotesKeysHelper($a, $l[$i])
73+
74+ func $f0_2 ($a,$i) = if (($i >= $s))
75+ then $a
76+ else throw("List size exceeds 5")
77+
78+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
79+ }
80+ let result = $t015461630._1
81+ let prefix = $t015461630._2
82+ result
83+ }
6284
6385
64-func keyDonated (assetId) = makeString(["%s%s", "donated", assetIdToString(assetId)], SEP)
86+func countVotesHelper (result,voteKey) = (result + valueOrElse(getInteger(voteKey), 0))
6587
6688
67-func keyAvailable (userAddress) = makeString(["%s%s", "available", toString(userAddress)], SEP)
89+func countVotes (prefix) = {
90+ let votes = genVotesKeys(prefix)
91+ let $l = votes
92+ let $s = size($l)
93+ let $acc0 = 0
94+ func $f0_1 ($a,$i) = if (($i >= $s))
95+ then $a
96+ else countVotesHelper($a, $l[$i])
97+
98+ func $f0_2 ($a,$i) = if (($i >= $s))
99+ then $a
100+ else throw("List size exceeds 5")
101+
102+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
103+ }
68104
69105
70-func keyClaimed (userAddress) = makeString(["%s%s", "claimed", toString(userAddress)], SEP)
106+func clearVotesHelper (result,key) = (result :+ DeleteEntry(key))
71107
72108
73-func keyCurrentPeriod () = makeString(["%s", "currentPeriod"], SEP)
109+func getClearVoteEntries (prefix) = {
110+ let votes = genVotesKeys(prefix)
111+ let $l = votes
112+ let $s = size($l)
113+ let $acc0 = nil
114+ func $f0_1 ($a,$i) = if (($i >= $s))
115+ then $a
116+ else clearVotesHelper($a, $l[$i])
117+
118+ func $f0_2 ($a,$i) = if (($i >= $s))
119+ then $a
120+ else throw("List size exceeds 5")
121+
122+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
123+ }
74124
75125
76-func keyPriceForPeriod (period) = makeString(["%s%d", "price", toString(period)], SEP)
126+func voteINTERNAL (callerAddressString,keyPrefix,minVotes,voteResult) = {
127+ let voteKey = keyFullAdminVote(keyPrefix, callerAddressString)
128+ let adminCurrentVote = getAdminVote(keyPrefix, callerAddressString)
129+ let err = if (!(isInAdminList(callerAddressString)))
130+ then throwErr((("Address: " + callerAddressString) + " not in Admin list"))
131+ else if ((adminCurrentVote == 1))
132+ then throwErr((voteKey + " you already voted"))
133+ else unit
134+ if ((err == err))
135+ then {
136+ let votes = countVotes(keyPrefix)
137+ if (((votes + 1) >= minVotes))
138+ then {
139+ let clearVoteEntries = getClearVoteEntries(keyPrefix)
140+ (clearVoteEntries ++ voteResult)
141+ }
142+ else [IntegerEntry(voteKey, 1)]
143+ }
144+ else throw("Strict value is not equal to itself.")
145+ }
77146
78147
79-func keyStartHeight (period) = makeString(["%s%d", "startHeight", toString(period)], SEP)
148+func keyCalculatorAddress () = "%s__calculator"
80149
81150
82-func keyPowerManagerBonus (period) = makeString(["%s%d", "powerManagerBonus", toString(period)], SEP)
151+func keyProxyTreasuryAddress () = "%s__proxyTreasury"
83152
84153
85-func keyPeriodLength () = "%s__periodLength"
86-
87-
88-func keyInvestPeriodLength () = "%s__investPeriodLength"
154+func keyChildAddress () = "%s__child"
89155
90156
91157 func keyBlockProcessingReward () = "%s__blockProcessingReward"
94160 func keyNextBlockToProcess () = "%s__nextBlockToProcess"
95161
96162
97-func keyBlockProcessed (height) = makeString(["%s%d", "blockProcessed", toString(height)], SEP)
163+func keyLpAssetId () = "%s__lpAssetId"
98164
99165
100-func keyWithdrawal () = "%s__withdrawal"
101-
102-
103-func keyWithdrawalRequest (userAddress,txId) = makeString(["%s%s%s", "withdrawal", toString(userAddress), toBase58String(txId)], SEP)
104-
105-
106-func valueWithdrawalRequest (status,lpAssetAmount,targetPeriod,claimTxId) = {
107- let claimTxIdStr = match claimTxId {
108- case b: ByteVector =>
109- toBase58String(b)
110- case _: Unit =>
111- "SOON"
112- case _ =>
113- throw("Match error")
114- }
115- makeString(["%s%d%d%s", status, toString(lpAssetAmount), toString(targetPeriod), claimTxIdStr], SEP)
116- }
117-
118-
119-func keyWithdrawalHistory (userAddress,txId) = makeString(["%s%s%s", "withdrawalHistory", toString(userAddress), toBase58String(txId)], SEP)
120-
121-
122-func keyPeriodWithdrawalAssetIds (period) = makeString(["%s%d", "periodReward", toString(period)], SEP)
123-
124-
125-func keyPeriodWithdrawalAmounts (period) = makeString(["%s%d", "periodRewardAmount", toString(period)], SEP)
126-
127-
128-func parseWithdrawalRequestValueOrFail (s) = {
129- let parts = split(s, SEP)
130- if ((size(parts) == 5))
131- then {
132- let status = parts[1]
133- let lpAssetAmount = valueOrErrorMessage(parseInt(parts[2]), wrapErr("invalid lpAssetAmount"))
134- let targetPeriod = valueOrErrorMessage(parseInt(parts[3]), wrapErr("invalid targetPeriod"))
135- let claimTxId = parts[4]
136- $Tuple4(status, lpAssetAmount, targetPeriod, claimTxId)
137- }
138- else throwErr("invalid withdrawal request value")
139- }
140-
141-
142-let factoryAddressOption = match getString(this, keyFactoryAddress()) {
166+let calculatorAddressOption = match getString(this, keyCalculatorAddress()) {
143167 case s: String =>
144168 addressFromString(s)
145169 case _: Unit =>
148172 throw("Match error")
149173 }
150174
151-let factoryAddressOrFail = valueOrErrorMessage(factoryAddressOption, wrapErr("invalid factory address"))
175+let calculatorAddressOrFail = valueOrErrorMessage(calculatorAddressOption, wrapErr("invalid calculator address"))
152176
153-let lpAssetIdOption = match factoryAddressOption {
154- case a: Address =>
155- match getString(a, keyLpAssetId()) {
156- case s: String =>
157- fromBase58String(s)
158- case _: Unit =>
159- unit
160- case _ =>
161- throw("Match error")
162- }
177+let proxyTreasuryAddressOption = match getString(this, keyProxyTreasuryAddress()) {
178+ case s: String =>
179+ addressFromString(s)
163180 case _: Unit =>
164181 unit
165182 case _ =>
166183 throw("Match error")
167184 }
168185
169-let lpAssetIdOrFail = valueOrErrorMessage(lpAssetIdOption, wrapErr("invalid lpAssetId"))
186+let proxyTreasuryAddressOrFail = valueOrErrorMessage(proxyTreasuryAddressOption, wrapErr("invalid proxy treasury address"))
170187
171-let proxyTreasuryAddressOption = match factoryAddressOption {
188+func keyConfigAddress () = "%s__config"
189+
190+
191+func keyChildrenAddress () = "contract_children"
192+
193+
194+func keyVotingResultAddress () = "contract_voting_result"
195+
196+
197+func keyProposalAllowBroadcast (address,txId) = ((("proposal_allow_broadcast_" + toString(address)) + "_") + toBase58String(txId))
198+
199+
200+func keyInvestedByUser (childAddress,userAddress) = makeString(["investor", toString(childAddress), toString(userAddress)], "_")
201+
202+
203+let configAddressOption = match getString(this, keyConfigAddress()) {
204+ case s: String =>
205+ addressFromString(s)
206+ case _: Unit =>
207+ unit
208+ case _ =>
209+ throw("Match error")
210+}
211+
212+let configAddressOrFail = valueOrErrorMessage(configAddressOption, wrapErr("invalid config address"))
213+
214+let votingResultAddressOption = match configAddressOption {
172215 case a: Address =>
173- match getString(a, keyProxyTreasuryAddress()) {
216+ match getString(a, keyVotingResultAddress()) {
174217 case s: String =>
175218 addressFromString(s)
176219 case _: Unit =>
184227 throw("Match error")
185228 }
186229
187-let proxyTreasuryAddressOrFail = valueOrErrorMessage(proxyTreasuryAddressOption, wrapErr("invalid proxy treasury address"))
230+let votingResultAddressOrFail = valueOrErrorMessage(votingResultAddressOption, wrapErr("invalid voting result address"))
188231
189-let mainTreasuryAddressOption = match factoryAddressOption {
232+let childrenAddressOption = match configAddressOption {
190233 case a: Address =>
191- match getString(a, keyMainTreasuryAddress()) {
234+ match getString(a, keyChildrenAddress()) {
192235 case s: String =>
193236 addressFromString(s)
194237 case _: Unit =>
202245 throw("Match error")
203246 }
204247
205-let businessTreasuryAddressOption = match factoryAddressOption {
206- case a: Address =>
207- match getString(a, keyBusinessTreasuryAddress()) {
208- case s: String =>
209- addressFromString(s)
210- case _: Unit =>
211- unit
212- case _ =>
213- throw("Match error")
214- }
248+let childrenAddressOrFail = valueOrErrorMessage(childrenAddressOption, wrapErr("invalid children address"))
249+
250+let lpAssetIdOption = match getString(this, keyLpAssetId()) {
251+ case s: String =>
252+ fromBase58String(s)
215253 case _: Unit =>
216254 unit
217255 case _ =>
218256 throw("Match error")
219257 }
220258
221-let mainTreasuryAddressOrFail = valueOrErrorMessage(mainTreasuryAddressOption, wrapErr("invalid main treasury address"))
222-
223-let businessTreasuryAddressOrFail = valueOrErrorMessage(businessTreasuryAddressOption, wrapErr("invalid business treasury address"))
224-
225-func getManagerPublicKeyOrUnit () = match factoryAddressOption {
226- case fa: Address =>
227- match getString(fa, keyManagerPublicKey()) {
228- case pub: String =>
229- fromBase58String(pub)
230- case _ =>
231- unit
232- }
233- case _ =>
234- unit
235-}
236-
259+let lpAssetIdOrFail = valueOrErrorMessage(lpAssetIdOption, wrapErr("invalid lpAssetId"))
237260
238261 func onlyAddress (i,address) = if ((i.caller == address))
239262 then true
240263 else throwErr("permission denied")
241264
242265
243-func onlyFactory (i) = onlyAddress(i, factoryAddressOrFail)
266+func onlyThis (i) = onlyAddress(i, this)
244267
245268
246-func rewardForOption (rewards,target) = {
247- let s = size(rewards)
248- let $t057855810 = rewards[0]
249- let a0 = $t057855810._1
250- let r0 = $t057855810._2
251- let $t058135838 = rewards[1]
252- let a1 = $t058135838._1
253- let r1 = $t058135838._2
254- let $t058415866 = rewards[2]
255- let a2 = $t058415866._1
256- let r2 = $t058415866._2
257- if (if ((s > 0))
258- then (a0 == target)
259- else false)
260- then r0
261- else if (if ((s > 1))
262- then (a1 == target)
263- else false)
264- then r1
265- else if (if ((s > 2))
266- then (a2 == target)
267- else false)
268- then r2
269- else unit
270- }
271-
272-
273-func finalizeINTERNAL (newTreasuryVolumeInWaves,pwrManagersBonusInWaves,treasuryVolumeDiffAllocationCoef) = {
274- let donatedWavesAmount = valueOrElse(getInteger(factoryAddressOrFail, keyDonated(unit)), 0)
275- let investedWavesAmount = valueOrElse(getInteger(factoryAddressOrFail, keyInvested(unit)), 0)
276- let currentTreasuryVolumeInWaves = (donatedWavesAmount + investedWavesAmount)
277- let profitRaw = (newTreasuryVolumeInWaves - currentTreasuryVolumeInWaves)
278- let pwrManagersBonusAmount = if (if ((profitRaw >= pwrManagersBonusInWaves))
279- then true
280- else (pwrManagersBonusInWaves == 0))
281- then pwrManagersBonusInWaves
282- else throwErr("power bonus is more than profit")
283- let profit = (profitRaw - pwrManagersBonusAmount)
284- let donationPart = if ((currentTreasuryVolumeInWaves > 0))
285- then fraction(donatedWavesAmount, SCALE8, currentTreasuryVolumeInWaves)
286- else 0
287- let donationProfitPartRaw = fraction(profit, donationPart, SCALE8)
288- let investmentProfitPartRaw = (profit - donationProfitPartRaw)
289- let treasuryVolumeDiffAllocationCoefAbs = abs(treasuryVolumeDiffAllocationCoef)
290- let amountToDonation = fraction(investmentProfitPartRaw, if ((0 > treasuryVolumeDiffAllocationCoef))
291- then treasuryVolumeDiffAllocationCoefAbs
292- else 0, SCALE8)
293- let amountToInvestment = fraction(donationProfitPartRaw, if ((treasuryVolumeDiffAllocationCoef > 0))
294- then treasuryVolumeDiffAllocationCoefAbs
295- else 0, SCALE8)
296- let donationProfitPart = ((donationProfitPartRaw - amountToInvestment) + amountToDonation)
297- let investmentProfitPart = ((investmentProfitPartRaw - amountToDonation) + amountToInvestment)
298- let donatedWavesAmountNewRaw = (donatedWavesAmount + donationProfitPart)
299- let investedWavesAmountNewRaw = (investedWavesAmount + investmentProfitPart)
300- let donatedPartDebt = min([0, donatedWavesAmountNewRaw])
301- let investedPartDebt = min([0, investedWavesAmountNewRaw])
302- let donatedWavesAmountNew = (max([0, donatedWavesAmountNewRaw]) + investedPartDebt)
303- let investedWavesAmountNew = (max([0, investedWavesAmountNewRaw]) + donatedPartDebt)
304- let lpAssetQuantity = valueOrErrorMessage(assetInfo(lpAssetIdOrFail), wrapErr("invalid lpAsset info")).quantity
305- let newPrice = fraction(investedWavesAmountNew, SCALE8, lpAssetQuantity)
306- let checkIfPriceNotZero = if ((newPrice != 0))
307- then true
308- else throwErr("LP price cannot be 0")
309- if ((checkIfPriceNotZero == checkIfPriceNotZero))
310- then {
311- let lpAssetAmountToBurn = valueOrElse(getInteger(factoryAddressOrFail, keyWithdrawal()), 0)
312- let paymentAmountMin = max([0, fraction(lpAssetAmountToBurn, newPrice, SCALE8)])
313- let finalInvestedWavesAmount = (investedWavesAmountNew - paymentAmountMin)
314- let lpAssetFinalQuantity = (lpAssetQuantity - lpAssetAmountToBurn)
315- $Tuple6(paymentAmountMin, finalInvestedWavesAmount, donatedWavesAmountNew, newPrice, lpAssetAmountToBurn, lpAssetFinalQuantity)
316- }
317- else throw("Strict value is not equal to itself.")
318- }
319-
320-
321-func claimCollateralINTERNAL (userAddressBytes,txId) = {
322- let userAddress = Address(userAddressBytes)
323- let currentPeriodOrFail = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyCurrentPeriod()), wrapErr("invalid period"))
324- let withdrawalRequestOption = valueOrErrorMessage(getString(factoryAddressOrFail, keyWithdrawalRequest(userAddress, txId)), wrapErr("invalid withdrawal request"))
325- let $t092819394 = parseWithdrawalRequestValueOrFail(withdrawalRequestOption)
326- let status = $t092819394._1
327- let lpAssetAmount = $t092819394._2
328- let targetPeriod = $t092819394._3
329- let claimTxId = $t092819394._4
330- if ((targetPeriod > currentPeriodOrFail))
331- then throwErr("invalid withdrawal request period")
332- else {
333- let priceOrFail = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyPriceForPeriod(targetPeriod)), wrapErr("invalid price"))
334- let wavesAmount = if ((priceOrFail > 0))
335- then fraction(lpAssetAmount, priceOrFail, SCALE8)
336- else 0
337- let assetsString = getStringValue(factoryAddressOrFail, keyPeriodWithdrawalAssetIds(currentPeriodOrFail))
338- let amountsString = getStringValue(factoryAddressOrFail, keyPeriodWithdrawalAmounts(currentPeriodOrFail))
339- $Tuple6(userAddress, lpAssetAmount, targetPeriod, wavesAmount, assetsString, amountsString)
340- }
341- }
342-
343-
344-func claimCollateralREADONLYStringResponse (userAddressBytes,txId) = {
345- let $t01018110347 = claimCollateralINTERNAL(userAddressBytes, txId)
346- let userAddress = $t01018110347._1
347- let lpAssetAmount = $t01018110347._2
348- let targetPeriod = $t01018110347._3
349- let wavesAmount = $t01018110347._4
350- let assetsString = $t01018110347._5
351- let amountsString = $t01018110347._6
352- let assets = makeString(removeByIndex(split_51C(assetsString, SEP), 0), ":")
353- let amounts = makeString(removeByIndex(split_51C(amountsString, SEP), 0), ":")
354- makeString(["%d%s%s", toString(wavesAmount), assets, amounts], SEP)
355- }
269+func onlyCalculator (i) = onlyAddress(i, calculatorAddressOrFail)
356270
357271
358272 @Callable(i)
359-func claimLP (userAddressBytes) = {
360- let checkCaller = onlyFactory(i)
361- if ((checkCaller == checkCaller))
362- then {
363- let userAddress = Address(userAddressBytes)
364- let available = valueOrElse(getInteger(factoryAddressOrFail, keyAvailable(userAddress)), 0)
365- let claimed = valueOrElse(getInteger(factoryAddressOrFail, keyClaimed(userAddress)), 0)
366- let factoryActions = if ((available > 0))
367- then [invoke(factoryAddressOrFail, "transferAsset", [userAddressBytes, available, lpAssetIdOrFail], nil), invoke(factoryAddressOrFail, "integerEntry", [keyAvailable(userAddress), 0], nil), invoke(factoryAddressOrFail, "integerEntry", [keyClaimed(userAddress), (claimed + available)], nil)]
368- else throwErr("nothing to claim")
369- $Tuple2(nil, factoryActions)
370- }
371- else throw("Strict value is not equal to itself.")
372- }
273+func stringEntry (key,val) = if (onlyCalculator(i))
274+ then $Tuple2([StringEntry(key, val)], key)
275+ else $Tuple2(nil, unit)
373276
374277
375278
376279 @Callable(i)
377-func finalize (userAddressBytes,newTreasuryVolumeInWaves,pwrManagersBonusInWaves,treasuryVolumeDiffAllocationCoef) = {
378- let checkCaller = onlyFactory(i)
379- if ((checkCaller == checkCaller))
380- then {
381- let currentPeriodOrFail = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyCurrentPeriod()), wrapErr("invalid period"))
382- let periodLength = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyPeriodLength()), wrapErr("invalid period length"))
383- let currentStartHeight = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyStartHeight(currentPeriodOrFail)), wrapErr("invalid start height"))
384- let currentPriceOrFail = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyPriceForPeriod(currentPeriodOrFail)), wrapErr("invalid price"))
385- let nextBlockToProcess = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyNextBlockToProcess()), wrapErr("invalid next block to process"))
386- let periodEndHeight = ((currentStartHeight + periodLength) - 1)
387- let checks = [if ((i.originCaller == mainTreasuryAddressOrFail))
388- then true
389- else throwErr("permission denied"), if ((nextBlockToProcess > periodEndHeight))
390- then true
391- else throwErr("unprocessed blocks"), if ((newTreasuryVolumeInWaves >= 0))
392- then true
393- else throwErr("invalid new treasury volume"), if ((pwrManagersBonusInWaves >= 0))
394- then true
395- else throwErr("invalid PWR managers bonus"), if (if ((treasuryVolumeDiffAllocationCoef >= -(SCALE8)))
396- then (SCALE8 >= treasuryVolumeDiffAllocationCoef)
397- else false)
398- then true
399- else throwErr("invalid treasury volume diff allocation coefficient")]
400- if ((checks == checks))
401- then {
402- let $t01310913369 = finalizeINTERNAL(newTreasuryVolumeInWaves, pwrManagersBonusInWaves, treasuryVolumeDiffAllocationCoef)
403- let paymentAmountMin = $t01310913369._1
404- let finalInvestedWavesAmount = $t01310913369._2
405- let donatedWavesAmountNew = $t01310913369._3
406- let newPrice = $t01310913369._4
407- let lpAssetAmountToBurn = $t01310913369._5
408- let lpAssetFinalQuantity = $t01310913369._6
409- let newPeriod = (currentPeriodOrFail + 1)
410- func addNewAction (actions,payment) = {
411- let $t01351713579 = actions
412- let scriptTransfers = $t01351713579._1
413- let assetIdsString = $t01351713579._2
414- let amountsString = $t01351713579._3
415- let paymentAmount = payment.amount
416- let paymentAssetId = payment.assetId
417- let newAssetIdsString = ("%s" + makeString([assetIdsString, assetIdToString(paymentAssetId)], SEP))
418- let newAmountsString = ("%d" + makeString([amountsString, toString(paymentAmount)], SEP))
419- let newScriptTransfer = ScriptTransfer(factoryAddressOrFail, paymentAmount, paymentAssetId)
420- $Tuple3((scriptTransfers :+ newScriptTransfer), newAssetIdsString, newAmountsString)
421- }
422-
423- let $t01403914130 = {
424- let $l = i.payments
425- let $s = size($l)
426- let $acc0 = $Tuple3(nil, "", "")
427- func $f0_1 ($a,$i) = if (($i >= $s))
428- then $a
429- else addNewAction($a, $l[$i])
430-
431- func $f0_2 ($a,$i) = if (($i >= $s))
432- then $a
433- else throw("List size exceeds 10")
434-
435- $f0_2($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)
436- }
437- let scriptTransfers = $t01403914130._1
438- let AssetIds = $t01403914130._2
439- let Amounts = $t01403914130._3
440- let factoryActions = [invoke(factoryAddressOrFail, "integerEntry", [keyPowerManagerBonus(currentPeriodOrFail), pwrManagersBonusInWaves], nil), invoke(factoryAddressOrFail, "integerEntry", [keyCurrentPeriod(), newPeriod], nil), invoke(factoryAddressOrFail, "integerEntry", [keyPriceForPeriod(newPeriod), newPrice], nil), invoke(factoryAddressOrFail, "integerEntry", [keyStartHeight(newPeriod), (periodEndHeight + 1)], nil), invoke(factoryAddressOrFail, "burn", [lpAssetAmountToBurn], nil), invoke(factoryAddressOrFail, "integerEntry", [keyWithdrawal(), 0], nil), invoke(factoryAddressOrFail, "integerEntry", [keyInvested(unit), finalInvestedWavesAmount], nil), invoke(factoryAddressOrFail, "integerEntry", [keyDonated(unit), donatedWavesAmountNew], nil), invoke(factoryAddressOrFail, "stringEntry", [keyPeriodWithdrawalAssetIds(newPeriod), AssetIds], nil), invoke(factoryAddressOrFail, "stringEntry", [keyPeriodWithdrawalAmounts(newPeriod), Amounts], nil)]
441- $Tuple2(scriptTransfers, factoryActions)
442- }
443- else throw("Strict value is not equal to itself.")
444- }
445- else throw("Strict value is not equal to itself.")
446- }
280+func integerEntry (key,val) = if (onlyCalculator(i))
281+ then $Tuple2([IntegerEntry(key, val)], key)
282+ else $Tuple2(nil, unit)
447283
448284
449285
450286 @Callable(i)
451-func finalizeREADONLY (newTreasuryVolumeInWaves,pwrManagersBonusInWaves,treasuryVolumeDiffAllocationCoef) = {
452- let currentPeriodOrFail = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyCurrentPeriod()), wrapErr("invalid period"))
453- let periodLength = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyPeriodLength()), wrapErr("invalid period length"))
454- let currentStartHeight = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyStartHeight(currentPeriodOrFail)), wrapErr("invalid start height"))
455- let currentPriceOrFail = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyPriceForPeriod(currentPeriodOrFail)), wrapErr("invalid price"))
456- let nextBlockToProcess = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyNextBlockToProcess()), wrapErr("invalid next block to process"))
457- let periodEndHeight = ((currentStartHeight + periodLength) - 1)
458- let checks = [if ((nextBlockToProcess > periodEndHeight))
459- then true
460- else throwErr("unprocessed blocks"), if ((newTreasuryVolumeInWaves >= 0))
461- then true
462- else throwErr("invalid new treasury volume"), if ((pwrManagersBonusInWaves >= 0))
463- then true
464- else throwErr("invalid PWR managers bonus"), if (if ((treasuryVolumeDiffAllocationCoef >= -(SCALE8)))
465- then (SCALE8 >= treasuryVolumeDiffAllocationCoef)
466- else false)
467- then true
468- else throwErr("invalid treasury volume diff allocation coefficient")]
469- if ((checks == checks))
470- then $Tuple2(nil, finalizeINTERNAL(newTreasuryVolumeInWaves, pwrManagersBonusInWaves, treasuryVolumeDiffAllocationCoef))
471- else throw("Strict value is not equal to itself.")
472- }
287+func booleanEntry (key,val) = if (onlyCalculator(i))
288+ then $Tuple2([BooleanEntry(key, val)], key)
289+ else $Tuple2(nil, unit)
473290
474291
475292
476293 @Callable(i)
477-func invest (userAddressBytes) = {
478- let checkCaller = onlyFactory(i)
479- if ((checkCaller == checkCaller))
480- then {
481- let userAddress = Address(userAddressBytes)
482- let currentPeriodOrFail = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyCurrentPeriod()), wrapErr("invalid period"))
483- let currentStartHeight = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyStartHeight(currentPeriodOrFail)), wrapErr("invalid start height"))
484- let investPeriodLength = getIntegerValue(keyInvestPeriodLength())
485- let heightCheck = if (((currentStartHeight + investPeriodLength) > height))
486- then true
487- else throwErr("too late to invest in this period")
488- if ((heightCheck == heightCheck))
489- then {
490- let currentPriceOrFail = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyPriceForPeriod(currentPeriodOrFail)), wrapErr("invalid price"))
491- let payment = if ((size(i.payments) == 1))
492- then i.payments[0]
493- else throwErr("invalid payments")
494- let $t01796718144 = if (if ((payment.assetId == unit))
495- then (payment.amount > 0)
496- else false)
497- then $Tuple2(payment.amount, payment.assetId)
498- else throwErr("invalid payment amount")
499- let paymentAmount = $t01796718144._1
500- let paymentAssetId = $t01796718144._2
501- let treasuryPart = valueOrElse(getInteger(factoryAddressOrFail, keyBusinessTreasuryPart()), 0)
502- let paymentsWithoutTreasuryPart = fraction(paymentAmount, (SCALE8 - treasuryPart), SCALE8)
503- let lpAssetAmount = if ((currentPriceOrFail > 0))
504- then fraction(paymentsWithoutTreasuryPart, SCALE8, currentPriceOrFail)
505- else 0
506- let invested = valueOrElse(getInteger(factoryAddressOrFail, keyInvested(unit)), 0)
507- let actions = [ScriptTransfer(mainTreasuryAddressOrFail, paymentsWithoutTreasuryPart, paymentAssetId), ScriptTransfer(businessTreasuryAddressOrFail, treasuryPart, paymentAssetId)]
508- let factoryActions = [invoke(factoryAddressOrFail, "integerEntry", [keyInvested(unit), (invested + paymentsWithoutTreasuryPart)], nil), invoke(factoryAddressOrFail, "reissue", [lpAssetAmount], nil), invoke(factoryAddressOrFail, "transferAsset", [userAddressBytes, lpAssetAmount, lpAssetIdOrFail], nil)]
509- $Tuple2(actions, factoryActions)
510- }
511- else throw("Strict value is not equal to itself.")
512- }
513- else throw("Strict value is not equal to itself.")
514- }
294+func binaryEntry (key,val) = if (onlyCalculator(i))
295+ then $Tuple2([BinaryEntry(key, val)], key)
296+ else $Tuple2(nil, unit)
515297
516298
517299
518300 @Callable(i)
519-func withdraw (userAddressBytes) = {
520- let checkCaller = onlyFactory(i)
521- if ((checkCaller == checkCaller))
522- then {
523- let userAddress = Address(userAddressBytes)
524- let currentPeriodOrFail = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyCurrentPeriod()), wrapErr("invalid period"))
525- let payment = if ((size(i.payments) == 1))
526- then i.payments[0]
527- else throwErr(wrapErr("invalid payments"))
528- let paymentAssetId = if ((payment.assetId == lpAssetIdOrFail))
529- then lpAssetIdOrFail
530- else throwErr("invalid payment asset")
531- let paymentAmount = if ((payment.amount > 0))
532- then payment.amount
533- else throwErr("invalid payment amount")
534- let withdrawal = valueOrElse(getInteger(factoryAddressOrFail, keyWithdrawal()), 0)
535- let actions = [ScriptTransfer(factoryAddressOrFail, paymentAmount, paymentAssetId)]
536- let factoryActions = [invoke(factoryAddressOrFail, "integerEntry", [keyWithdrawal(), (withdrawal + paymentAmount)], nil), invoke(factoryAddressOrFail, "stringEntry", [keyWithdrawalRequest(userAddress, i.transactionId), valueWithdrawalRequest(PENDING, paymentAmount, (currentPeriodOrFail + 1), unit)], nil)]
537- if ((factoryActions == factoryActions))
538- then $Tuple2(actions, factoryActions)
539- else throw("Strict value is not equal to itself.")
540- }
541- else throw("Strict value is not equal to itself.")
542- }
301+func deleteEntry (key) = if (onlyCalculator(i))
302+ then $Tuple2([DeleteEntry(key)], key)
303+ else $Tuple2(nil, unit)
543304
544305
545306
546307 @Callable(i)
547-func cancelWithdraw (userAddressBytes,txId) = {
548- let checkCaller = onlyFactory(i)
549- if ((checkCaller == checkCaller))
550- then {
551- let userAddress = Address(userAddressBytes)
552- let withdrawalRequestOption = valueOrErrorMessage(getString(factoryAddressOrFail, keyWithdrawalRequest(userAddress, txId)), wrapErr("invalid withdrawal request"))
553- let currentPeriodOrFail = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyCurrentPeriod()), wrapErr("invalid period"))
554- let $t02087820991 = parseWithdrawalRequestValueOrFail(withdrawalRequestOption)
555- let status = $t02087820991._1
556- let lpAssetAmount = $t02087820991._2
557- let targetPeriod = $t02087820991._3
558- let claimTxId = $t02087820991._4
559- let checks = [if ((status == PENDING))
560- then true
561- else throwErr("invalid withdrawal request status"), if ((targetPeriod > currentPeriodOrFail))
562- then true
563- else throwErr("invalid withdrawal request period")]
564- if ((checks == checks))
565- then {
566- let withdrawal = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyWithdrawal()), wrapErr("invalid total withdrawal amount"))
567- let factoryActions = [invoke(factoryAddressOrFail, "integerEntry", [keyWithdrawal(), if ((withdrawal >= lpAssetAmount))
568- then (withdrawal - lpAssetAmount)
569- else throwErr("invalid withdrawal amount")], nil), invoke(factoryAddressOrFail, "deleteEntry", [keyWithdrawalRequest(userAddress, txId)], nil), invoke(factoryAddressOrFail, "transferAsset", [userAddressBytes, lpAssetAmount, lpAssetIdOrFail], nil)]
570- if ((factoryActions == factoryActions))
571- then $Tuple2(nil, factoryActions)
572- else throw("Strict value is not equal to itself.")
573- }
574- else throw("Strict value is not equal to itself.")
575- }
576- else throw("Strict value is not equal to itself.")
577- }
308+func reissue (amount) = if (onlyCalculator(i))
309+ then $Tuple2([Reissue(lpAssetIdOrFail, amount, true)], amount)
310+ else $Tuple2(nil, unit)
578311
579312
580313
581314 @Callable(i)
582-func claimCollateral (userAddressBytes,txId) = {
583- let checkCaller = onlyFactory(i)
584- if ((checkCaller == checkCaller))
585- then {
586- let $t02197722162 = claimCollateralINTERNAL(userAddressBytes, fromBase58String(txId))
587- let userAddress = $t02197722162._1
588- let lpAssetAmount = $t02197722162._2
589- let targetPeriod = $t02197722162._3
590- let wavesAmount = $t02197722162._4
591- let assetsString = $t02197722162._5
592- let amountsString = $t02197722162._6
593- let assetsList = removeByIndex(split_51C(assetsString, SEP), 0)
594- let amountsList = removeByIndex(split_51C(amountsString, SEP), 0)
595- let factoryActions = [invoke(factoryAddressOrFail, "deleteEntry", [keyWithdrawalRequest(userAddress, fromBase58String(txId))], nil), invoke(factoryAddressOrFail, "integerEntry", [keyWithdrawalHistory(userAddress, fromBase58String(txId)), lpAssetAmount], nil), invoke(factoryAddressOrFail, "transferAssets", [userAddressBytes, assetsList, amountsList], nil)]
596- $Tuple2(nil, factoryActions)
597- }
598- else throw("Strict value is not equal to itself.")
599- }
315+func burn (amount) = if (onlyCalculator(i))
316+ then $Tuple2([Burn(lpAssetIdOrFail, amount)], amount)
317+ else $Tuple2(nil, unit)
600318
601319
602320
603321 @Callable(i)
604-func claimCollateralBulk (userAddressBytes,txIds) = {
605- let checkCaller = onlyFactory(i)
606- if ((checkCaller == checkCaller))
607- then {
608- func addNewAction (state,txId) = {
609- let $t02292023119 = claimCollateralINTERNAL(userAddressBytes, fromBase58String(txId))
610- let userAddress = $t02292023119._1
611- let lpAssetAmount = $t02292023119._2
612- let targetPeriod = $t02292023119._3
613- let wavesAmount = $t02292023119._4
614- let assetsString = $t02292023119._5
615- let amountsString = $t02292023119._6
616- let assetsList = removeByIndex(split_51C(assetsString, SEP), 0)
617- let amountsList = removeByIndex(split_51C(amountsString, SEP), 0)
618- let newActions = [invoke(factoryAddressOrFail, "deleteEntry", [keyWithdrawalRequest(userAddress, fromBase58String(txId))], nil), invoke(factoryAddressOrFail, "integerEntry", [keyWithdrawalHistory(userAddress, fromBase58String(txId)), lpAssetAmount], nil), invoke(factoryAddressOrFail, "transferAssets", [userAddressBytes, assetsList, amountsList], nil)]
619- (state ++ newActions)
620- }
621-
622- let allFactoryActions = {
623- let $l = txIds
624- let $s = size($l)
625- let $acc0 = nil
626- func $f0_1 ($a,$i) = if (($i >= $s))
627- then $a
628- else addNewAction($a, $l[$i])
629-
630- func $f0_2 ($a,$i) = if (($i >= $s))
631- then $a
632- else throw("List size exceeds 10")
633-
634- $f0_2($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)
635- }
636- $Tuple2(nil, allFactoryActions)
637- }
638- else throw("Strict value is not equal to itself.")
639- }
322+func transferAsset (recepientBytes,amount,assetId) = if (onlyCalculator(i))
323+ then $Tuple2([ScriptTransfer(Address(recepientBytes), amount, assetId)], amount)
324+ else $Tuple2(nil, unit)
640325
641326
642327
643328 @Callable(i)
644-func claimCollateralREADONLY (userAddressBytes,txId) = {
645- let response = claimCollateralREADONLYStringResponse(userAddressBytes, fromBase58String(txId))
646- $Tuple2(nil, response)
647- }
329+func transferAssets (recepientBytes,assetsList,amountsList) = if (onlyCalculator(i))
330+ then {
331+ func addNewTransfer (accum,nextAssetId) = {
332+ let $t074577483 = accum
333+ let transfers = $t074577483._1
334+ let j = $t074577483._2
335+ let newTransfer = ScriptTransfer(Address(recepientBytes), parseIntValue(amountsList[j]), stringToAssetId(assetsList[j]))
336+ let updatedTransfers = (transfers :+ newTransfer)
337+ $Tuple2(updatedTransfers, (j + 1))
338+ }
339+
340+ let $t077437824 = {
341+ let $l = assetsList
342+ let $s = size($l)
343+ let $acc0 = $Tuple2(nil, 0)
344+ func $f0_1 ($a,$i) = if (($i >= $s))
345+ then $a
346+ else addNewTransfer($a, $l[$i])
347+
348+ func $f0_2 ($a,$i) = if (($i >= $s))
349+ then $a
350+ else throw("List size exceeds 10")
351+
352+ $f0_2($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)
353+ }
354+ let assetsTransfers = $t077437824._1
355+ let _lastIndex = $t077437824._2
356+ $Tuple2(assetsTransfers, unit)
357+ }
358+ else $Tuple2(nil, unit)
648359
649360
650361
651362 @Callable(i)
652-func claimCollateralBulkREADONLY (userAddressBytes,txIds) = {
653- func processTxId (state,txId) = {
654- let response = claimCollateralREADONLYStringResponse(userAddressBytes, fromBase58String(txId))
655- (state :+ response)
656- }
657-
658- let allResponses = {
659- let $l = txIds
660- let $s = size($l)
661- let $acc0 = nil
662- func $f0_1 ($a,$i) = if (($i >= $s))
663- then $a
664- else processTxId($a, $l[$i])
665-
666- func $f0_2 ($a,$i) = if (($i >= $s))
667- then $a
668- else throw("List size exceeds 10")
669-
670- $f0_2($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)
671- }
672- $Tuple2(nil, allResponses)
673- }
363+func transferWaves (recepientBytes,amount) = if (onlyCalculator(i))
364+ then $Tuple2([ScriptTransfer(Address(recepientBytes), amount, unit)], amount)
365+ else $Tuple2(nil, unit)
674366
675367
676368
677369 @Callable(i)
678-func processBlocks (userAddressBytes) = {
679- let checkCaller = onlyFactory(i)
680- if ((checkCaller == checkCaller))
681- then {
682- let userAddress = Address(userAddressBytes)
683- let currentPeriodOrFail = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyCurrentPeriod()), wrapErr("invalid period"))
684- let periodLength = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyPeriodLength()), wrapErr("invalid period length"))
685- let currentStartHeight = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyStartHeight(currentPeriodOrFail)), wrapErr("invalid start height"))
686- let currentPriceOrFail = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyPriceForPeriod(currentPeriodOrFail)), wrapErr("invalid price"))
687- let nextBlockToProcess = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyNextBlockToProcess()), wrapErr("invalid next block to process"))
688- let periodEndHeight = ((currentStartHeight + periodLength) - 1)
689- let blocksProcessingBatchSizeMax = 40
690- let blocksProcessingBatchSize = if (if (if ((height >= nextBlockToProcess))
691- then if ((nextBlockToProcess >= currentStartHeight))
692- then true
693- else (currentPeriodOrFail == 0)
694- else false)
695- then (periodEndHeight >= nextBlockToProcess)
696- else false)
697- then min([((periodEndHeight - nextBlockToProcess) + 1), blocksProcessingBatchSizeMax])
698- else throwErr(wrapErr("invalid target block"))
699- let blockProcessingReward = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyBlockProcessingReward()), wrapErr("invalid block processing reward"))
700- let blockProcessingRewardByGenerator = (blockProcessingReward / blocksProcessingBatchSize)
701- let blockProcessingRewardByGeneratorRemainder = (blockProcessingReward - (blockProcessingRewardByGenerator * blocksProcessingBatchSize))
702- func map (acc,inc) = if ((inc >= blocksProcessingBatchSize))
703- then acc
704- else {
705- let targetBlockHeight = (nextBlockToProcess + inc)
706- let targetBlockInfo = valueOrErrorMessage(blockInfoByHeight(targetBlockHeight), wrapErr("invalid block info"))
707- let treasuryRewardOrFail = valueOrErrorMessage(rewardForOption(targetBlockInfo.rewards, proxyTreasuryAddressOrFail), wrapErr(("invalid treasury reward for height " + toString(targetBlockHeight))))
708- let generator = targetBlockInfo.generator
709- let available = valueOrElse(getInteger(factoryAddressOrFail, keyAvailable(generator)), 0)
710- let callerReward = if ((inc == (blocksProcessingBatchSize - 1)))
711- then (blockProcessingRewardByGenerator + blockProcessingRewardByGeneratorRemainder)
712- else blockProcessingRewardByGenerator
713- let lpAssetAmount = if ((currentPriceOrFail > 0))
714- then fraction((treasuryRewardOrFail - callerReward), SCALE8, currentPriceOrFail)
715- else 0
716- let factoryActionsSingle = [invoke(factoryAddressOrFail, "stringEntry", [keyBlockProcessed(targetBlockHeight), makeString([toBase58String(i.transactionId), toString(currentPeriodOrFail), toString(generator), toBase58String(userAddressBytes), toString(treasuryRewardOrFail), toString(callerReward), toString(lpAssetAmount)], SEP)], nil), invoke(factoryAddressOrFail, "integerEntry", [keyAvailable(generator), (available + lpAssetAmount)], nil)]
717- if ((factoryActionsSingle == factoryActionsSingle))
718- then {
719- let $t02782327856 = acc
720- let lpAssetAcc = $t02782327856._1
721- let rewardAcc = $t02782327856._2
722- $Tuple2((lpAssetAcc + lpAssetAmount), (rewardAcc + treasuryRewardOrFail))
723- }
724- else throw("Strict value is not equal to itself.")
725- }
370+func transferFromProxyTreasury (recipientBytes,rewardsAmount) = if (onlyCalculator(i))
371+ then $Tuple2(nil, invoke(proxyTreasuryAddressOrFail, "transferWaves", [recipientBytes, rewardsAmount], nil))
372+ else $Tuple2(nil, unit)
726373
727- let list = [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]
728- let $t02812328199 = {
729- let $l = list
730- let $s = size($l)
731- let $acc0 = $Tuple2(0, 0)
732- func $f0_1 ($a,$i) = if (($i >= $s))
733- then $a
734- else map($a, $l[$i])
735374
736- func $f0_2 ($a,$i) = if (($i >= $s))
737- then $a
738- else throw("List size exceeds 40")
739375
740- $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($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)
741- }
742- if (($t02812328199 == $t02812328199))
743- then {
744- let rewardAmountTotal = $t02812328199._2
745- let lpAssetAmountTotal = $t02812328199._1
746- let businessTreasuryPart = valueOrElse(getInteger(factoryAddressOrFail, keyBusinessTreasuryPart()), 0)
747- let rewardToBusinessTreasuryAmount = fraction(rewardAmountTotal, businessTreasuryPart, SCALE8)
748- let rewardToMainTreasuryAmount = ((rewardAmountTotal - rewardToBusinessTreasuryAmount) - blockProcessingReward)
749- let invested = valueOrElse(getInteger(factoryAddressOrFail, keyInvested(unit)), 0)
750- let actions = [invoke(factoryAddressOrFail, "reissue", [lpAssetAmountTotal], nil), invoke(factoryAddressOrFail, "integerEntry", [keyNextBlockToProcess(), (nextBlockToProcess + blocksProcessingBatchSize)], nil), invoke(factoryAddressOrFail, "transferFromProxyTreasury", [mainTreasuryAddressOrFail.bytes, rewardToMainTreasuryAmount], nil), invoke(factoryAddressOrFail, "transferFromProxyTreasury", [userAddressBytes, blockProcessingReward], nil), invoke(factoryAddressOrFail, "transferFromProxyTreasury", [businessTreasuryAddressOrFail.bytes, rewardToBusinessTreasuryAmount], nil), invoke(factoryAddressOrFail, "integerEntry", [keyInvested(unit), (invested + rewardToMainTreasuryAmount)], nil)]
751- if ((actions == actions))
752- then $Tuple2(nil, unit)
753- else throw("Strict value is not equal to itself.")
754- }
755- else throw("Strict value is not equal to itself.")
756- }
376+@Callable(i)
377+func finalize (newTreasuryVolumeInWaves,pwrManagersBonusInWaves,treasuryVolumeDiffAllocationCoef) = $Tuple2(nil, reentrantInvoke(calculatorAddressOrFail, "finalize", [i.caller.bytes, newTreasuryVolumeInWaves, pwrManagersBonusInWaves, treasuryVolumeDiffAllocationCoef], i.payments))
378+
379+
380+
381+@Callable(i)
382+func finalizeREADONLY (newTreasuryVolumeInWaves,pwrManagersBonusInWaves,treasuryVolumeDiffAllocationCoef) = $Tuple2(nil, reentrantInvoke(calculatorAddressOrFail, "finalizeREADONLY", [newTreasuryVolumeInWaves, pwrManagersBonusInWaves, treasuryVolumeDiffAllocationCoef], nil))
383+
384+
385+
386+@Callable(i)
387+func claimLP () = $Tuple2(nil, reentrantInvoke(calculatorAddressOrFail, "claimLP", [i.caller.bytes], i.payments))
388+
389+
390+
391+@Callable(i)
392+func claimCollateral (txIdStr) = $Tuple2(nil, reentrantInvoke(calculatorAddressOrFail, "claimCollateral", [i.caller.bytes, txIdStr], i.payments))
393+
394+
395+
396+@Callable(i)
397+func claimCollateralBulk (txIds) = $Tuple2(nil, reentrantInvoke(calculatorAddressOrFail, "claimCollateralBulk", [i.caller.bytes, txIds], i.payments))
398+
399+
400+
401+@Callable(i)
402+func invest () = $Tuple2(nil, reentrantInvoke(calculatorAddressOrFail, "invest", [i.caller.bytes], i.payments))
403+
404+
405+
406+@Callable(i)
407+func withdraw () = $Tuple2(nil, reentrantInvoke(calculatorAddressOrFail, "withdraw", [i.caller.bytes], i.payments))
408+
409+
410+
411+@Callable(i)
412+func cancelWithdraw (txIdStr) = $Tuple2(nil, reentrantInvoke(calculatorAddressOrFail, "cancelWithdraw", [i.caller.bytes, fromBase58String(txIdStr)], i.payments))
413+
414+
415+
416+@Callable(i)
417+func processBlocks () = $Tuple2(nil, reentrantInvoke(calculatorAddressOrFail, "processBlocks", [i.caller.bytes], i.payments))
418+
419+
420+
421+@Callable(i)
422+func claimCollateralREADONLY (userAddress,txIdStr) = $Tuple2(nil, reentrantInvoke(calculatorAddressOrFail, "claimCollateralREADONLY", [fromBase58String(userAddress), txIdStr], nil))
423+
424+
425+
426+@Callable(i)
427+func claimCollateralBulkREADONLY (userAddress,txIds) = $Tuple2(nil, reentrantInvoke(calculatorAddressOrFail, "claimCollateralBulkREADONLY", [fromBase58String(userAddress), txIds], nil))
428+
429+
430+
431+@Callable(i)
432+func voteForTxId (txId) = {
433+ let callerAddressString = toBase58String(i.caller.bytes)
434+ let keyPrefix = keyAllowedTxIdVotePrefix(txId)
435+ let result = [StringEntry(keyAllowedTxId(), txId)]
436+ let allowedTxIdOption = getString(this, keyAllowedTxId())
437+ let err = [if ((size(fromBase58String(txId)) == TXID_BYTES_LENGTH))
438+ then true
439+ else throwErr((txId + " is not valid txId")), if (if ((allowedTxIdOption == unit))
440+ then true
441+ else (value(allowedTxIdOption) != txId))
442+ then true
443+ else throwErr((txId + " is already allowed"))]
444+ if ((err == err))
445+ then voteINTERNAL(callerAddressString, keyPrefix, QUORUM, result)
757446 else throw("Strict value is not equal to itself.")
758447 }
759448
760449
761450 @Verifier(tx)
762451 func verify () = {
763- let publicKey = match getManagerPublicKeyOrUnit() {
764- case pub: ByteVector =>
765- pub
452+ let byProposal = match votingResultAddressOption {
453+ case proposalAddress: Address =>
454+ valueOrElse(getBoolean(proposalAddress, keyProposalAllowBroadcast(this, tx.id)), false)
766455 case _ =>
767- tx.senderPublicKey
456+ false
768457 }
769- sigVerify(tx.bodyBytes, tx.proofs[0], publicKey)
458+ let byAdmins = (tx.id == fromBase58String(valueOrElse(getString(this, keyAllowedTxId()), "")))
459+ let byOwner = if ((size(getAdminsList()) >= QUORUM))
460+ then false
461+ else sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
462+ if (if (byProposal)
463+ then true
464+ else byAdmins)
465+ then true
466+ else byOwner
770467 }
771468
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 7 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let SEP = "__"
55
6-let CONTRACT_NAME = "calculator.ride"
7-
8-let SCALE8 = 100000000
9-
10-let PENDING = "PENDING"
11-
126 let WAVES = "WAVES"
137
14-func wrapErr (s) = ((CONTRACT_NAME + ": ") + s)
8+let contractFilename = "factory.ride"
9+
10+func wrapErr (s) = ((contractFilename + ": ") + s)
1511
1612
1713 func throwErr (s) = throw(wrapErr(s))
18-
19-
20-func assetIdToString (assetId) = match assetId {
21- case b: ByteVector =>
22- toBase58String(b)
23- case _: Unit =>
24- WAVES
25- case _ =>
26- throw("Match error")
27-}
2814
2915
3016 func stringToAssetId (s) = if ((s == WAVES))
3117 then unit
3218 else fromBase58String(s)
3319
3420
35-func abs (n) = if ((0 > n))
36- then -(n)
37- else n
21+let ADMIN_LIST_SIZE = 5
22+
23+let QUORUM = 3
24+
25+let TXID_BYTES_LENGTH = 32
26+
27+func keyAllowedTxIdVotePrefix (txId) = makeString(["%s%s%s", "allowTxId", txId], SEP)
3828
3929
40-func keyFactoryAddress () = makeString(["%s", "factory"], SEP)
30+func keyFullAdminVote (prefix,adminAddress) = makeString([prefix, adminAddress], SEP)
4131
4232
43-func keyManagerPublicKey () = makeString(["%s", "managerPublicKey"], SEP)
33+func keyAdminAddressList () = makeString(["%s", "adminAddressList"], SEP)
4434
4535
46-func keyLpAssetId () = makeString(["%s", "lpAssetId"], SEP)
36+func keyAllowedTxId () = makeString(["%s", "txId"], SEP)
4737
4838
49-func keyProxyTreasuryAddress () = makeString(["%s", "proxyTreasury"], SEP)
39+func getAdminVote (prefix,admin) = {
40+ let voteKey = keyFullAdminVote(prefix, admin)
41+ valueOrElse(getInteger(voteKey), 0)
42+ }
5043
5144
52-func keyMainTreasuryAddress () = makeString(["%s", "mainTreasury"], SEP)
45+func getAdminsList () = match getString(this, keyAdminAddressList()) {
46+ case s: String =>
47+ split(s, SEP)
48+ case _ =>
49+ nil
50+}
5351
5452
55-func keyBusinessTreasuryAddress () = makeString(["%s", "businessTreasury"], SEP)
53+func isInAdminList (address) = containsElement(getAdminsList(), address)
5654
5755
58-func keyBusinessTreasuryPart () = makeString(["%s", "businessTreasuryPart"], SEP)
56+func genVotesKeysHelper (a,adminAddress) = {
57+ let $t013751399 = a
58+ let result = $t013751399._1
59+ let prefix = $t013751399._2
60+ $Tuple2((result :+ keyFullAdminVote(prefix, adminAddress)), prefix)
61+ }
5962
6063
61-func keyInvested (assetId) = makeString(["%s%s", "invested", assetIdToString(assetId)], SEP)
64+func genVotesKeys (keyPrefix) = {
65+ let adminList = keyAdminAddressList()
66+ let $t015461630 = {
67+ let $l = getAdminsList()
68+ let $s = size($l)
69+ let $acc0 = $Tuple2(nil, keyPrefix)
70+ func $f0_1 ($a,$i) = if (($i >= $s))
71+ then $a
72+ else genVotesKeysHelper($a, $l[$i])
73+
74+ func $f0_2 ($a,$i) = if (($i >= $s))
75+ then $a
76+ else throw("List size exceeds 5")
77+
78+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
79+ }
80+ let result = $t015461630._1
81+ let prefix = $t015461630._2
82+ result
83+ }
6284
6385
64-func keyDonated (assetId) = makeString(["%s%s", "donated", assetIdToString(assetId)], SEP)
86+func countVotesHelper (result,voteKey) = (result + valueOrElse(getInteger(voteKey), 0))
6587
6688
67-func keyAvailable (userAddress) = makeString(["%s%s", "available", toString(userAddress)], SEP)
89+func countVotes (prefix) = {
90+ let votes = genVotesKeys(prefix)
91+ let $l = votes
92+ let $s = size($l)
93+ let $acc0 = 0
94+ func $f0_1 ($a,$i) = if (($i >= $s))
95+ then $a
96+ else countVotesHelper($a, $l[$i])
97+
98+ func $f0_2 ($a,$i) = if (($i >= $s))
99+ then $a
100+ else throw("List size exceeds 5")
101+
102+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
103+ }
68104
69105
70-func keyClaimed (userAddress) = makeString(["%s%s", "claimed", toString(userAddress)], SEP)
106+func clearVotesHelper (result,key) = (result :+ DeleteEntry(key))
71107
72108
73-func keyCurrentPeriod () = makeString(["%s", "currentPeriod"], SEP)
109+func getClearVoteEntries (prefix) = {
110+ let votes = genVotesKeys(prefix)
111+ let $l = votes
112+ let $s = size($l)
113+ let $acc0 = nil
114+ func $f0_1 ($a,$i) = if (($i >= $s))
115+ then $a
116+ else clearVotesHelper($a, $l[$i])
117+
118+ func $f0_2 ($a,$i) = if (($i >= $s))
119+ then $a
120+ else throw("List size exceeds 5")
121+
122+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
123+ }
74124
75125
76-func keyPriceForPeriod (period) = makeString(["%s%d", "price", toString(period)], SEP)
126+func voteINTERNAL (callerAddressString,keyPrefix,minVotes,voteResult) = {
127+ let voteKey = keyFullAdminVote(keyPrefix, callerAddressString)
128+ let adminCurrentVote = getAdminVote(keyPrefix, callerAddressString)
129+ let err = if (!(isInAdminList(callerAddressString)))
130+ then throwErr((("Address: " + callerAddressString) + " not in Admin list"))
131+ else if ((adminCurrentVote == 1))
132+ then throwErr((voteKey + " you already voted"))
133+ else unit
134+ if ((err == err))
135+ then {
136+ let votes = countVotes(keyPrefix)
137+ if (((votes + 1) >= minVotes))
138+ then {
139+ let clearVoteEntries = getClearVoteEntries(keyPrefix)
140+ (clearVoteEntries ++ voteResult)
141+ }
142+ else [IntegerEntry(voteKey, 1)]
143+ }
144+ else throw("Strict value is not equal to itself.")
145+ }
77146
78147
79-func keyStartHeight (period) = makeString(["%s%d", "startHeight", toString(period)], SEP)
148+func keyCalculatorAddress () = "%s__calculator"
80149
81150
82-func keyPowerManagerBonus (period) = makeString(["%s%d", "powerManagerBonus", toString(period)], SEP)
151+func keyProxyTreasuryAddress () = "%s__proxyTreasury"
83152
84153
85-func keyPeriodLength () = "%s__periodLength"
86-
87-
88-func keyInvestPeriodLength () = "%s__investPeriodLength"
154+func keyChildAddress () = "%s__child"
89155
90156
91157 func keyBlockProcessingReward () = "%s__blockProcessingReward"
92158
93159
94160 func keyNextBlockToProcess () = "%s__nextBlockToProcess"
95161
96162
97-func keyBlockProcessed (height) = makeString(["%s%d", "blockProcessed", toString(height)], SEP)
163+func keyLpAssetId () = "%s__lpAssetId"
98164
99165
100-func keyWithdrawal () = "%s__withdrawal"
101-
102-
103-func keyWithdrawalRequest (userAddress,txId) = makeString(["%s%s%s", "withdrawal", toString(userAddress), toBase58String(txId)], SEP)
104-
105-
106-func valueWithdrawalRequest (status,lpAssetAmount,targetPeriod,claimTxId) = {
107- let claimTxIdStr = match claimTxId {
108- case b: ByteVector =>
109- toBase58String(b)
110- case _: Unit =>
111- "SOON"
112- case _ =>
113- throw("Match error")
114- }
115- makeString(["%s%d%d%s", status, toString(lpAssetAmount), toString(targetPeriod), claimTxIdStr], SEP)
116- }
117-
118-
119-func keyWithdrawalHistory (userAddress,txId) = makeString(["%s%s%s", "withdrawalHistory", toString(userAddress), toBase58String(txId)], SEP)
120-
121-
122-func keyPeriodWithdrawalAssetIds (period) = makeString(["%s%d", "periodReward", toString(period)], SEP)
123-
124-
125-func keyPeriodWithdrawalAmounts (period) = makeString(["%s%d", "periodRewardAmount", toString(period)], SEP)
126-
127-
128-func parseWithdrawalRequestValueOrFail (s) = {
129- let parts = split(s, SEP)
130- if ((size(parts) == 5))
131- then {
132- let status = parts[1]
133- let lpAssetAmount = valueOrErrorMessage(parseInt(parts[2]), wrapErr("invalid lpAssetAmount"))
134- let targetPeriod = valueOrErrorMessage(parseInt(parts[3]), wrapErr("invalid targetPeriod"))
135- let claimTxId = parts[4]
136- $Tuple4(status, lpAssetAmount, targetPeriod, claimTxId)
137- }
138- else throwErr("invalid withdrawal request value")
139- }
140-
141-
142-let factoryAddressOption = match getString(this, keyFactoryAddress()) {
166+let calculatorAddressOption = match getString(this, keyCalculatorAddress()) {
143167 case s: String =>
144168 addressFromString(s)
145169 case _: Unit =>
146170 unit
147171 case _ =>
148172 throw("Match error")
149173 }
150174
151-let factoryAddressOrFail = valueOrErrorMessage(factoryAddressOption, wrapErr("invalid factory address"))
175+let calculatorAddressOrFail = valueOrErrorMessage(calculatorAddressOption, wrapErr("invalid calculator address"))
152176
153-let lpAssetIdOption = match factoryAddressOption {
154- case a: Address =>
155- match getString(a, keyLpAssetId()) {
156- case s: String =>
157- fromBase58String(s)
158- case _: Unit =>
159- unit
160- case _ =>
161- throw("Match error")
162- }
177+let proxyTreasuryAddressOption = match getString(this, keyProxyTreasuryAddress()) {
178+ case s: String =>
179+ addressFromString(s)
163180 case _: Unit =>
164181 unit
165182 case _ =>
166183 throw("Match error")
167184 }
168185
169-let lpAssetIdOrFail = valueOrErrorMessage(lpAssetIdOption, wrapErr("invalid lpAssetId"))
186+let proxyTreasuryAddressOrFail = valueOrErrorMessage(proxyTreasuryAddressOption, wrapErr("invalid proxy treasury address"))
170187
171-let proxyTreasuryAddressOption = match factoryAddressOption {
188+func keyConfigAddress () = "%s__config"
189+
190+
191+func keyChildrenAddress () = "contract_children"
192+
193+
194+func keyVotingResultAddress () = "contract_voting_result"
195+
196+
197+func keyProposalAllowBroadcast (address,txId) = ((("proposal_allow_broadcast_" + toString(address)) + "_") + toBase58String(txId))
198+
199+
200+func keyInvestedByUser (childAddress,userAddress) = makeString(["investor", toString(childAddress), toString(userAddress)], "_")
201+
202+
203+let configAddressOption = match getString(this, keyConfigAddress()) {
204+ case s: String =>
205+ addressFromString(s)
206+ case _: Unit =>
207+ unit
208+ case _ =>
209+ throw("Match error")
210+}
211+
212+let configAddressOrFail = valueOrErrorMessage(configAddressOption, wrapErr("invalid config address"))
213+
214+let votingResultAddressOption = match configAddressOption {
172215 case a: Address =>
173- match getString(a, keyProxyTreasuryAddress()) {
216+ match getString(a, keyVotingResultAddress()) {
174217 case s: String =>
175218 addressFromString(s)
176219 case _: Unit =>
177220 unit
178221 case _ =>
179222 throw("Match error")
180223 }
181224 case _: Unit =>
182225 unit
183226 case _ =>
184227 throw("Match error")
185228 }
186229
187-let proxyTreasuryAddressOrFail = valueOrErrorMessage(proxyTreasuryAddressOption, wrapErr("invalid proxy treasury address"))
230+let votingResultAddressOrFail = valueOrErrorMessage(votingResultAddressOption, wrapErr("invalid voting result address"))
188231
189-let mainTreasuryAddressOption = match factoryAddressOption {
232+let childrenAddressOption = match configAddressOption {
190233 case a: Address =>
191- match getString(a, keyMainTreasuryAddress()) {
234+ match getString(a, keyChildrenAddress()) {
192235 case s: String =>
193236 addressFromString(s)
194237 case _: Unit =>
195238 unit
196239 case _ =>
197240 throw("Match error")
198241 }
199242 case _: Unit =>
200243 unit
201244 case _ =>
202245 throw("Match error")
203246 }
204247
205-let businessTreasuryAddressOption = match factoryAddressOption {
206- case a: Address =>
207- match getString(a, keyBusinessTreasuryAddress()) {
208- case s: String =>
209- addressFromString(s)
210- case _: Unit =>
211- unit
212- case _ =>
213- throw("Match error")
214- }
248+let childrenAddressOrFail = valueOrErrorMessage(childrenAddressOption, wrapErr("invalid children address"))
249+
250+let lpAssetIdOption = match getString(this, keyLpAssetId()) {
251+ case s: String =>
252+ fromBase58String(s)
215253 case _: Unit =>
216254 unit
217255 case _ =>
218256 throw("Match error")
219257 }
220258
221-let mainTreasuryAddressOrFail = valueOrErrorMessage(mainTreasuryAddressOption, wrapErr("invalid main treasury address"))
222-
223-let businessTreasuryAddressOrFail = valueOrErrorMessage(businessTreasuryAddressOption, wrapErr("invalid business treasury address"))
224-
225-func getManagerPublicKeyOrUnit () = match factoryAddressOption {
226- case fa: Address =>
227- match getString(fa, keyManagerPublicKey()) {
228- case pub: String =>
229- fromBase58String(pub)
230- case _ =>
231- unit
232- }
233- case _ =>
234- unit
235-}
236-
259+let lpAssetIdOrFail = valueOrErrorMessage(lpAssetIdOption, wrapErr("invalid lpAssetId"))
237260
238261 func onlyAddress (i,address) = if ((i.caller == address))
239262 then true
240263 else throwErr("permission denied")
241264
242265
243-func onlyFactory (i) = onlyAddress(i, factoryAddressOrFail)
266+func onlyThis (i) = onlyAddress(i, this)
244267
245268
246-func rewardForOption (rewards,target) = {
247- let s = size(rewards)
248- let $t057855810 = rewards[0]
249- let a0 = $t057855810._1
250- let r0 = $t057855810._2
251- let $t058135838 = rewards[1]
252- let a1 = $t058135838._1
253- let r1 = $t058135838._2
254- let $t058415866 = rewards[2]
255- let a2 = $t058415866._1
256- let r2 = $t058415866._2
257- if (if ((s > 0))
258- then (a0 == target)
259- else false)
260- then r0
261- else if (if ((s > 1))
262- then (a1 == target)
263- else false)
264- then r1
265- else if (if ((s > 2))
266- then (a2 == target)
267- else false)
268- then r2
269- else unit
270- }
271-
272-
273-func finalizeINTERNAL (newTreasuryVolumeInWaves,pwrManagersBonusInWaves,treasuryVolumeDiffAllocationCoef) = {
274- let donatedWavesAmount = valueOrElse(getInteger(factoryAddressOrFail, keyDonated(unit)), 0)
275- let investedWavesAmount = valueOrElse(getInteger(factoryAddressOrFail, keyInvested(unit)), 0)
276- let currentTreasuryVolumeInWaves = (donatedWavesAmount + investedWavesAmount)
277- let profitRaw = (newTreasuryVolumeInWaves - currentTreasuryVolumeInWaves)
278- let pwrManagersBonusAmount = if (if ((profitRaw >= pwrManagersBonusInWaves))
279- then true
280- else (pwrManagersBonusInWaves == 0))
281- then pwrManagersBonusInWaves
282- else throwErr("power bonus is more than profit")
283- let profit = (profitRaw - pwrManagersBonusAmount)
284- let donationPart = if ((currentTreasuryVolumeInWaves > 0))
285- then fraction(donatedWavesAmount, SCALE8, currentTreasuryVolumeInWaves)
286- else 0
287- let donationProfitPartRaw = fraction(profit, donationPart, SCALE8)
288- let investmentProfitPartRaw = (profit - donationProfitPartRaw)
289- let treasuryVolumeDiffAllocationCoefAbs = abs(treasuryVolumeDiffAllocationCoef)
290- let amountToDonation = fraction(investmentProfitPartRaw, if ((0 > treasuryVolumeDiffAllocationCoef))
291- then treasuryVolumeDiffAllocationCoefAbs
292- else 0, SCALE8)
293- let amountToInvestment = fraction(donationProfitPartRaw, if ((treasuryVolumeDiffAllocationCoef > 0))
294- then treasuryVolumeDiffAllocationCoefAbs
295- else 0, SCALE8)
296- let donationProfitPart = ((donationProfitPartRaw - amountToInvestment) + amountToDonation)
297- let investmentProfitPart = ((investmentProfitPartRaw - amountToDonation) + amountToInvestment)
298- let donatedWavesAmountNewRaw = (donatedWavesAmount + donationProfitPart)
299- let investedWavesAmountNewRaw = (investedWavesAmount + investmentProfitPart)
300- let donatedPartDebt = min([0, donatedWavesAmountNewRaw])
301- let investedPartDebt = min([0, investedWavesAmountNewRaw])
302- let donatedWavesAmountNew = (max([0, donatedWavesAmountNewRaw]) + investedPartDebt)
303- let investedWavesAmountNew = (max([0, investedWavesAmountNewRaw]) + donatedPartDebt)
304- let lpAssetQuantity = valueOrErrorMessage(assetInfo(lpAssetIdOrFail), wrapErr("invalid lpAsset info")).quantity
305- let newPrice = fraction(investedWavesAmountNew, SCALE8, lpAssetQuantity)
306- let checkIfPriceNotZero = if ((newPrice != 0))
307- then true
308- else throwErr("LP price cannot be 0")
309- if ((checkIfPriceNotZero == checkIfPriceNotZero))
310- then {
311- let lpAssetAmountToBurn = valueOrElse(getInteger(factoryAddressOrFail, keyWithdrawal()), 0)
312- let paymentAmountMin = max([0, fraction(lpAssetAmountToBurn, newPrice, SCALE8)])
313- let finalInvestedWavesAmount = (investedWavesAmountNew - paymentAmountMin)
314- let lpAssetFinalQuantity = (lpAssetQuantity - lpAssetAmountToBurn)
315- $Tuple6(paymentAmountMin, finalInvestedWavesAmount, donatedWavesAmountNew, newPrice, lpAssetAmountToBurn, lpAssetFinalQuantity)
316- }
317- else throw("Strict value is not equal to itself.")
318- }
319-
320-
321-func claimCollateralINTERNAL (userAddressBytes,txId) = {
322- let userAddress = Address(userAddressBytes)
323- let currentPeriodOrFail = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyCurrentPeriod()), wrapErr("invalid period"))
324- let withdrawalRequestOption = valueOrErrorMessage(getString(factoryAddressOrFail, keyWithdrawalRequest(userAddress, txId)), wrapErr("invalid withdrawal request"))
325- let $t092819394 = parseWithdrawalRequestValueOrFail(withdrawalRequestOption)
326- let status = $t092819394._1
327- let lpAssetAmount = $t092819394._2
328- let targetPeriod = $t092819394._3
329- let claimTxId = $t092819394._4
330- if ((targetPeriod > currentPeriodOrFail))
331- then throwErr("invalid withdrawal request period")
332- else {
333- let priceOrFail = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyPriceForPeriod(targetPeriod)), wrapErr("invalid price"))
334- let wavesAmount = if ((priceOrFail > 0))
335- then fraction(lpAssetAmount, priceOrFail, SCALE8)
336- else 0
337- let assetsString = getStringValue(factoryAddressOrFail, keyPeriodWithdrawalAssetIds(currentPeriodOrFail))
338- let amountsString = getStringValue(factoryAddressOrFail, keyPeriodWithdrawalAmounts(currentPeriodOrFail))
339- $Tuple6(userAddress, lpAssetAmount, targetPeriod, wavesAmount, assetsString, amountsString)
340- }
341- }
342-
343-
344-func claimCollateralREADONLYStringResponse (userAddressBytes,txId) = {
345- let $t01018110347 = claimCollateralINTERNAL(userAddressBytes, txId)
346- let userAddress = $t01018110347._1
347- let lpAssetAmount = $t01018110347._2
348- let targetPeriod = $t01018110347._3
349- let wavesAmount = $t01018110347._4
350- let assetsString = $t01018110347._5
351- let amountsString = $t01018110347._6
352- let assets = makeString(removeByIndex(split_51C(assetsString, SEP), 0), ":")
353- let amounts = makeString(removeByIndex(split_51C(amountsString, SEP), 0), ":")
354- makeString(["%d%s%s", toString(wavesAmount), assets, amounts], SEP)
355- }
269+func onlyCalculator (i) = onlyAddress(i, calculatorAddressOrFail)
356270
357271
358272 @Callable(i)
359-func claimLP (userAddressBytes) = {
360- let checkCaller = onlyFactory(i)
361- if ((checkCaller == checkCaller))
362- then {
363- let userAddress = Address(userAddressBytes)
364- let available = valueOrElse(getInteger(factoryAddressOrFail, keyAvailable(userAddress)), 0)
365- let claimed = valueOrElse(getInteger(factoryAddressOrFail, keyClaimed(userAddress)), 0)
366- let factoryActions = if ((available > 0))
367- then [invoke(factoryAddressOrFail, "transferAsset", [userAddressBytes, available, lpAssetIdOrFail], nil), invoke(factoryAddressOrFail, "integerEntry", [keyAvailable(userAddress), 0], nil), invoke(factoryAddressOrFail, "integerEntry", [keyClaimed(userAddress), (claimed + available)], nil)]
368- else throwErr("nothing to claim")
369- $Tuple2(nil, factoryActions)
370- }
371- else throw("Strict value is not equal to itself.")
372- }
273+func stringEntry (key,val) = if (onlyCalculator(i))
274+ then $Tuple2([StringEntry(key, val)], key)
275+ else $Tuple2(nil, unit)
373276
374277
375278
376279 @Callable(i)
377-func finalize (userAddressBytes,newTreasuryVolumeInWaves,pwrManagersBonusInWaves,treasuryVolumeDiffAllocationCoef) = {
378- let checkCaller = onlyFactory(i)
379- if ((checkCaller == checkCaller))
380- then {
381- let currentPeriodOrFail = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyCurrentPeriod()), wrapErr("invalid period"))
382- let periodLength = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyPeriodLength()), wrapErr("invalid period length"))
383- let currentStartHeight = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyStartHeight(currentPeriodOrFail)), wrapErr("invalid start height"))
384- let currentPriceOrFail = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyPriceForPeriod(currentPeriodOrFail)), wrapErr("invalid price"))
385- let nextBlockToProcess = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyNextBlockToProcess()), wrapErr("invalid next block to process"))
386- let periodEndHeight = ((currentStartHeight + periodLength) - 1)
387- let checks = [if ((i.originCaller == mainTreasuryAddressOrFail))
388- then true
389- else throwErr("permission denied"), if ((nextBlockToProcess > periodEndHeight))
390- then true
391- else throwErr("unprocessed blocks"), if ((newTreasuryVolumeInWaves >= 0))
392- then true
393- else throwErr("invalid new treasury volume"), if ((pwrManagersBonusInWaves >= 0))
394- then true
395- else throwErr("invalid PWR managers bonus"), if (if ((treasuryVolumeDiffAllocationCoef >= -(SCALE8)))
396- then (SCALE8 >= treasuryVolumeDiffAllocationCoef)
397- else false)
398- then true
399- else throwErr("invalid treasury volume diff allocation coefficient")]
400- if ((checks == checks))
401- then {
402- let $t01310913369 = finalizeINTERNAL(newTreasuryVolumeInWaves, pwrManagersBonusInWaves, treasuryVolumeDiffAllocationCoef)
403- let paymentAmountMin = $t01310913369._1
404- let finalInvestedWavesAmount = $t01310913369._2
405- let donatedWavesAmountNew = $t01310913369._3
406- let newPrice = $t01310913369._4
407- let lpAssetAmountToBurn = $t01310913369._5
408- let lpAssetFinalQuantity = $t01310913369._6
409- let newPeriod = (currentPeriodOrFail + 1)
410- func addNewAction (actions,payment) = {
411- let $t01351713579 = actions
412- let scriptTransfers = $t01351713579._1
413- let assetIdsString = $t01351713579._2
414- let amountsString = $t01351713579._3
415- let paymentAmount = payment.amount
416- let paymentAssetId = payment.assetId
417- let newAssetIdsString = ("%s" + makeString([assetIdsString, assetIdToString(paymentAssetId)], SEP))
418- let newAmountsString = ("%d" + makeString([amountsString, toString(paymentAmount)], SEP))
419- let newScriptTransfer = ScriptTransfer(factoryAddressOrFail, paymentAmount, paymentAssetId)
420- $Tuple3((scriptTransfers :+ newScriptTransfer), newAssetIdsString, newAmountsString)
421- }
422-
423- let $t01403914130 = {
424- let $l = i.payments
425- let $s = size($l)
426- let $acc0 = $Tuple3(nil, "", "")
427- func $f0_1 ($a,$i) = if (($i >= $s))
428- then $a
429- else addNewAction($a, $l[$i])
430-
431- func $f0_2 ($a,$i) = if (($i >= $s))
432- then $a
433- else throw("List size exceeds 10")
434-
435- $f0_2($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)
436- }
437- let scriptTransfers = $t01403914130._1
438- let AssetIds = $t01403914130._2
439- let Amounts = $t01403914130._3
440- let factoryActions = [invoke(factoryAddressOrFail, "integerEntry", [keyPowerManagerBonus(currentPeriodOrFail), pwrManagersBonusInWaves], nil), invoke(factoryAddressOrFail, "integerEntry", [keyCurrentPeriod(), newPeriod], nil), invoke(factoryAddressOrFail, "integerEntry", [keyPriceForPeriod(newPeriod), newPrice], nil), invoke(factoryAddressOrFail, "integerEntry", [keyStartHeight(newPeriod), (periodEndHeight + 1)], nil), invoke(factoryAddressOrFail, "burn", [lpAssetAmountToBurn], nil), invoke(factoryAddressOrFail, "integerEntry", [keyWithdrawal(), 0], nil), invoke(factoryAddressOrFail, "integerEntry", [keyInvested(unit), finalInvestedWavesAmount], nil), invoke(factoryAddressOrFail, "integerEntry", [keyDonated(unit), donatedWavesAmountNew], nil), invoke(factoryAddressOrFail, "stringEntry", [keyPeriodWithdrawalAssetIds(newPeriod), AssetIds], nil), invoke(factoryAddressOrFail, "stringEntry", [keyPeriodWithdrawalAmounts(newPeriod), Amounts], nil)]
441- $Tuple2(scriptTransfers, factoryActions)
442- }
443- else throw("Strict value is not equal to itself.")
444- }
445- else throw("Strict value is not equal to itself.")
446- }
280+func integerEntry (key,val) = if (onlyCalculator(i))
281+ then $Tuple2([IntegerEntry(key, val)], key)
282+ else $Tuple2(nil, unit)
447283
448284
449285
450286 @Callable(i)
451-func finalizeREADONLY (newTreasuryVolumeInWaves,pwrManagersBonusInWaves,treasuryVolumeDiffAllocationCoef) = {
452- let currentPeriodOrFail = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyCurrentPeriod()), wrapErr("invalid period"))
453- let periodLength = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyPeriodLength()), wrapErr("invalid period length"))
454- let currentStartHeight = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyStartHeight(currentPeriodOrFail)), wrapErr("invalid start height"))
455- let currentPriceOrFail = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyPriceForPeriod(currentPeriodOrFail)), wrapErr("invalid price"))
456- let nextBlockToProcess = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyNextBlockToProcess()), wrapErr("invalid next block to process"))
457- let periodEndHeight = ((currentStartHeight + periodLength) - 1)
458- let checks = [if ((nextBlockToProcess > periodEndHeight))
459- then true
460- else throwErr("unprocessed blocks"), if ((newTreasuryVolumeInWaves >= 0))
461- then true
462- else throwErr("invalid new treasury volume"), if ((pwrManagersBonusInWaves >= 0))
463- then true
464- else throwErr("invalid PWR managers bonus"), if (if ((treasuryVolumeDiffAllocationCoef >= -(SCALE8)))
465- then (SCALE8 >= treasuryVolumeDiffAllocationCoef)
466- else false)
467- then true
468- else throwErr("invalid treasury volume diff allocation coefficient")]
469- if ((checks == checks))
470- then $Tuple2(nil, finalizeINTERNAL(newTreasuryVolumeInWaves, pwrManagersBonusInWaves, treasuryVolumeDiffAllocationCoef))
471- else throw("Strict value is not equal to itself.")
472- }
287+func booleanEntry (key,val) = if (onlyCalculator(i))
288+ then $Tuple2([BooleanEntry(key, val)], key)
289+ else $Tuple2(nil, unit)
473290
474291
475292
476293 @Callable(i)
477-func invest (userAddressBytes) = {
478- let checkCaller = onlyFactory(i)
479- if ((checkCaller == checkCaller))
480- then {
481- let userAddress = Address(userAddressBytes)
482- let currentPeriodOrFail = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyCurrentPeriod()), wrapErr("invalid period"))
483- let currentStartHeight = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyStartHeight(currentPeriodOrFail)), wrapErr("invalid start height"))
484- let investPeriodLength = getIntegerValue(keyInvestPeriodLength())
485- let heightCheck = if (((currentStartHeight + investPeriodLength) > height))
486- then true
487- else throwErr("too late to invest in this period")
488- if ((heightCheck == heightCheck))
489- then {
490- let currentPriceOrFail = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyPriceForPeriod(currentPeriodOrFail)), wrapErr("invalid price"))
491- let payment = if ((size(i.payments) == 1))
492- then i.payments[0]
493- else throwErr("invalid payments")
494- let $t01796718144 = if (if ((payment.assetId == unit))
495- then (payment.amount > 0)
496- else false)
497- then $Tuple2(payment.amount, payment.assetId)
498- else throwErr("invalid payment amount")
499- let paymentAmount = $t01796718144._1
500- let paymentAssetId = $t01796718144._2
501- let treasuryPart = valueOrElse(getInteger(factoryAddressOrFail, keyBusinessTreasuryPart()), 0)
502- let paymentsWithoutTreasuryPart = fraction(paymentAmount, (SCALE8 - treasuryPart), SCALE8)
503- let lpAssetAmount = if ((currentPriceOrFail > 0))
504- then fraction(paymentsWithoutTreasuryPart, SCALE8, currentPriceOrFail)
505- else 0
506- let invested = valueOrElse(getInteger(factoryAddressOrFail, keyInvested(unit)), 0)
507- let actions = [ScriptTransfer(mainTreasuryAddressOrFail, paymentsWithoutTreasuryPart, paymentAssetId), ScriptTransfer(businessTreasuryAddressOrFail, treasuryPart, paymentAssetId)]
508- let factoryActions = [invoke(factoryAddressOrFail, "integerEntry", [keyInvested(unit), (invested + paymentsWithoutTreasuryPart)], nil), invoke(factoryAddressOrFail, "reissue", [lpAssetAmount], nil), invoke(factoryAddressOrFail, "transferAsset", [userAddressBytes, lpAssetAmount, lpAssetIdOrFail], nil)]
509- $Tuple2(actions, factoryActions)
510- }
511- else throw("Strict value is not equal to itself.")
512- }
513- else throw("Strict value is not equal to itself.")
514- }
294+func binaryEntry (key,val) = if (onlyCalculator(i))
295+ then $Tuple2([BinaryEntry(key, val)], key)
296+ else $Tuple2(nil, unit)
515297
516298
517299
518300 @Callable(i)
519-func withdraw (userAddressBytes) = {
520- let checkCaller = onlyFactory(i)
521- if ((checkCaller == checkCaller))
522- then {
523- let userAddress = Address(userAddressBytes)
524- let currentPeriodOrFail = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyCurrentPeriod()), wrapErr("invalid period"))
525- let payment = if ((size(i.payments) == 1))
526- then i.payments[0]
527- else throwErr(wrapErr("invalid payments"))
528- let paymentAssetId = if ((payment.assetId == lpAssetIdOrFail))
529- then lpAssetIdOrFail
530- else throwErr("invalid payment asset")
531- let paymentAmount = if ((payment.amount > 0))
532- then payment.amount
533- else throwErr("invalid payment amount")
534- let withdrawal = valueOrElse(getInteger(factoryAddressOrFail, keyWithdrawal()), 0)
535- let actions = [ScriptTransfer(factoryAddressOrFail, paymentAmount, paymentAssetId)]
536- let factoryActions = [invoke(factoryAddressOrFail, "integerEntry", [keyWithdrawal(), (withdrawal + paymentAmount)], nil), invoke(factoryAddressOrFail, "stringEntry", [keyWithdrawalRequest(userAddress, i.transactionId), valueWithdrawalRequest(PENDING, paymentAmount, (currentPeriodOrFail + 1), unit)], nil)]
537- if ((factoryActions == factoryActions))
538- then $Tuple2(actions, factoryActions)
539- else throw("Strict value is not equal to itself.")
540- }
541- else throw("Strict value is not equal to itself.")
542- }
301+func deleteEntry (key) = if (onlyCalculator(i))
302+ then $Tuple2([DeleteEntry(key)], key)
303+ else $Tuple2(nil, unit)
543304
544305
545306
546307 @Callable(i)
547-func cancelWithdraw (userAddressBytes,txId) = {
548- let checkCaller = onlyFactory(i)
549- if ((checkCaller == checkCaller))
550- then {
551- let userAddress = Address(userAddressBytes)
552- let withdrawalRequestOption = valueOrErrorMessage(getString(factoryAddressOrFail, keyWithdrawalRequest(userAddress, txId)), wrapErr("invalid withdrawal request"))
553- let currentPeriodOrFail = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyCurrentPeriod()), wrapErr("invalid period"))
554- let $t02087820991 = parseWithdrawalRequestValueOrFail(withdrawalRequestOption)
555- let status = $t02087820991._1
556- let lpAssetAmount = $t02087820991._2
557- let targetPeriod = $t02087820991._3
558- let claimTxId = $t02087820991._4
559- let checks = [if ((status == PENDING))
560- then true
561- else throwErr("invalid withdrawal request status"), if ((targetPeriod > currentPeriodOrFail))
562- then true
563- else throwErr("invalid withdrawal request period")]
564- if ((checks == checks))
565- then {
566- let withdrawal = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyWithdrawal()), wrapErr("invalid total withdrawal amount"))
567- let factoryActions = [invoke(factoryAddressOrFail, "integerEntry", [keyWithdrawal(), if ((withdrawal >= lpAssetAmount))
568- then (withdrawal - lpAssetAmount)
569- else throwErr("invalid withdrawal amount")], nil), invoke(factoryAddressOrFail, "deleteEntry", [keyWithdrawalRequest(userAddress, txId)], nil), invoke(factoryAddressOrFail, "transferAsset", [userAddressBytes, lpAssetAmount, lpAssetIdOrFail], nil)]
570- if ((factoryActions == factoryActions))
571- then $Tuple2(nil, factoryActions)
572- else throw("Strict value is not equal to itself.")
573- }
574- else throw("Strict value is not equal to itself.")
575- }
576- else throw("Strict value is not equal to itself.")
577- }
308+func reissue (amount) = if (onlyCalculator(i))
309+ then $Tuple2([Reissue(lpAssetIdOrFail, amount, true)], amount)
310+ else $Tuple2(nil, unit)
578311
579312
580313
581314 @Callable(i)
582-func claimCollateral (userAddressBytes,txId) = {
583- let checkCaller = onlyFactory(i)
584- if ((checkCaller == checkCaller))
585- then {
586- let $t02197722162 = claimCollateralINTERNAL(userAddressBytes, fromBase58String(txId))
587- let userAddress = $t02197722162._1
588- let lpAssetAmount = $t02197722162._2
589- let targetPeriod = $t02197722162._3
590- let wavesAmount = $t02197722162._4
591- let assetsString = $t02197722162._5
592- let amountsString = $t02197722162._6
593- let assetsList = removeByIndex(split_51C(assetsString, SEP), 0)
594- let amountsList = removeByIndex(split_51C(amountsString, SEP), 0)
595- let factoryActions = [invoke(factoryAddressOrFail, "deleteEntry", [keyWithdrawalRequest(userAddress, fromBase58String(txId))], nil), invoke(factoryAddressOrFail, "integerEntry", [keyWithdrawalHistory(userAddress, fromBase58String(txId)), lpAssetAmount], nil), invoke(factoryAddressOrFail, "transferAssets", [userAddressBytes, assetsList, amountsList], nil)]
596- $Tuple2(nil, factoryActions)
597- }
598- else throw("Strict value is not equal to itself.")
599- }
315+func burn (amount) = if (onlyCalculator(i))
316+ then $Tuple2([Burn(lpAssetIdOrFail, amount)], amount)
317+ else $Tuple2(nil, unit)
600318
601319
602320
603321 @Callable(i)
604-func claimCollateralBulk (userAddressBytes,txIds) = {
605- let checkCaller = onlyFactory(i)
606- if ((checkCaller == checkCaller))
607- then {
608- func addNewAction (state,txId) = {
609- let $t02292023119 = claimCollateralINTERNAL(userAddressBytes, fromBase58String(txId))
610- let userAddress = $t02292023119._1
611- let lpAssetAmount = $t02292023119._2
612- let targetPeriod = $t02292023119._3
613- let wavesAmount = $t02292023119._4
614- let assetsString = $t02292023119._5
615- let amountsString = $t02292023119._6
616- let assetsList = removeByIndex(split_51C(assetsString, SEP), 0)
617- let amountsList = removeByIndex(split_51C(amountsString, SEP), 0)
618- let newActions = [invoke(factoryAddressOrFail, "deleteEntry", [keyWithdrawalRequest(userAddress, fromBase58String(txId))], nil), invoke(factoryAddressOrFail, "integerEntry", [keyWithdrawalHistory(userAddress, fromBase58String(txId)), lpAssetAmount], nil), invoke(factoryAddressOrFail, "transferAssets", [userAddressBytes, assetsList, amountsList], nil)]
619- (state ++ newActions)
620- }
621-
622- let allFactoryActions = {
623- let $l = txIds
624- let $s = size($l)
625- let $acc0 = nil
626- func $f0_1 ($a,$i) = if (($i >= $s))
627- then $a
628- else addNewAction($a, $l[$i])
629-
630- func $f0_2 ($a,$i) = if (($i >= $s))
631- then $a
632- else throw("List size exceeds 10")
633-
634- $f0_2($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)
635- }
636- $Tuple2(nil, allFactoryActions)
637- }
638- else throw("Strict value is not equal to itself.")
639- }
322+func transferAsset (recepientBytes,amount,assetId) = if (onlyCalculator(i))
323+ then $Tuple2([ScriptTransfer(Address(recepientBytes), amount, assetId)], amount)
324+ else $Tuple2(nil, unit)
640325
641326
642327
643328 @Callable(i)
644-func claimCollateralREADONLY (userAddressBytes,txId) = {
645- let response = claimCollateralREADONLYStringResponse(userAddressBytes, fromBase58String(txId))
646- $Tuple2(nil, response)
647- }
329+func transferAssets (recepientBytes,assetsList,amountsList) = if (onlyCalculator(i))
330+ then {
331+ func addNewTransfer (accum,nextAssetId) = {
332+ let $t074577483 = accum
333+ let transfers = $t074577483._1
334+ let j = $t074577483._2
335+ let newTransfer = ScriptTransfer(Address(recepientBytes), parseIntValue(amountsList[j]), stringToAssetId(assetsList[j]))
336+ let updatedTransfers = (transfers :+ newTransfer)
337+ $Tuple2(updatedTransfers, (j + 1))
338+ }
339+
340+ let $t077437824 = {
341+ let $l = assetsList
342+ let $s = size($l)
343+ let $acc0 = $Tuple2(nil, 0)
344+ func $f0_1 ($a,$i) = if (($i >= $s))
345+ then $a
346+ else addNewTransfer($a, $l[$i])
347+
348+ func $f0_2 ($a,$i) = if (($i >= $s))
349+ then $a
350+ else throw("List size exceeds 10")
351+
352+ $f0_2($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)
353+ }
354+ let assetsTransfers = $t077437824._1
355+ let _lastIndex = $t077437824._2
356+ $Tuple2(assetsTransfers, unit)
357+ }
358+ else $Tuple2(nil, unit)
648359
649360
650361
651362 @Callable(i)
652-func claimCollateralBulkREADONLY (userAddressBytes,txIds) = {
653- func processTxId (state,txId) = {
654- let response = claimCollateralREADONLYStringResponse(userAddressBytes, fromBase58String(txId))
655- (state :+ response)
656- }
657-
658- let allResponses = {
659- let $l = txIds
660- let $s = size($l)
661- let $acc0 = nil
662- func $f0_1 ($a,$i) = if (($i >= $s))
663- then $a
664- else processTxId($a, $l[$i])
665-
666- func $f0_2 ($a,$i) = if (($i >= $s))
667- then $a
668- else throw("List size exceeds 10")
669-
670- $f0_2($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)
671- }
672- $Tuple2(nil, allResponses)
673- }
363+func transferWaves (recepientBytes,amount) = if (onlyCalculator(i))
364+ then $Tuple2([ScriptTransfer(Address(recepientBytes), amount, unit)], amount)
365+ else $Tuple2(nil, unit)
674366
675367
676368
677369 @Callable(i)
678-func processBlocks (userAddressBytes) = {
679- let checkCaller = onlyFactory(i)
680- if ((checkCaller == checkCaller))
681- then {
682- let userAddress = Address(userAddressBytes)
683- let currentPeriodOrFail = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyCurrentPeriod()), wrapErr("invalid period"))
684- let periodLength = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyPeriodLength()), wrapErr("invalid period length"))
685- let currentStartHeight = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyStartHeight(currentPeriodOrFail)), wrapErr("invalid start height"))
686- let currentPriceOrFail = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyPriceForPeriod(currentPeriodOrFail)), wrapErr("invalid price"))
687- let nextBlockToProcess = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyNextBlockToProcess()), wrapErr("invalid next block to process"))
688- let periodEndHeight = ((currentStartHeight + periodLength) - 1)
689- let blocksProcessingBatchSizeMax = 40
690- let blocksProcessingBatchSize = if (if (if ((height >= nextBlockToProcess))
691- then if ((nextBlockToProcess >= currentStartHeight))
692- then true
693- else (currentPeriodOrFail == 0)
694- else false)
695- then (periodEndHeight >= nextBlockToProcess)
696- else false)
697- then min([((periodEndHeight - nextBlockToProcess) + 1), blocksProcessingBatchSizeMax])
698- else throwErr(wrapErr("invalid target block"))
699- let blockProcessingReward = valueOrErrorMessage(getInteger(factoryAddressOrFail, keyBlockProcessingReward()), wrapErr("invalid block processing reward"))
700- let blockProcessingRewardByGenerator = (blockProcessingReward / blocksProcessingBatchSize)
701- let blockProcessingRewardByGeneratorRemainder = (blockProcessingReward - (blockProcessingRewardByGenerator * blocksProcessingBatchSize))
702- func map (acc,inc) = if ((inc >= blocksProcessingBatchSize))
703- then acc
704- else {
705- let targetBlockHeight = (nextBlockToProcess + inc)
706- let targetBlockInfo = valueOrErrorMessage(blockInfoByHeight(targetBlockHeight), wrapErr("invalid block info"))
707- let treasuryRewardOrFail = valueOrErrorMessage(rewardForOption(targetBlockInfo.rewards, proxyTreasuryAddressOrFail), wrapErr(("invalid treasury reward for height " + toString(targetBlockHeight))))
708- let generator = targetBlockInfo.generator
709- let available = valueOrElse(getInteger(factoryAddressOrFail, keyAvailable(generator)), 0)
710- let callerReward = if ((inc == (blocksProcessingBatchSize - 1)))
711- then (blockProcessingRewardByGenerator + blockProcessingRewardByGeneratorRemainder)
712- else blockProcessingRewardByGenerator
713- let lpAssetAmount = if ((currentPriceOrFail > 0))
714- then fraction((treasuryRewardOrFail - callerReward), SCALE8, currentPriceOrFail)
715- else 0
716- let factoryActionsSingle = [invoke(factoryAddressOrFail, "stringEntry", [keyBlockProcessed(targetBlockHeight), makeString([toBase58String(i.transactionId), toString(currentPeriodOrFail), toString(generator), toBase58String(userAddressBytes), toString(treasuryRewardOrFail), toString(callerReward), toString(lpAssetAmount)], SEP)], nil), invoke(factoryAddressOrFail, "integerEntry", [keyAvailable(generator), (available + lpAssetAmount)], nil)]
717- if ((factoryActionsSingle == factoryActionsSingle))
718- then {
719- let $t02782327856 = acc
720- let lpAssetAcc = $t02782327856._1
721- let rewardAcc = $t02782327856._2
722- $Tuple2((lpAssetAcc + lpAssetAmount), (rewardAcc + treasuryRewardOrFail))
723- }
724- else throw("Strict value is not equal to itself.")
725- }
370+func transferFromProxyTreasury (recipientBytes,rewardsAmount) = if (onlyCalculator(i))
371+ then $Tuple2(nil, invoke(proxyTreasuryAddressOrFail, "transferWaves", [recipientBytes, rewardsAmount], nil))
372+ else $Tuple2(nil, unit)
726373
727- let list = [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]
728- let $t02812328199 = {
729- let $l = list
730- let $s = size($l)
731- let $acc0 = $Tuple2(0, 0)
732- func $f0_1 ($a,$i) = if (($i >= $s))
733- then $a
734- else map($a, $l[$i])
735374
736- func $f0_2 ($a,$i) = if (($i >= $s))
737- then $a
738- else throw("List size exceeds 40")
739375
740- $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($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)
741- }
742- if (($t02812328199 == $t02812328199))
743- then {
744- let rewardAmountTotal = $t02812328199._2
745- let lpAssetAmountTotal = $t02812328199._1
746- let businessTreasuryPart = valueOrElse(getInteger(factoryAddressOrFail, keyBusinessTreasuryPart()), 0)
747- let rewardToBusinessTreasuryAmount = fraction(rewardAmountTotal, businessTreasuryPart, SCALE8)
748- let rewardToMainTreasuryAmount = ((rewardAmountTotal - rewardToBusinessTreasuryAmount) - blockProcessingReward)
749- let invested = valueOrElse(getInteger(factoryAddressOrFail, keyInvested(unit)), 0)
750- let actions = [invoke(factoryAddressOrFail, "reissue", [lpAssetAmountTotal], nil), invoke(factoryAddressOrFail, "integerEntry", [keyNextBlockToProcess(), (nextBlockToProcess + blocksProcessingBatchSize)], nil), invoke(factoryAddressOrFail, "transferFromProxyTreasury", [mainTreasuryAddressOrFail.bytes, rewardToMainTreasuryAmount], nil), invoke(factoryAddressOrFail, "transferFromProxyTreasury", [userAddressBytes, blockProcessingReward], nil), invoke(factoryAddressOrFail, "transferFromProxyTreasury", [businessTreasuryAddressOrFail.bytes, rewardToBusinessTreasuryAmount], nil), invoke(factoryAddressOrFail, "integerEntry", [keyInvested(unit), (invested + rewardToMainTreasuryAmount)], nil)]
751- if ((actions == actions))
752- then $Tuple2(nil, unit)
753- else throw("Strict value is not equal to itself.")
754- }
755- else throw("Strict value is not equal to itself.")
756- }
376+@Callable(i)
377+func finalize (newTreasuryVolumeInWaves,pwrManagersBonusInWaves,treasuryVolumeDiffAllocationCoef) = $Tuple2(nil, reentrantInvoke(calculatorAddressOrFail, "finalize", [i.caller.bytes, newTreasuryVolumeInWaves, pwrManagersBonusInWaves, treasuryVolumeDiffAllocationCoef], i.payments))
378+
379+
380+
381+@Callable(i)
382+func finalizeREADONLY (newTreasuryVolumeInWaves,pwrManagersBonusInWaves,treasuryVolumeDiffAllocationCoef) = $Tuple2(nil, reentrantInvoke(calculatorAddressOrFail, "finalizeREADONLY", [newTreasuryVolumeInWaves, pwrManagersBonusInWaves, treasuryVolumeDiffAllocationCoef], nil))
383+
384+
385+
386+@Callable(i)
387+func claimLP () = $Tuple2(nil, reentrantInvoke(calculatorAddressOrFail, "claimLP", [i.caller.bytes], i.payments))
388+
389+
390+
391+@Callable(i)
392+func claimCollateral (txIdStr) = $Tuple2(nil, reentrantInvoke(calculatorAddressOrFail, "claimCollateral", [i.caller.bytes, txIdStr], i.payments))
393+
394+
395+
396+@Callable(i)
397+func claimCollateralBulk (txIds) = $Tuple2(nil, reentrantInvoke(calculatorAddressOrFail, "claimCollateralBulk", [i.caller.bytes, txIds], i.payments))
398+
399+
400+
401+@Callable(i)
402+func invest () = $Tuple2(nil, reentrantInvoke(calculatorAddressOrFail, "invest", [i.caller.bytes], i.payments))
403+
404+
405+
406+@Callable(i)
407+func withdraw () = $Tuple2(nil, reentrantInvoke(calculatorAddressOrFail, "withdraw", [i.caller.bytes], i.payments))
408+
409+
410+
411+@Callable(i)
412+func cancelWithdraw (txIdStr) = $Tuple2(nil, reentrantInvoke(calculatorAddressOrFail, "cancelWithdraw", [i.caller.bytes, fromBase58String(txIdStr)], i.payments))
413+
414+
415+
416+@Callable(i)
417+func processBlocks () = $Tuple2(nil, reentrantInvoke(calculatorAddressOrFail, "processBlocks", [i.caller.bytes], i.payments))
418+
419+
420+
421+@Callable(i)
422+func claimCollateralREADONLY (userAddress,txIdStr) = $Tuple2(nil, reentrantInvoke(calculatorAddressOrFail, "claimCollateralREADONLY", [fromBase58String(userAddress), txIdStr], nil))
423+
424+
425+
426+@Callable(i)
427+func claimCollateralBulkREADONLY (userAddress,txIds) = $Tuple2(nil, reentrantInvoke(calculatorAddressOrFail, "claimCollateralBulkREADONLY", [fromBase58String(userAddress), txIds], nil))
428+
429+
430+
431+@Callable(i)
432+func voteForTxId (txId) = {
433+ let callerAddressString = toBase58String(i.caller.bytes)
434+ let keyPrefix = keyAllowedTxIdVotePrefix(txId)
435+ let result = [StringEntry(keyAllowedTxId(), txId)]
436+ let allowedTxIdOption = getString(this, keyAllowedTxId())
437+ let err = [if ((size(fromBase58String(txId)) == TXID_BYTES_LENGTH))
438+ then true
439+ else throwErr((txId + " is not valid txId")), if (if ((allowedTxIdOption == unit))
440+ then true
441+ else (value(allowedTxIdOption) != txId))
442+ then true
443+ else throwErr((txId + " is already allowed"))]
444+ if ((err == err))
445+ then voteINTERNAL(callerAddressString, keyPrefix, QUORUM, result)
757446 else throw("Strict value is not equal to itself.")
758447 }
759448
760449
761450 @Verifier(tx)
762451 func verify () = {
763- let publicKey = match getManagerPublicKeyOrUnit() {
764- case pub: ByteVector =>
765- pub
452+ let byProposal = match votingResultAddressOption {
453+ case proposalAddress: Address =>
454+ valueOrElse(getBoolean(proposalAddress, keyProposalAllowBroadcast(this, tx.id)), false)
766455 case _ =>
767- tx.senderPublicKey
456+ false
768457 }
769- sigVerify(tx.bodyBytes, tx.proofs[0], publicKey)
458+ let byAdmins = (tx.id == fromBase58String(valueOrElse(getString(this, keyAllowedTxId()), "")))
459+ let byOwner = if ((size(getAdminsList()) >= QUORUM))
460+ then false
461+ else sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
462+ if (if (byProposal)
463+ then true
464+ else byAdmins)
465+ then true
466+ else byOwner
770467 }
771468

github/deemru/w8io/c3f4982 
87.51 ms