tx · EH4dbp2JxJT5VsKgPbf4zqqEShchkWdjXgKqNiEAqyt1 3PJ7RB5CC3Bnn44RNR2hceZ6wKsULnMSxPi: -0.01400000 Waves 2021.03.30 23:55 [2525627] smart account 3PJ7RB5CC3Bnn44RNR2hceZ6wKsULnMSxPi > SELF 0.00000000 Waves
{ "type": 13, "id": "EH4dbp2JxJT5VsKgPbf4zqqEShchkWdjXgKqNiEAqyt1", "fee": 1400000, "feeAssetId": null, "timestamp": 1617137667482, "version": 1, "sender": "3PJ7RB5CC3Bnn44RNR2hceZ6wKsULnMSxPi", "senderPublicKey": "G5ztBKfbizrqVQWMZknsgbG2HS91eJ7QgHh7X3AznjoW", "proofs": [ "2fAUMsVwkxJdknphy6SR9WY8aakjuYgwKkoKexBLjuebuXvckQ6Ycj57znw1bVB3jwocQcdt9Z2Pd1PTsyC6cLS8", "4DTnXcdGvrCfv34AuciXu4nYFbpe6ezof1rAGYcPfkbxKyFBZhq15RVSgPFiD9HdtpnqsRR3K79ouErrn3SfWSBw" ], "script": "base64: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dHNPdXRBbW91bnQJAQAAAA5mcmFjdGlvbkhhbGZVcAAAAAMFAAAACnVzZHhBbW91bnQFAAAACXRoaXNQcmljZQUAAAAHcG93TXVsdAQAAAANcmF0c0ZlZUFtb3VudAkBAAAADmZyYWN0aW9uSGFsZlVwAAAAAwUAAAAKdXNkeEFtb3VudAUAAAAMdGhpc0ZlZVByaWNlBQAAAAdwb3dNdWx0BAAAAA11c2R4RmVlQW1vdW50CQEAAAAOZnJhY3Rpb25IYWxmVXAAAAADBQAAAAp1c2R4QW1vdW50BQAAAAx1c2R4RmVlUHJpY2UFAAAAD3VzZHhBY3R1YWxQcmljZQkABE4AAAACCQAETgAAAAIJAQAAAA5zY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgkAAGUAAAACBQAAAA1yYXRzT3V0QW1vdW50BQAAAA1yYXRzRmVlQW1vdW50BQAAAAlyYXRzQXNzZXQJAQAAAA5zY3JpcHRUcmFuc2ZlcgAAAAMFAAAABWFkbWluBQAAAA1yYXRzRmVlQW1vdW50BQAAAAlyYXRzQXNzZXQJAQAAAA5wZmVlRnVuZHNFbnRyeQAAAAEJAABkAAAAAgUAAAAJcGZlZUZ1bmRzBQAAAA11c2R4RmVlQW1vdW50AQAAAAh3aXRoZHJhdwAAAAIAAAABaQAAAApyYXRzQW1vdW50BAAAAA11c2R4T3V0QW1vdW50CQEAAAAOZnJhY3Rpb25IYWxmVXAAAAADBQAAAApyYXRzQW1vdW50BQAAAAl1c2R4UHJpY2UFAAAAB3Bvd011bHQEAAAADXVzZHhGZWVBbW91bnQJAQAAAA5mcmFjdGlvbkhhbGZVcAAAAAMFAAAACnJhdHNBbW91bnQFAAAADHVzZHhGZWVQcmljZQUAAAAHcG93TXVsdAQAAAANdXNkeFN1YkFtb3VudAUAAAAJcGZlZUZ1bmRzBAAAAA0kdDAxMDY1MzEwNzY4AwkAAGYAAAACBQAAAAl1c2RjRnVuZHMFAAAACXVzZHRGdW5kcwkABRQAAAACBQAAAAl1c2R0RnVuZHMFAAAACXVzZHRBc3NldAkABRQAAAACBQAAAAl1c2RjRnVuZHMFAAAACXVzZGNBc3NldAQAAAAJdGhpc0Z1bmRzCAUAAAANJHQwMTA2NTMxMDc2OAAAAAJfMQQAAAAJdGhpc0Fzc2V0CAUAAAANJHQwMTA2NTMxMDc2OAAAAAJfMgQAAAANJHQwMTA3NzExMDg4OAMJAABmAAAAAgUAAAAJdXNkY0Z1bmRzBQAAAAl1c2R0RnVuZHMJAAUUAAAAAgUAAAAJdXNkY0Z1bmRzBQAAAAl1c2RjQXNzZXQJAAUUAAAAAgUAAAAJdXNkdEZ1bmRzBQAAAAl1c2R0QXNzZXQEAAAACm90aGVyRnVuZHMIBQAAAA0kdDAxMDc3MTEwODg4AAAAAl8xBAAAAApvdGhlckFzc2V0CAUAAAANJHQwMTA3NzExMDg4OAAAAAJfMgQAAAAJdGhpc1ByaWNlCQAAawAAAAMFAAAACXVzZHhQcmljZQUAAAAJdGhpc0Z1bmRzBQAAAAl1c2R4RnVuZHMEAAAADHRoaXNGZWVQcmljZQkAAGsAAAADBQAAAAx1c2R4RmVlUHJpY2UFAAAACXRoaXNGdW5kcwUAAAAJdXNkeEZ1bmRzBAAAAA10aGlzT3V0QW1vdW50CQEAAAAOZnJhY3Rpb25IYWxmVXAAAAADBQAAAApyYXRzQW1vdW50BQAAAAl0aGlzUHJpY2UFAAAAB3Bvd011bHQEAAAADXRoaXNGZWVBbW91bnQJAQAAAA5mcmFjdGlvbkhhbGZVcAAAAAMFAAAACnJhdHNBbW91bnQFAAAADHRoaXNGZWVQcmljZQUAAAAHcG93TXVsdAQAAAANdGhpc1N1YkFtb3VudAkBAAAADmZyYWN0aW9uSGFsZlVwAAAAAwUAAAANdXNkeFN1YkFtb3VudAUAAAAJdGhpc0Z1bmRzBQAAAAl1c2R4RnVuZHMEAAAADm90aGVyT3V0QW1vdW50CQAAZQAAAAIFAAAADXVzZHhPdXRBbW91bnQFAAAADXRoaXNPdXRBbW91bnQEAAAADm90aGVyRmVlQW1vdW50CQAAZQAAAAIFAAAADXVzZHhGZWVBbW91bnQFAAAADXRoaXNGZWVBbW91bnQEAAAADm90aGVyU3ViQW1vdW50CQAAZQAAAAIFAAAADXVzZHhTdWJBbW91bnQFAAAADXRoaXNTdWJBbW91bnQJAAROAAAAAgkABE4AAAACCQAETgAAAAIJAAROAAAAAgkBAAAADnNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyCQAAZQAAAAIFAAAADXRoaXNPdXRBbW91bnQFAAAADXRoaXNGZWVBbW91bnQFAAAACXRoaXNBc3NldAkBAAAADnNjcmlwdFRyYW5zZmVyAAAAAwUAAAAFYWRtaW4JAABlAAAAAgUAAAANdGhpc0ZlZUFtb3VudAUAAAANdGhpc1N1YkFtb3VudAUAAAAJdGhpc0Fzc2V0CQEAAAAOc2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIJAABlAAAAAgUAAAAOb3RoZXJPdXRBbW91bnQFAAAADm90aGVyRmVlQW1vdW50BQAAAApvdGhlckFzc2V0CQEAAAAOc2NyaXB0VHJhbnNmZXIAAAADBQAAAAVhZG1pbgkAAGUAAAACBQAAAA5vdGhlckZlZUFtb3VudAUAAAAOb3RoZXJTdWJBbW91bnQFAAAACm90aGVyQXNzZXQJAQAAAA5wZmVlRnVuZHNFbnRyeQAAAAEJAQAAAA52YWx1ZU9yTWluaW11bQAAAAIJAABlAAAAAgUAAAAJcGZlZUZ1bmRzBQAAAA11c2R4RmVlQW1vdW50AAAAAAAAAAAAAQAAAAptYW5hZ2VtZW50AAAAAQAAAAFpBAAAAA1yYXRzRmVlQW1vdW50CQEAAAAOZnJhY3Rpb25IYWxmVXAAAAADBQAAAAlyYXRzRnVuZHMFAAAACG1mZWVQZXJjCQAAZQAAAAIFAAAAB3BlcmNlbnQFAAAACG1mZWVQZXJjBAAAAA11c2R4RmVlQW1vdW50CQEAAAAOZnJhY3Rpb25IYWxmVXAAAAADBQAAAAlyYXRzRnVuZHMFAAAADHVzZHhGZWVQcmljZQUAAAAHcG93TXVsdAQAAAANdXNkeFN1YkFtb3VudAUAAAAJcGZlZUZ1bmRzBAAAAA0kdDAxMjAzMTEyMTQ2AwkAAGYAAAACBQAAAAl1c2RjRnVuZHMFAAAACXVzZHRGdW5kcwkABRQAAAACBQAAAAl1c2R0RnVuZHMFAAAACXVzZHRBc3NldAkABRQAAAACBQAAAAl1c2RjRnVuZHMFAAAACXVzZGNBc3NldAQAAAAJdGhpc0Z1bmRzCAUAAAANJHQwMTIwMzExMjE0NgAAAAJfMQQAAAAJdGhpc0Fzc2V0CAUAAAANJHQwMTIwMzExMjE0NgAAAAJfMgQAAAANJHQwMTIxNDkxMjI2NgMJAABmAAAAAgUAAAAJdXNkY0Z1bmRzBQAAAAl1c2R0RnVuZHMJAAUUAAAAAgUAAAAJdXNkY0Z1bmRzBQAAAAl1c2RjQXNzZXQJAAUUAAAAAgUAAAAJdXNkdEZ1bmRzBQAAAAl1c2R0QXNzZXQEAAAACm90aGVyRnVuZHMIBQAAAA0kdDAxMjE0OTEyMjY2AAAAAl8xBAAAAApvdGhlckFzc2V0CAUAAAANJHQwMTIxNDkxMjI2NgAAAAJfMgQAAAAMdGhpc0ZlZVByaWNlCQAAawAAAAMFAAAADHVzZHhGZWVQcmljZQUAAAAJdGhpc0Z1bmRzBQAAAAl1c2R4RnVuZHMEAAAADXRoaXNGZWVBbW91bnQJAQAAAA5mcmFjdGlvbkhhbGZVcAAAAAMFAAAACXJhdHNGdW5kcwUAAAAMdGhpc0ZlZVByaWNlBQAAAAdwb3dNdWx0BAAAAA10aGlzU3ViQW1vdW50CQEAAAAOZnJhY3Rpb25IYWxmVXAAAAADBQAAAA11c2R4U3ViQW1vdW50BQAAAAl0aGlzRnVuZHMFAAAACXVzZHhGdW5kcwQAAAAOb3RoZXJGZWVBbW91bnQJAABlAAAAAgUAAAANdXNkeEZlZUFtb3VudAUAAAANdGhpc0ZlZUFtb3VudAQAAAAOb3RoZXJTdWJBbW91bnQJAABlAAAAAgUAAAANdXNkeFN1YkFtb3VudAUAAAANdGhpc1N1YkFtb3VudAkABE0AAAACCQAETgAAAAIJAAROAAAAAgkABE4AAAACCQEAAAAOc2NyaXB0VHJhbnNmZXIAAAADBQAAAAVhZG1pbgUAAAANcmF0c0ZlZUFtb3VudAUAAAAJcmF0c0Fzc2V0CQEAAAAOc2NyaXB0VHJhbnNmZXIAAAADBQAAAAVhZG1pbgkAAGUAAAACBQAAAA10aGlzRmVlQW1vdW50BQAAAA10aGlzU3ViQW1vdW50BQAAAAl0aGlzQXNzZXQJAQAAAA5zY3JpcHRUcmFuc2ZlcgAAAAMFAAAABWFkbWluCQAAZQAAAAIFAAAADm90aGVyRmVlQW1vdW50BQAAAA5vdGhlclN1YkFtb3VudAUAAAAKb3RoZXJBc3NldAkBAAAADnBmZWVGdW5kc0VudHJ5AAAAAQkBAAAADnZhbHVlT3JNaW5pbXVt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dAcJAAAAAAAAAggFAAAAAW8AAAARbWF0Y2hlckZlZUFzc2V0SWQICAUAAAABbwAAAAlhc3NldFBhaXIAAAALYW1vdW50QXNzZXQHBwYDAwkBAAAAASEAAAABCQEAAAAPY29udGFpbnNFbGVtZW50AAAAAgkABE4AAAACBQAAAAlwb3J0Zm9saW8FAAAACW91ckFzc2V0cwgFAAAAAW8AAAARbWF0Y2hlckZlZUFzc2V0SWQJAQAAAAEhAAAAAQkBAAAAD2NvbnRhaW5zRWxlbWVudAAAAAIJAAROAAAAAgUAAAAJcG9ydGZvbGlvBQAAAAlvdXJBc3NldHMICAUAAAABbwAAAAlhc3NldFBhaXIAAAAKcHJpY2VBc3NldAcJAQAAAAEhAAAAAQkBAAAAD2NvbnRhaW5zRWxlbWVudAAAAAIJAAROAAAAAgUAAAAJcG9ydGZvbGlvBQAAAAlvdXJBc3NldHMICAUAAAABbwAAAAlhc3NldFBhaXIAAAALYW1vdW50QXNzZXQHBwMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAPQnVyblRyYW5zYWN0aW9uBAAAAAFiBQAAAAckbWF0Y2gwAwUAAAAMaXNWYWxpZE93bmVyCQEAAAABIQAAAAEJAQAAAA9jb250YWluc0VsZW1lbnQAAAACCQAETgAAAAIFAAAACXBvcnRmb2xpbwUAAAAJb3VyQXNzZXRzCAUAAAABYgAAAAdhc3NldElkBwMDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAFkxlYXNlQ2FuY2VsVHJhbnNhY3Rpb24GCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAEExlYXNlVHJhbnNhY3Rpb24FAAAADGlzVmFsaWRPd25lcgMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAATVHJhbnNmZXJUcmFuc2FjdGlvbgQAAAABdAUAAAAHJG1hdGNoMAMDBQAAAAxpc1ZhbGlkT3duZXIJAQAAAAEhAAAAAQkBAAAAD2NvbnRhaW5zRWxlbWVudAAAAAIJAAROAAAAAgUAAAAJcG9ydGZvbGlvBQAAAAlvdXJBc3NldHMIBQAAAAF0AAAAB2Fzc2V0SWQHCQEAAAABIQAAAAEJAQAAAA9jb250YWluc0VsZW1lbnQAAAACCQAETgAAAAIFAAAACXBvcnRmb2xpbwUAAAAJb3VyQXNzZXRzCAUAAAABdAAAAApmZWVBc3NldElkBwMDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAFFNldFNjcmlwdFRyYW5zYWN0aW9uBgkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAA9EYXRhVHJhbnNhY3Rpb24DBQAAAAxpc1ZhbGlkQWRtaW4FAAAAEWlzVmFsaWRHdWFyYW50b3JzBwf9p4F5", "chainId": 87, "height": 2525627, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: Eu6NGjE3PJtGLPiUH6ATh7YSZagMR6p8uM4cvkYBBgbF Next: 5Ztzsi8RT6g2rMKhbG7yJEddwDA1PUFfz6MW69en2WWU Diff:
Old | New | Differences | |
---|---|---|---|
1 | 1 | {-# STDLIB_VERSION 4 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | - | let version = "1.12. | |
4 | + | let version = "1.12.8_20210330" | |
5 | 5 | ||
6 | 6 | let cent = 100 | |
7 | 7 | ||
23 | 23 | ||
24 | 24 | let minAmount = max([usdMult, valueOrElse(getInteger(this, "minamount"), (1 * usdMult))]) | |
25 | 25 | ||
26 | - | let annual = (31556952 * msec) | |
27 | - | ||
28 | 26 | let openstamp = (1609573796 * msec) | |
29 | 27 | ||
30 | 28 | let timestamp = valueOrElse(getInteger(this, "timestamp"), openstamp) | |
31 | 29 | ||
32 | - | let | |
30 | + | let minute = (60 * msec) | |
33 | 31 | ||
34 | - | let minTimeout = max([0, valueOrElse(getInteger(this, "mintimeout"), (60 * msec))]) | |
32 | + | let hour = (60 * minute) | |
33 | + | ||
34 | + | let day = (24 * hour) | |
35 | + | ||
36 | + | let month = (2629746 * msec) | |
37 | + | ||
38 | + | let year = (12 * month) | |
39 | + | ||
40 | + | let timeframe = (3 * month) | |
41 | + | ||
42 | + | let maxTimeout = day | |
43 | + | ||
44 | + | let minTimeout = max([0, valueOrElse(getInteger(this, "mintimeout"), minute)]) | |
35 | 45 | ||
36 | 46 | let admin = Address(base58'3PLRw83NCgHKKFfeJi8XWZ4fypqJJxm2x2x') | |
37 | 47 | ||
122 | 132 | else $Tuple2(payments[idx].assetId, payments[idx].amount) | |
123 | 133 | ||
124 | 134 | ||
125 | - | func toMinuteString (val) = toString((((val - 1) / (60 * msec)) + 1)) | |
126 | - | ||
127 | - | ||
128 | 135 | func toFloatBytes (val,sep,dec) = { | |
129 | 136 | func separate (b0) = { | |
130 | 137 | let b1 = dropRightBytes(b0, 3) | |
164 | 171 | else (toFloatBytes(fraction(val, (100 * cent), mult), base58'', 2) + base58'e')) | |
165 | 172 | ||
166 | 173 | ||
174 | + | func toMinuteString (val) = toString((((val - 1) / minute) + 1)) | |
175 | + | ||
176 | + | ||
177 | + | func toDateTimeString (val) = { | |
178 | + | let sp = toBytes(" ") | |
179 | + | let zd = toBytes(" UTC") | |
180 | + | let norm = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365] | |
181 | + | let leap = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366] | |
182 | + | let epoch = (((((1969 * 365) + (1969 / 4)) - (1969 / 100)) + (1969 / 400)) + 366) | |
183 | + | let ce = (val + (epoch * day)) | |
184 | + | if (((-12212553600 * msec) > val)) | |
185 | + | then throw("ISO 8601: Only years after 1583 inclusive are allowed!") | |
186 | + | else { | |
187 | + | let date = { | |
188 | + | let yyyy = ((ce / year) - 1) | |
189 | + | let days = ((ce / day) - (((((yyyy * 365) + (yyyy / 4)) - (yyyy / 100)) + (yyyy / 400)) + 366)) | |
190 | + | let months = if (if (if ((((yyyy + 1) % 4) == 0)) | |
191 | + | then (((yyyy + 1) % 100) != 0) | |
192 | + | else false) | |
193 | + | then true | |
194 | + | else (((yyyy + 1) % 400) == 0)) | |
195 | + | then leap | |
196 | + | else norm | |
197 | + | let mm = if (if ((0 > days)) | |
198 | + | then true | |
199 | + | else (days >= months[12])) | |
200 | + | then throw("Unexpected error: Value overflow for months!") | |
201 | + | else if ((days >= months[11])) | |
202 | + | then 11 | |
203 | + | else if ((days >= months[10])) | |
204 | + | then 10 | |
205 | + | else if ((days >= months[9])) | |
206 | + | then 9 | |
207 | + | else if ((days >= months[8])) | |
208 | + | then 8 | |
209 | + | else if ((days >= months[7])) | |
210 | + | then 7 | |
211 | + | else if ((days >= months[6])) | |
212 | + | then 6 | |
213 | + | else if ((days >= months[5])) | |
214 | + | then 5 | |
215 | + | else if ((days >= months[4])) | |
216 | + | then 4 | |
217 | + | else if ((days >= months[3])) | |
218 | + | then 3 | |
219 | + | else if ((days >= months[2])) | |
220 | + | then 2 | |
221 | + | else if ((days >= months[1])) | |
222 | + | then 1 | |
223 | + | else 0 | |
224 | + | let dd = (days - months[mm]) | |
225 | + | ((((drop(toBytes(toString((yyyy + 1))), 0) + base58'n') + drop(toBytes(toString((mm + 101))), 1)) + base58'n') + drop(toBytes(toString((dd + 101))), 1)) | |
226 | + | } | |
227 | + | let time = { | |
228 | + | let rd = (ce % day) | |
229 | + | let hh = (rd / hour) | |
230 | + | let rh = (rd % hour) | |
231 | + | let mm = (rh / minute) | |
232 | + | let rm = (rh % minute) | |
233 | + | let ss = (rm / msec) | |
234 | + | ((((drop(toBytes(toString((hh + 100))), 1) + base58'21') + drop(toBytes(toString((mm + 100))), 1)) + base58'21') + drop(toBytes(toString((ss + 100))), 1)) | |
235 | + | } | |
236 | + | toUtf8String((((date + sp) + time) + zd)) | |
237 | + | } | |
238 | + | } | |
239 | + | ||
240 | + | ||
167 | 241 | func pfeeFundsEntry (amount) = if ((amount == pfeeFunds)) | |
168 | 242 | then nil | |
169 | 243 | else [IntegerEntry("pfeefunds", amount)] | |
195 | 269 | let usdxOutAmount = fractionHalfUp(ratsAmount, usdxPrice, powMult) | |
196 | 270 | let usdxFeeAmount = fractionHalfUp(ratsAmount, usdxFeePrice, powMult) | |
197 | 271 | let usdxSubAmount = pfeeFunds | |
198 | - | let $ | |
272 | + | let $t01065310768 = if ((usdcFunds > usdtFunds)) | |
199 | 273 | then $Tuple2(usdtFunds, usdtAsset) | |
200 | 274 | else $Tuple2(usdcFunds, usdcAsset) | |
201 | - | let thisFunds = $ | |
202 | - | let thisAsset = $ | |
203 | - | let $ | |
275 | + | let thisFunds = $t01065310768._1 | |
276 | + | let thisAsset = $t01065310768._2 | |
277 | + | let $t01077110888 = if ((usdcFunds > usdtFunds)) | |
204 | 278 | then $Tuple2(usdcFunds, usdcAsset) | |
205 | 279 | else $Tuple2(usdtFunds, usdtAsset) | |
206 | - | let otherFunds = $ | |
207 | - | let otherAsset = $ | |
280 | + | let otherFunds = $t01077110888._1 | |
281 | + | let otherAsset = $t01077110888._2 | |
208 | 282 | let thisPrice = fraction(usdxPrice, thisFunds, usdxFunds) | |
209 | 283 | let thisFeePrice = fraction(usdxFeePrice, thisFunds, usdxFunds) | |
210 | 284 | let thisOutAmount = fractionHalfUp(ratsAmount, thisPrice, powMult) | |
221 | 295 | let ratsFeeAmount = fractionHalfUp(ratsFunds, mfeePerc, (percent - mfeePerc)) | |
222 | 296 | let usdxFeeAmount = fractionHalfUp(ratsFunds, usdxFeePrice, powMult) | |
223 | 297 | let usdxSubAmount = pfeeFunds | |
224 | - | let $ | |
298 | + | let $t01203112146 = if ((usdcFunds > usdtFunds)) | |
225 | 299 | then $Tuple2(usdtFunds, usdtAsset) | |
226 | 300 | else $Tuple2(usdcFunds, usdcAsset) | |
227 | - | let thisFunds = $ | |
228 | - | let thisAsset = $ | |
229 | - | let $ | |
301 | + | let thisFunds = $t01203112146._1 | |
302 | + | let thisAsset = $t01203112146._2 | |
303 | + | let $t01214912266 = if ((usdcFunds > usdtFunds)) | |
230 | 304 | then $Tuple2(usdcFunds, usdcAsset) | |
231 | 305 | else $Tuple2(usdtFunds, usdtAsset) | |
232 | - | let otherFunds = $ | |
233 | - | let otherAsset = $ | |
306 | + | let otherFunds = $t01214912266._1 | |
307 | + | let otherAsset = $t01214912266._2 | |
234 | 308 | let thisFeePrice = fraction(usdxFeePrice, thisFunds, usdxFunds) | |
235 | 309 | let thisFeeAmount = fractionHalfUp(ratsFunds, thisFeePrice, powMult) | |
236 | 310 | let thisSubAmount = fractionHalfUp(usdxSubAmount, thisFunds, usdxFunds) | |
243 | 317 | @Callable(i) | |
244 | 318 | func BalanceSheet () = { | |
245 | 319 | let duration = (lastBlock.timestamp - openstamp) | |
246 | - | let exponent = fraction(decMult, | |
320 | + | let exponent = fraction(decMult, year, duration) | |
247 | 321 | let grossAPY = ((pow(fraction(usdxPrice, decMult, powMult), 8, exponent, 8, decimals(percent), DOWN) + (4 * mfeePerc)) - percent) | |
248 | 322 | let netFunds = valueOrMaximum(fractionHalfUp(ratsFunds, usdxActualPrice, powMult), usdxFunds) | |
249 | 323 | if ((size(i.payments) > 0)) | |
258 | 332 | let isAdmin = if ((i.caller == this)) | |
259 | 333 | then true | |
260 | 334 | else (i.callerPublicKey == adminPublicKey) | |
261 | - | let $ | |
262 | - | let asset0 = $ | |
263 | - | let amount0 = $ | |
264 | - | let $ | |
265 | - | let asset1 = $ | |
266 | - | let amount1 = $ | |
335 | + | let $t01408014131 = getAttachment(i.payments, 0) | |
336 | + | let asset0 = $t01408014131._1 | |
337 | + | let amount0 = $t01408014131._2 | |
338 | + | let $t01413414185 = getAttachment(i.payments, 1) | |
339 | + | let asset1 = $t01413414185._1 | |
340 | + | let amount1 = $t01413414185._2 | |
267 | 341 | let maxAmount = valueOrMinimum((maxFunds - usdxFunds), (100 * usdMult)) | |
268 | 342 | let usdxAmount = ((if (containsElement(portfolio, asset0)) | |
269 | 343 | then amount0 | |
277 | 351 | else if (if (!(isAdmin)) | |
278 | 352 | then (usdxFunds > maxFunds) | |
279 | 353 | else false) | |
280 | - | then throw(makeString(["DepositFunds () =>", "The maximum limit has been reached | |
354 | + | then throw(makeString(["DepositFunds () =>", "The maximum limit has been reached! Funding has been deactivated."], " ")) | |
281 | 355 | else if (if (if (if ((minAmount > usdxAmount)) | |
282 | 356 | then true | |
283 | 357 | else (usdxAmount > maxAmount)) | |
304 | 378 | let isAdmin = if ((i.caller == this)) | |
305 | 379 | then true | |
306 | 380 | else (i.callerPublicKey == adminPublicKey) | |
307 | - | let $ | |
308 | - | let asset0 = $ | |
309 | - | let amount0 = $ | |
310 | - | let $ | |
311 | - | let asset1 = $ | |
312 | - | let amount1 = $ | |
381 | + | let $t01592115972 = getAttachment(i.payments, 0) | |
382 | + | let asset0 = $t01592115972._1 | |
383 | + | let amount0 = $t01592115972._2 | |
384 | + | let $t01597516026 = getAttachment(i.payments, 1) | |
385 | + | let asset1 = $t01597516026._1 | |
386 | + | let amount1 = $t01597516026._2 | |
313 | 387 | let maxAmount = valueOrMinimum((ratsFunds - minAmount), 0) | |
314 | 388 | let ratsAmount = ((if ((asset0 == ratsAsset)) | |
315 | 389 | then amount0 | |
346 | 420 | let isAdmin = if ((i.caller == this)) | |
347 | 421 | then true | |
348 | 422 | else (i.callerPublicKey == adminPublicKey) | |
349 | - | if (!(isAdmin)) | |
350 | - | then throw(makeString(["TakeCommission () =>", "This action can only be performed by authorized persons!"], " ")) | |
351 | - | else if ((size(i.payments) > 0)) | |
352 | - | then throw(makeString(["TakeCommission () =>", "Don't attach payment when calling this function ..."], " ")) | |
353 | - | else if ((minTimeout > etaTimer)) | |
354 | - | then throw(makeString(["TakeCommission () =>", "The balancing of dollar funds is going on ...", "Please wait less than", toMinuteString((minTimeout - etaTimer)), "min."], " ")) | |
355 | - | else ((management(i) :+ IntegerEntry("timestamp", lastBlock.timestamp)) ++ (if ((lockStatus != suspended)) | |
356 | - | then [DeleteEntry("suspended")] | |
357 | - | else nil)) | |
423 | + | let isManager = if (isAdmin) | |
424 | + | then true | |
425 | + | else containsElement(guarantors, i.callerPublicKey) | |
426 | + | let teamstamp = valueOrElse(getInteger(this, "taemstamp"), (lastBlock.timestamp - timeframe)) | |
427 | + | let nextstamp = (((((teamstamp + timeframe) / timeframe) + 1) * timeframe) - (month / 4)) | |
428 | + | if ((nextstamp > lastBlock.timestamp)) | |
429 | + | then throw(makeString(["TakeCommission () =>", "The commission has already been charged!", "Please wait until the date:", toDateTimeString(nextstamp)], " ")) | |
430 | + | else if (!(isAdmin)) | |
431 | + | then throw(makeString(["TakeCommission () =>", "This action can only be performed by authorized persons!"], " ")) | |
432 | + | else if ((size(i.payments) > 0)) | |
433 | + | then throw(makeString(["TakeCommission () =>", "Don't attach payment when calling this function ..."], " ")) | |
434 | + | else if ((minTimeout > etaTimer)) | |
435 | + | then throw(makeString(["TakeCommission () =>", "The balancing of dollar funds is going on ...", "Please wait less than", toMinuteString((minTimeout - etaTimer)), "min."], " ")) | |
436 | + | else ((management(i) :+ IntegerEntry("timestamp", lastBlock.timestamp)) ++ (if ((lockStatus != suspended)) | |
437 | + | then [DeleteEntry("suspended")] | |
438 | + | else nil)) | |
358 | 439 | } | |
359 | 440 | ||
360 | 441 |
Old | New | Differences | |
---|---|---|---|
1 | 1 | {-# STDLIB_VERSION 4 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | - | let version = "1.12. | |
4 | + | let version = "1.12.8_20210330" | |
5 | 5 | ||
6 | 6 | let cent = 100 | |
7 | 7 | ||
8 | 8 | let msec = 1000 | |
9 | 9 | ||
10 | 10 | let percent = (100 * 10000) | |
11 | 11 | ||
12 | 12 | let usdMult = 1000000 | |
13 | 13 | ||
14 | 14 | let decMult = 100000000 | |
15 | 15 | ||
16 | 16 | let powMult = (decMult * decMult) | |
17 | 17 | ||
18 | 18 | let mfeePerc = ((2 * percent) / 400) | |
19 | 19 | ||
20 | 20 | let pfeePerc = ((20 * percent) / 100) | |
21 | 21 | ||
22 | 22 | let maxFunds = max([0, valueOrElse(getInteger(this, "maxfunds"), (1000 * usdMult))]) | |
23 | 23 | ||
24 | 24 | let minAmount = max([usdMult, valueOrElse(getInteger(this, "minamount"), (1 * usdMult))]) | |
25 | 25 | ||
26 | - | let annual = (31556952 * msec) | |
27 | - | ||
28 | 26 | let openstamp = (1609573796 * msec) | |
29 | 27 | ||
30 | 28 | let timestamp = valueOrElse(getInteger(this, "timestamp"), openstamp) | |
31 | 29 | ||
32 | - | let | |
30 | + | let minute = (60 * msec) | |
33 | 31 | ||
34 | - | let minTimeout = max([0, valueOrElse(getInteger(this, "mintimeout"), (60 * msec))]) | |
32 | + | let hour = (60 * minute) | |
33 | + | ||
34 | + | let day = (24 * hour) | |
35 | + | ||
36 | + | let month = (2629746 * msec) | |
37 | + | ||
38 | + | let year = (12 * month) | |
39 | + | ||
40 | + | let timeframe = (3 * month) | |
41 | + | ||
42 | + | let maxTimeout = day | |
43 | + | ||
44 | + | let minTimeout = max([0, valueOrElse(getInteger(this, "mintimeout"), minute)]) | |
35 | 45 | ||
36 | 46 | let admin = Address(base58'3PLRw83NCgHKKFfeJi8XWZ4fypqJJxm2x2x') | |
37 | 47 | ||
38 | 48 | let adminPublicKey = base58'JDYJq5RKnSXKLYUQfL89zWPdM3QH5hW8JUTpjnTYV95k' | |
39 | 49 | ||
40 | 50 | let traderPublicKey = base58'G5ztBKfbizrqVQWMZknsgbG2HS91eJ7QgHh7X3AznjoW' | |
41 | 51 | ||
42 | 52 | let matcherPublicKey = base58'9cpfKN9suPNvfeUNphzxXMjcnn974eme8ZhWUjaktzU5' | |
43 | 53 | ||
44 | 54 | let guarantors = ([valueOrElse(getBinary(this, "guarantor1"), base58''), valueOrElse(getBinary(this, "guarantor2"), base58''), valueOrElse(getBinary(this, "guarantor3"), base58'')] :+ base58'') | |
45 | 55 | ||
46 | 56 | let actualSize = value(indexOf(guarantors, base58'')) | |
47 | 57 | ||
48 | 58 | let minSignatures = ((actualSize / 2) + (actualSize % 2)) | |
49 | 59 | ||
50 | 60 | let usdtAsset = base58'34N9YcEETLWn93qYQ64EsP1x89tSruJU44RrEMSXXEPJ' | |
51 | 61 | ||
52 | 62 | let usdcAsset = base58'6XtHjpXbs9RRJP2Sr9GUyVqzACcby9TkThHXnjVC5CDJ' | |
53 | 63 | ||
54 | 64 | let ratsAsset = base58'Z7817F7hnbWYsVHykjPtn8sUjyuLLf8NPofdveb8CMD' | |
55 | 65 | ||
56 | 66 | let portfolio = [usdtAsset, usdcAsset] | |
57 | 67 | ||
58 | 68 | let ourAssets = [ratsAsset] | |
59 | 69 | ||
60 | 70 | let usdtFunds = assetBalance(this, usdtAsset) | |
61 | 71 | ||
62 | 72 | let usdcFunds = assetBalance(this, usdcAsset) | |
63 | 73 | ||
64 | 74 | let usdxFunds = (usdtFunds + usdcFunds) | |
65 | 75 | ||
66 | 76 | let ratsTotal = value(assetInfo(ratsAsset)).quantity | |
67 | 77 | ||
68 | 78 | let ratsFunds = (ratsTotal - assetBalance(this, ratsAsset)) | |
69 | 79 | ||
70 | 80 | let pfeeFunds = valueOrElse(getInteger(this, "pfeefunds"), 0) | |
71 | 81 | ||
72 | 82 | let usdxPrice = fraction(powMult, (usdxFunds + pfeeFunds), ratsFunds) | |
73 | 83 | ||
74 | 84 | let usdxFeePrice = fraction((usdxPrice - powMult), pfeePerc, percent) | |
75 | 85 | ||
76 | 86 | let usdxActualPrice = (usdxPrice - usdxFeePrice) | |
77 | 87 | ||
78 | 88 | let etaTimer = (lastBlock.timestamp - timestamp) | |
79 | 89 | ||
80 | 90 | let suspended = valueOrElse(getBoolean(this, "suspended"), false) | |
81 | 91 | ||
82 | 92 | let lockStatus = if (suspended) | |
83 | 93 | then (maxTimeout > etaTimer) | |
84 | 94 | else false | |
85 | 95 | ||
86 | 96 | func decimals (mult) = (size(toString(mult)) - 1) | |
87 | 97 | ||
88 | 98 | ||
89 | 99 | func reciprocal (val,mult) = fraction(mult, mult, val) | |
90 | 100 | ||
91 | 101 | ||
92 | 102 | func valueOrMinimum (val,minVal) = if ((minVal > val)) | |
93 | 103 | then minVal | |
94 | 104 | else val | |
95 | 105 | ||
96 | 106 | ||
97 | 107 | func valueOrMaximum (val,maxVal) = if ((val > maxVal)) | |
98 | 108 | then maxVal | |
99 | 109 | else val | |
100 | 110 | ||
101 | 111 | ||
102 | 112 | func fractionHalfUp (val,num,den) = { | |
103 | 113 | func round (xVal) = (xVal + (if ((xVal > 0)) | |
104 | 114 | then 1 | |
105 | 115 | else 0)) | |
106 | 116 | ||
107 | 117 | (round(fraction((2 * val), num, den)) / 2) | |
108 | 118 | } | |
109 | 119 | ||
110 | 120 | ||
111 | 121 | func fractionCeiling (val,num,den) = { | |
112 | 122 | func round (xVal) = (xVal + (if (((xVal % 10) == 0)) | |
113 | 123 | then 0 | |
114 | 124 | else 10)) | |
115 | 125 | ||
116 | 126 | (round(fraction((10 * val), num, den)) / 10) | |
117 | 127 | } | |
118 | 128 | ||
119 | 129 | ||
120 | 130 | func getAttachment (payments,idx) = if ((idx >= size(payments))) | |
121 | 131 | then $Tuple2(base58'', 0) | |
122 | 132 | else $Tuple2(payments[idx].assetId, payments[idx].amount) | |
123 | 133 | ||
124 | 134 | ||
125 | - | func toMinuteString (val) = toString((((val - 1) / (60 * msec)) + 1)) | |
126 | - | ||
127 | - | ||
128 | 135 | func toFloatBytes (val,sep,dec) = { | |
129 | 136 | func separate (b0) = { | |
130 | 137 | let b1 = dropRightBytes(b0, 3) | |
131 | 138 | let b2 = dropRightBytes(b1, 3) | |
132 | 139 | let b3 = dropRightBytes(b2, 3) | |
133 | 140 | let b4 = dropRightBytes(b3, 3) | |
134 | 141 | ((((((((takeRightBytes(b4, 3) + (if ((b4 != base58'')) | |
135 | 142 | then sep | |
136 | 143 | else base58'')) + takeRightBytes(b3, 3)) + (if ((b3 != base58'')) | |
137 | 144 | then sep | |
138 | 145 | else base58'')) + takeRightBytes(b2, 3)) + (if ((b2 != base58'')) | |
139 | 146 | then sep | |
140 | 147 | else base58'')) + takeRightBytes(b1, 3)) + (if ((b1 != base58'')) | |
141 | 148 | then sep | |
142 | 149 | else base58'')) + takeRightBytes(b0, 3)) | |
143 | 150 | } | |
144 | 151 | ||
145 | 152 | let bVal = toBytes(toString(val)) | |
146 | 153 | ((separate(dropRightBytes(bVal, dec)) + base58'o') + takeRightBytes(bVal, dec)) | |
147 | 154 | } | |
148 | 155 | ||
149 | 156 | ||
150 | 157 | func toPriceString (val,mult) = toUtf8String(if ((0 > val)) | |
151 | 158 | then throw("Unexpected error: Negative values are not allowed!") | |
152 | 159 | else toFloatBytes(fractionCeiling(val, usdMult, mult), base58'm', 6)) | |
153 | 160 | ||
154 | 161 | ||
155 | 162 | func toAmountString (val,mult,isDollar) = toUtf8String(if ((0 > val)) | |
156 | 163 | then throw("Unexpected error: Negative values are not allowed!") | |
157 | 164 | else ((if (isDollar) | |
158 | 165 | then base58'd' | |
159 | 166 | else base58'') + toFloatBytes(fraction(val, cent, mult), base58'm', 2))) | |
160 | 167 | ||
161 | 168 | ||
162 | 169 | func toPercentString (val,mult) = toUtf8String(if ((0 > val)) | |
163 | 170 | then throw("Unexpected error: Negative values are not allowed!") | |
164 | 171 | else (toFloatBytes(fraction(val, (100 * cent), mult), base58'', 2) + base58'e')) | |
165 | 172 | ||
166 | 173 | ||
174 | + | func toMinuteString (val) = toString((((val - 1) / minute) + 1)) | |
175 | + | ||
176 | + | ||
177 | + | func toDateTimeString (val) = { | |
178 | + | let sp = toBytes(" ") | |
179 | + | let zd = toBytes(" UTC") | |
180 | + | let norm = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365] | |
181 | + | let leap = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366] | |
182 | + | let epoch = (((((1969 * 365) + (1969 / 4)) - (1969 / 100)) + (1969 / 400)) + 366) | |
183 | + | let ce = (val + (epoch * day)) | |
184 | + | if (((-12212553600 * msec) > val)) | |
185 | + | then throw("ISO 8601: Only years after 1583 inclusive are allowed!") | |
186 | + | else { | |
187 | + | let date = { | |
188 | + | let yyyy = ((ce / year) - 1) | |
189 | + | let days = ((ce / day) - (((((yyyy * 365) + (yyyy / 4)) - (yyyy / 100)) + (yyyy / 400)) + 366)) | |
190 | + | let months = if (if (if ((((yyyy + 1) % 4) == 0)) | |
191 | + | then (((yyyy + 1) % 100) != 0) | |
192 | + | else false) | |
193 | + | then true | |
194 | + | else (((yyyy + 1) % 400) == 0)) | |
195 | + | then leap | |
196 | + | else norm | |
197 | + | let mm = if (if ((0 > days)) | |
198 | + | then true | |
199 | + | else (days >= months[12])) | |
200 | + | then throw("Unexpected error: Value overflow for months!") | |
201 | + | else if ((days >= months[11])) | |
202 | + | then 11 | |
203 | + | else if ((days >= months[10])) | |
204 | + | then 10 | |
205 | + | else if ((days >= months[9])) | |
206 | + | then 9 | |
207 | + | else if ((days >= months[8])) | |
208 | + | then 8 | |
209 | + | else if ((days >= months[7])) | |
210 | + | then 7 | |
211 | + | else if ((days >= months[6])) | |
212 | + | then 6 | |
213 | + | else if ((days >= months[5])) | |
214 | + | then 5 | |
215 | + | else if ((days >= months[4])) | |
216 | + | then 4 | |
217 | + | else if ((days >= months[3])) | |
218 | + | then 3 | |
219 | + | else if ((days >= months[2])) | |
220 | + | then 2 | |
221 | + | else if ((days >= months[1])) | |
222 | + | then 1 | |
223 | + | else 0 | |
224 | + | let dd = (days - months[mm]) | |
225 | + | ((((drop(toBytes(toString((yyyy + 1))), 0) + base58'n') + drop(toBytes(toString((mm + 101))), 1)) + base58'n') + drop(toBytes(toString((dd + 101))), 1)) | |
226 | + | } | |
227 | + | let time = { | |
228 | + | let rd = (ce % day) | |
229 | + | let hh = (rd / hour) | |
230 | + | let rh = (rd % hour) | |
231 | + | let mm = (rh / minute) | |
232 | + | let rm = (rh % minute) | |
233 | + | let ss = (rm / msec) | |
234 | + | ((((drop(toBytes(toString((hh + 100))), 1) + base58'21') + drop(toBytes(toString((mm + 100))), 1)) + base58'21') + drop(toBytes(toString((ss + 100))), 1)) | |
235 | + | } | |
236 | + | toUtf8String((((date + sp) + time) + zd)) | |
237 | + | } | |
238 | + | } | |
239 | + | ||
240 | + | ||
167 | 241 | func pfeeFundsEntry (amount) = if ((amount == pfeeFunds)) | |
168 | 242 | then nil | |
169 | 243 | else [IntegerEntry("pfeefunds", amount)] | |
170 | 244 | ||
171 | 245 | ||
172 | 246 | func scriptTransfer (recipient,amount,assetId) = if ((1 > amount)) | |
173 | 247 | then nil | |
174 | 248 | else [ScriptTransfer(recipient, amount, assetId)] | |
175 | 249 | ||
176 | 250 | ||
177 | 251 | func airdropTransfer (recipient,assetId) = if (containsElement((portfolio ++ ourAssets), assetId)) | |
178 | 252 | then throw(makeString(["AirdropWasher () =>", "Please remove the asset ID:", toBase58String(assetId)], " ")) | |
179 | 253 | else if ((assetId == base58'')) | |
180 | 254 | then nil | |
181 | 255 | else scriptTransfer(recipient, assetBalance(this, assetId), assetId) | |
182 | 256 | ||
183 | 257 | ||
184 | 258 | func deposit (i,usdxAmount) = { | |
185 | 259 | let thisPrice = reciprocal(usdxActualPrice, powMult) | |
186 | 260 | let thisFeePrice = fraction(thisPrice, mfeePerc, percent) | |
187 | 261 | let ratsOutAmount = fractionHalfUp(usdxAmount, thisPrice, powMult) | |
188 | 262 | let ratsFeeAmount = fractionHalfUp(usdxAmount, thisFeePrice, powMult) | |
189 | 263 | let usdxFeeAmount = fractionHalfUp(usdxAmount, usdxFeePrice, usdxActualPrice) | |
190 | 264 | ((scriptTransfer(i.caller, (ratsOutAmount - ratsFeeAmount), ratsAsset) ++ scriptTransfer(admin, ratsFeeAmount, ratsAsset)) ++ pfeeFundsEntry((pfeeFunds + usdxFeeAmount))) | |
191 | 265 | } | |
192 | 266 | ||
193 | 267 | ||
194 | 268 | func withdraw (i,ratsAmount) = { | |
195 | 269 | let usdxOutAmount = fractionHalfUp(ratsAmount, usdxPrice, powMult) | |
196 | 270 | let usdxFeeAmount = fractionHalfUp(ratsAmount, usdxFeePrice, powMult) | |
197 | 271 | let usdxSubAmount = pfeeFunds | |
198 | - | let $ | |
272 | + | let $t01065310768 = if ((usdcFunds > usdtFunds)) | |
199 | 273 | then $Tuple2(usdtFunds, usdtAsset) | |
200 | 274 | else $Tuple2(usdcFunds, usdcAsset) | |
201 | - | let thisFunds = $ | |
202 | - | let thisAsset = $ | |
203 | - | let $ | |
275 | + | let thisFunds = $t01065310768._1 | |
276 | + | let thisAsset = $t01065310768._2 | |
277 | + | let $t01077110888 = if ((usdcFunds > usdtFunds)) | |
204 | 278 | then $Tuple2(usdcFunds, usdcAsset) | |
205 | 279 | else $Tuple2(usdtFunds, usdtAsset) | |
206 | - | let otherFunds = $ | |
207 | - | let otherAsset = $ | |
280 | + | let otherFunds = $t01077110888._1 | |
281 | + | let otherAsset = $t01077110888._2 | |
208 | 282 | let thisPrice = fraction(usdxPrice, thisFunds, usdxFunds) | |
209 | 283 | let thisFeePrice = fraction(usdxFeePrice, thisFunds, usdxFunds) | |
210 | 284 | let thisOutAmount = fractionHalfUp(ratsAmount, thisPrice, powMult) | |
211 | 285 | let thisFeeAmount = fractionHalfUp(ratsAmount, thisFeePrice, powMult) | |
212 | 286 | let thisSubAmount = fractionHalfUp(usdxSubAmount, thisFunds, usdxFunds) | |
213 | 287 | let otherOutAmount = (usdxOutAmount - thisOutAmount) | |
214 | 288 | let otherFeeAmount = (usdxFeeAmount - thisFeeAmount) | |
215 | 289 | let otherSubAmount = (usdxSubAmount - thisSubAmount) | |
216 | 290 | ((((scriptTransfer(i.caller, (thisOutAmount - thisFeeAmount), thisAsset) ++ scriptTransfer(admin, (thisFeeAmount - thisSubAmount), thisAsset)) ++ scriptTransfer(i.caller, (otherOutAmount - otherFeeAmount), otherAsset)) ++ scriptTransfer(admin, (otherFeeAmount - otherSubAmount), otherAsset)) ++ pfeeFundsEntry(valueOrMinimum((pfeeFunds - usdxFeeAmount), 0))) | |
217 | 291 | } | |
218 | 292 | ||
219 | 293 | ||
220 | 294 | func management (i) = { | |
221 | 295 | let ratsFeeAmount = fractionHalfUp(ratsFunds, mfeePerc, (percent - mfeePerc)) | |
222 | 296 | let usdxFeeAmount = fractionHalfUp(ratsFunds, usdxFeePrice, powMult) | |
223 | 297 | let usdxSubAmount = pfeeFunds | |
224 | - | let $ | |
298 | + | let $t01203112146 = if ((usdcFunds > usdtFunds)) | |
225 | 299 | then $Tuple2(usdtFunds, usdtAsset) | |
226 | 300 | else $Tuple2(usdcFunds, usdcAsset) | |
227 | - | let thisFunds = $ | |
228 | - | let thisAsset = $ | |
229 | - | let $ | |
301 | + | let thisFunds = $t01203112146._1 | |
302 | + | let thisAsset = $t01203112146._2 | |
303 | + | let $t01214912266 = if ((usdcFunds > usdtFunds)) | |
230 | 304 | then $Tuple2(usdcFunds, usdcAsset) | |
231 | 305 | else $Tuple2(usdtFunds, usdtAsset) | |
232 | - | let otherFunds = $ | |
233 | - | let otherAsset = $ | |
306 | + | let otherFunds = $t01214912266._1 | |
307 | + | let otherAsset = $t01214912266._2 | |
234 | 308 | let thisFeePrice = fraction(usdxFeePrice, thisFunds, usdxFunds) | |
235 | 309 | let thisFeeAmount = fractionHalfUp(ratsFunds, thisFeePrice, powMult) | |
236 | 310 | let thisSubAmount = fractionHalfUp(usdxSubAmount, thisFunds, usdxFunds) | |
237 | 311 | let otherFeeAmount = (usdxFeeAmount - thisFeeAmount) | |
238 | 312 | let otherSubAmount = (usdxSubAmount - thisSubAmount) | |
239 | 313 | ((((scriptTransfer(admin, ratsFeeAmount, ratsAsset) ++ scriptTransfer(admin, (thisFeeAmount - thisSubAmount), thisAsset)) ++ scriptTransfer(admin, (otherFeeAmount - otherSubAmount), otherAsset)) ++ pfeeFundsEntry(valueOrMinimum(usdxFeeAmount, pfeeFunds))) :+ IntegerEntry("teamstamp", lastBlock.timestamp)) | |
240 | 314 | } | |
241 | 315 | ||
242 | 316 | ||
243 | 317 | @Callable(i) | |
244 | 318 | func BalanceSheet () = { | |
245 | 319 | let duration = (lastBlock.timestamp - openstamp) | |
246 | - | let exponent = fraction(decMult, | |
320 | + | let exponent = fraction(decMult, year, duration) | |
247 | 321 | let grossAPY = ((pow(fraction(usdxPrice, decMult, powMult), 8, exponent, 8, decimals(percent), DOWN) + (4 * mfeePerc)) - percent) | |
248 | 322 | let netFunds = valueOrMaximum(fractionHalfUp(ratsFunds, usdxActualPrice, powMult), usdxFunds) | |
249 | 323 | if ((size(i.payments) > 0)) | |
250 | 324 | then throw(makeString(["BalanceSheet () =>", "Don't attach payment when calling this function ..."], " ")) | |
251 | 325 | else throw(makeString(["BalanceSheet () =>", "Gross APY:", (toPercentString(grossAPY, percent) + ";"), "Net cash balance:", toAmountString(netFunds, usdMult, true), "(USDT & USDC);", "Actual price: 1 RATS =", toPriceString(usdxActualPrice, powMult), "USDT (or USDC);", "Fees: 0.5% / quarter + 20% of pos. profit"], " ")) | |
252 | 326 | } | |
253 | 327 | ||
254 | 328 | ||
255 | 329 | ||
256 | 330 | @Callable(i) | |
257 | 331 | func DepositFunds () = { | |
258 | 332 | let isAdmin = if ((i.caller == this)) | |
259 | 333 | then true | |
260 | 334 | else (i.callerPublicKey == adminPublicKey) | |
261 | - | let $ | |
262 | - | let asset0 = $ | |
263 | - | let amount0 = $ | |
264 | - | let $ | |
265 | - | let asset1 = $ | |
266 | - | let amount1 = $ | |
335 | + | let $t01408014131 = getAttachment(i.payments, 0) | |
336 | + | let asset0 = $t01408014131._1 | |
337 | + | let amount0 = $t01408014131._2 | |
338 | + | let $t01413414185 = getAttachment(i.payments, 1) | |
339 | + | let asset1 = $t01413414185._1 | |
340 | + | let amount1 = $t01413414185._2 | |
267 | 341 | let maxAmount = valueOrMinimum((maxFunds - usdxFunds), (100 * usdMult)) | |
268 | 342 | let usdxAmount = ((if (containsElement(portfolio, asset0)) | |
269 | 343 | then amount0 | |
270 | 344 | else 0) + (if (containsElement(portfolio, asset1)) | |
271 | 345 | then amount1 | |
272 | 346 | else 0)) | |
273 | 347 | if (if (!(isAdmin)) | |
274 | 348 | then lockStatus | |
275 | 349 | else false) | |
276 | 350 | then throw(makeString(["DepositFunds () =>", "All transactions are temporarily suspended.", "Мax. ETA:", toMinuteString((maxTimeout - etaTimer)), "min."], " ")) | |
277 | 351 | else if (if (!(isAdmin)) | |
278 | 352 | then (usdxFunds > maxFunds) | |
279 | 353 | else false) | |
280 | - | then throw(makeString(["DepositFunds () =>", "The maximum limit has been reached | |
354 | + | then throw(makeString(["DepositFunds () =>", "The maximum limit has been reached! Funding has been deactivated."], " ")) | |
281 | 355 | else if (if (if (if ((minAmount > usdxAmount)) | |
282 | 356 | then true | |
283 | 357 | else (usdxAmount > maxAmount)) | |
284 | 358 | then true | |
285 | 359 | else if ((amount0 > 0)) | |
286 | 360 | then !(containsElement(portfolio, asset0)) | |
287 | 361 | else false) | |
288 | 362 | then true | |
289 | 363 | else if ((amount1 > 0)) | |
290 | 364 | then !(containsElement(portfolio, asset1)) | |
291 | 365 | else false) | |
292 | 366 | then throw(makeString(["DepositFunds () =>", "Please attach Tether (USDT) and/or USD Coin (USDC) assets.", "Total amount:", "from", toAmountString(minAmount, usdMult, true), "to", toAmountString(maxAmount, usdMult, true), "(USDT + USDC)"], " ")) | |
293 | 367 | else if ((minTimeout > etaTimer)) | |
294 | 368 | then throw(makeString(["DepositFunds () =>", "The balancing of dollar funds is going on ...", "Please wait less than", toMinuteString((minTimeout - etaTimer)), "min."], " ")) | |
295 | 369 | else ((deposit(i, usdxAmount) :+ IntegerEntry("timestamp", lastBlock.timestamp)) ++ (if ((lockStatus != suspended)) | |
296 | 370 | then [DeleteEntry("suspended")] | |
297 | 371 | else nil)) | |
298 | 372 | } | |
299 | 373 | ||
300 | 374 | ||
301 | 375 | ||
302 | 376 | @Callable(i) | |
303 | 377 | func WithdrawFunds () = { | |
304 | 378 | let isAdmin = if ((i.caller == this)) | |
305 | 379 | then true | |
306 | 380 | else (i.callerPublicKey == adminPublicKey) | |
307 | - | let $ | |
308 | - | let asset0 = $ | |
309 | - | let amount0 = $ | |
310 | - | let $ | |
311 | - | let asset1 = $ | |
312 | - | let amount1 = $ | |
381 | + | let $t01592115972 = getAttachment(i.payments, 0) | |
382 | + | let asset0 = $t01592115972._1 | |
383 | + | let amount0 = $t01592115972._2 | |
384 | + | let $t01597516026 = getAttachment(i.payments, 1) | |
385 | + | let asset1 = $t01597516026._1 | |
386 | + | let amount1 = $t01597516026._2 | |
313 | 387 | let maxAmount = valueOrMinimum((ratsFunds - minAmount), 0) | |
314 | 388 | let ratsAmount = ((if ((asset0 == ratsAsset)) | |
315 | 389 | then amount0 | |
316 | 390 | else 0) + (if ((asset1 == ratsAsset)) | |
317 | 391 | then amount1 | |
318 | 392 | else 0)) | |
319 | 393 | if (if (!(isAdmin)) | |
320 | 394 | then lockStatus | |
321 | 395 | else false) | |
322 | 396 | then throw(makeString(["WithdrawFunds () =>", "All transactions are temporarily suspended.", "Мax. ETA:", toMinuteString((maxTimeout - etaTimer)), "min."], " ")) | |
323 | 397 | else if (if (if (if ((1 > ratsAmount)) | |
324 | 398 | then true | |
325 | 399 | else (ratsAmount > maxAmount)) | |
326 | 400 | then true | |
327 | 401 | else if ((amount0 > 0)) | |
328 | 402 | then (asset0 != ratsAsset) | |
329 | 403 | else false) | |
330 | 404 | then true | |
331 | 405 | else if ((amount1 > 0)) | |
332 | 406 | then (asset1 != ratsAsset) | |
333 | 407 | else false) | |
334 | 408 | then throw(makeString(["WithdrawFunds () =>", "Please attach Ratatouille (RATS) asset.", "Max. amount:", toAmountString(maxAmount, usdMult, false), "RATS"], " ")) | |
335 | 409 | else if ((minTimeout > etaTimer)) | |
336 | 410 | then throw(makeString(["DepositFunds () =>", "The balancing of dollar funds is going on ...", "Please wait less than", toMinuteString((minTimeout - etaTimer)), "min."], " ")) | |
337 | 411 | else ((withdraw(i, ratsAmount) :+ IntegerEntry("timestamp", lastBlock.timestamp)) ++ (if ((lockStatus != suspended)) | |
338 | 412 | then [DeleteEntry("suspended")] | |
339 | 413 | else nil)) | |
340 | 414 | } | |
341 | 415 | ||
342 | 416 | ||
343 | 417 | ||
344 | 418 | @Callable(i) | |
345 | 419 | func TakeCommission () = { | |
346 | 420 | let isAdmin = if ((i.caller == this)) | |
347 | 421 | then true | |
348 | 422 | else (i.callerPublicKey == adminPublicKey) | |
349 | - | if (!(isAdmin)) | |
350 | - | then throw(makeString(["TakeCommission () =>", "This action can only be performed by authorized persons!"], " ")) | |
351 | - | else if ((size(i.payments) > 0)) | |
352 | - | then throw(makeString(["TakeCommission () =>", "Don't attach payment when calling this function ..."], " ")) | |
353 | - | else if ((minTimeout > etaTimer)) | |
354 | - | then throw(makeString(["TakeCommission () =>", "The balancing of dollar funds is going on ...", "Please wait less than", toMinuteString((minTimeout - etaTimer)), "min."], " ")) | |
355 | - | else ((management(i) :+ IntegerEntry("timestamp", lastBlock.timestamp)) ++ (if ((lockStatus != suspended)) | |
356 | - | then [DeleteEntry("suspended")] | |
357 | - | else nil)) | |
423 | + | let isManager = if (isAdmin) | |
424 | + | then true | |
425 | + | else containsElement(guarantors, i.callerPublicKey) | |
426 | + | let teamstamp = valueOrElse(getInteger(this, "taemstamp"), (lastBlock.timestamp - timeframe)) | |
427 | + | let nextstamp = (((((teamstamp + timeframe) / timeframe) + 1) * timeframe) - (month / 4)) | |
428 | + | if ((nextstamp > lastBlock.timestamp)) | |
429 | + | then throw(makeString(["TakeCommission () =>", "The commission has already been charged!", "Please wait until the date:", toDateTimeString(nextstamp)], " ")) | |
430 | + | else if (!(isAdmin)) | |
431 | + | then throw(makeString(["TakeCommission () =>", "This action can only be performed by authorized persons!"], " ")) | |
432 | + | else if ((size(i.payments) > 0)) | |
433 | + | then throw(makeString(["TakeCommission () =>", "Don't attach payment when calling this function ..."], " ")) | |
434 | + | else if ((minTimeout > etaTimer)) | |
435 | + | then throw(makeString(["TakeCommission () =>", "The balancing of dollar funds is going on ...", "Please wait less than", toMinuteString((minTimeout - etaTimer)), "min."], " ")) | |
436 | + | else ((management(i) :+ IntegerEntry("timestamp", lastBlock.timestamp)) ++ (if ((lockStatus != suspended)) | |
437 | + | then [DeleteEntry("suspended")] | |
438 | + | else nil)) | |
358 | 439 | } | |
359 | 440 | ||
360 | 441 | ||
361 | 442 | ||
362 | 443 | @Callable(i) | |
363 | 444 | func AirdropWasher (id0,id1,id2,id3,id4,id5,id6,id7,id8,id9) = { | |
364 | 445 | let isAdmin = if ((i.caller == this)) | |
365 | 446 | then true | |
366 | 447 | else (i.callerPublicKey == adminPublicKey) | |
367 | 448 | let isManager = if (isAdmin) | |
368 | 449 | then true | |
369 | 450 | else containsElement(guarantors, i.callerPublicKey) | |
370 | 451 | let idBytes = (((((((((id0 + id1) + id2) + id3) + id4) + id5) + id6) + id7) + id8) + id9) | |
371 | 452 | let recipient = Address(valueOrElse(getBinary(this, "washbin"), admin.bytes)) | |
372 | 453 | if (!(isManager)) | |
373 | 454 | then throw(makeString(["AirdropWasher () =>", "This action can only be performed by authorized persons!"], " ")) | |
374 | 455 | else if ((size(i.payments) > 0)) | |
375 | 456 | then throw(makeString(["AirdropWasher () =>", "Don't attach payment when calling this function ..."], " ")) | |
376 | 457 | else if ((idBytes == base58'')) | |
377 | 458 | then throw(makeString(["AirdropWasher () =>", "Please enter asset IDs in the fields below ..."], " ")) | |
378 | 459 | else (((((((((airdropTransfer(recipient, id0) ++ airdropTransfer(recipient, id1)) ++ airdropTransfer(recipient, id2)) ++ airdropTransfer(recipient, id3)) ++ airdropTransfer(recipient, id4)) ++ airdropTransfer(recipient, id5)) ++ airdropTransfer(recipient, id6)) ++ airdropTransfer(recipient, id7)) ++ airdropTransfer(recipient, id8)) ++ airdropTransfer(recipient, id9)) | |
379 | 460 | } | |
380 | 461 | ||
381 | 462 | ||
382 | 463 | ||
383 | 464 | @Callable(i) | |
384 | 465 | func EmergencyMode (status) = { | |
385 | 466 | let isAdmin = if ((i.caller == this)) | |
386 | 467 | then true | |
387 | 468 | else (i.callerPublicKey == adminPublicKey) | |
388 | 469 | let isManager = if (isAdmin) | |
389 | 470 | then true | |
390 | 471 | else containsElement(guarantors, i.callerPublicKey) | |
391 | 472 | if (if (if (!(isAdmin)) | |
392 | 473 | then !(status) | |
393 | 474 | else false) | |
394 | 475 | then true | |
395 | 476 | else !(isManager)) | |
396 | 477 | then throw(makeString(["EmergencyMode () =>", "This action can only be performed by authorized persons!"], " ")) | |
397 | 478 | else if ((size(i.payments) > 0)) | |
398 | 479 | then throw(makeString(["EmergencyMode () =>", "Don't attach payment when calling this function ..."], " ")) | |
399 | 480 | else if ((status == suspended)) | |
400 | 481 | then throw(makeString(["EmergencyMode () =>", "The status is already activated / deactivated.", "Current value:", toString(suspended)], " ")) | |
401 | 482 | else ((nil :+ BooleanEntry("suspended", status)) :+ IntegerEntry("timestamp", lastBlock.timestamp)) | |
402 | 483 | } | |
403 | 484 | ||
404 | 485 | ||
405 | 486 | @Verifier(tx) | |
406 | 487 | func verify () = { | |
407 | 488 | let isValidOwner = sigVerify_32Kb(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey) | |
408 | 489 | let isValidAdmin = if (isValidOwner) | |
409 | 490 | then true | |
410 | 491 | else sigVerify_32Kb(tx.bodyBytes, tx.proofs[0], adminPublicKey) | |
411 | 492 | let isTradingBot = if (isValidOwner) | |
412 | 493 | then true | |
413 | 494 | else sigVerify_32Kb(tx.bodyBytes, tx.proofs[0], traderPublicKey) | |
414 | 495 | let isValidGuarantors = ((((if (sigVerify_32Kb(tx.bodyBytes, tx.proofs[1], guarantors[0])) | |
415 | 496 | then 1 | |
416 | 497 | else 0) + (if (sigVerify_32Kb(tx.bodyBytes, tx.proofs[2], guarantors[1])) | |
417 | 498 | then 1 | |
418 | 499 | else 0)) + (if (sigVerify_32Kb(tx.bodyBytes, tx.proofs[3], guarantors[2])) | |
419 | 500 | then 1 | |
420 | 501 | else 0)) >= minSignatures) | |
421 | 502 | match tx { | |
422 | 503 | case o: Order => | |
423 | 504 | if (if (isTradingBot) | |
424 | 505 | then (o.matcherPublicKey == matcherPublicKey) | |
425 | 506 | else false) | |
426 | 507 | then if (if (if (containsElement(portfolio, o.assetPair.priceAsset)) | |
427 | 508 | then containsElement(portfolio, o.assetPair.amountAsset) | |
428 | 509 | else false) | |
429 | 510 | then if (if (if (!(isValidOwner)) | |
430 | 511 | then (maxTimeout >= (o.expiration - o.timestamp)) | |
431 | 512 | else false) | |
432 | 513 | then true | |
433 | 514 | else if (if ((o.orderType == Buy)) | |
434 | 515 | then ((o.expiration - o.timestamp) >= maxTimeout) | |
435 | 516 | else false) | |
436 | 517 | then (o.matcherFeeAssetId == o.assetPair.priceAsset) | |
437 | 518 | else false) | |
438 | 519 | then true | |
439 | 520 | else if (if ((o.orderType == Sell)) | |
440 | 521 | then ((o.expiration - o.timestamp) >= maxTimeout) | |
441 | 522 | else false) | |
442 | 523 | then (o.matcherFeeAssetId == o.assetPair.amountAsset) | |
443 | 524 | else false | |
444 | 525 | else false) | |
445 | 526 | then true | |
446 | 527 | else if (if (!(containsElement((portfolio ++ ourAssets), o.matcherFeeAssetId))) | |
447 | 528 | then !(containsElement((portfolio ++ ourAssets), o.assetPair.priceAsset)) | |
448 | 529 | else false) | |
449 | 530 | then !(containsElement((portfolio ++ ourAssets), o.assetPair.amountAsset)) | |
450 | 531 | else false | |
451 | 532 | else false | |
452 | 533 | case b: BurnTransaction => | |
453 | 534 | if (isValidOwner) | |
454 | 535 | then !(containsElement((portfolio ++ ourAssets), b.assetId)) | |
455 | 536 | else false | |
456 | 537 | case _: LeaseCancelTransaction|LeaseTransaction => | |
457 | 538 | isValidOwner | |
458 | 539 | case t: TransferTransaction => | |
459 | 540 | if (if (isValidOwner) | |
460 | 541 | then !(containsElement((portfolio ++ ourAssets), t.assetId)) | |
461 | 542 | else false) | |
462 | 543 | then !(containsElement((portfolio ++ ourAssets), t.feeAssetId)) | |
463 | 544 | else false | |
464 | 545 | case _: SetScriptTransaction|DataTransaction => | |
465 | 546 | if (isValidAdmin) | |
466 | 547 | then isValidGuarantors | |
467 | 548 | else false | |
468 | 549 | case _ => | |
469 | 550 | false | |
470 | 551 | } | |
471 | 552 | } | |
472 | 553 |
github/deemru/w8io/0e76f2f 91.58 ms ◑