tx · 8RSjeKLLywXTe515bVrvu7X5mQCHpByKueayvP9bFxhf 3MyDtNTkCNyRCw3o2qv5BPPS7vvUosiQe6F: -0.01400000 Waves 2020.03.26 19:54 [926659] smart account 3MyDtNTkCNyRCw3o2qv5BPPS7vvUosiQe6F > SELF 0.00000000 Waves
{ "type": 13, "id": "8RSjeKLLywXTe515bVrvu7X5mQCHpByKueayvP9bFxhf", "fee": 1400000, "feeAssetId": null, "timestamp": 1585241677584, "version": 1, "sender": "3MyDtNTkCNyRCw3o2qv5BPPS7vvUosiQe6F", "senderPublicKey": "3z5txV1G5GKezwMRCHZDkLThqb1Yggepxvi2wq6iP6oz", "proofs": [ "5rase6wwjYuWjyQ8KnGdjbtaF7fuMoh9kLuBSbKVUttCfoR5MvcEoEmSYYeKRCnNH8MZLGoT3KZYEskMVqiEdBCP" ], "script": "base64:AAIDAAAAAAAAABQIARIDCgEIEgUKAwgIARIECgIIAQAAABkBAAAADmdldE51bWJlckJ5S2V5AAAAAQAAAANrZXkEAAAAByRtYXRjaDAJAAQaAAAAAgUAAAAEdGhpcwUAAAADa2V5AwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAANJbnQEAAAAAWEFAAAAByRtYXRjaDAFAAAAAWEAAAAAAAAAAAABAAAADmdldFN0cmluZ0J5S2V5AAAAAQAAAANrZXkEAAAAByRtYXRjaDAJAAQdAAAAAgUAAAAEdGhpcwUAAAADa2V5AwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAAZTdHJpbmcEAAAAAWEFAAAAByRtYXRjaDAFAAAAAWECAAAAAAAAAAAETk9ORQAAAAAAAAAAAAAAAAADTkVXAAAAAAAAAAABAAAAAAhSRUpFQ1RFRAAAAAAAAAAAAgAAAAAHU1VDQ0VTUwAAAAAAAAAAAwAAAAAETE9DSwAAAAAAAAAAAAAAAAAGVU5MT0NLAAAAAAAAAAABAAAAAApBc3NldElkS2V5AgAAAAhhc3NldF9pZAAAAAAJQWRtaW5zS2V5AgAAAAZhZG1pbnMAAAAAEUJmdENvZWZmaWNpZW50S2V5AgAAAA5iZnRDb2VmZmljaWVudAEAAAAOZ2V0UnFTdGF0dXNLZXkAAAABAAAACXJlcXVlc3RJZAkAASwAAAACAgAAAAdzdGF0dXNfBQAAAAlyZXF1ZXN0SWQBAAAADmdldFJxSGVpZ2h0S2V5AAAAAQAAAAlyZXF1ZXN0SWQJAAEsAAAAAgIAAAAHaGVpZ2h0XwUAAAAJcmVxdWVzdElkAQAAAAxnZXRScVR5cGVLZXkAAAABAAAACXJlcXVlc3RJZAkAASwAAAACAgAAAAV0eXBlXwUAAAAJcmVxdWVzdElkAQAAAA1nZXRScU93bmVyS2V5AAAAAQAAAAlyZXF1ZXN0SWQJAAEsAAAAAgIAAAAGb3duZXJfBQAAAAlyZXF1ZXN0SWQBAAAADmdldFJxVGFyZ2V0S2V5AAAAAQAAAAlyZXF1ZXN0SWQJAAEsAAAAAgIAAAAHdGFyZ2V0XwUAAAAJcmVxdWVzdElkAQAAAA5nZXRScUFtb3VudEtleQAAAAEAAAAJcmVxdWVzdElkCQABLAAAAAICAAAAB2Ftb3VudF8FAAAACXJlcXVlc3RJZAAAAAAGYWRtaW5zCQAEtQAAAAIJAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEFAAAACUFkbWluc0tleQIAAAABLAAAAAAHYXNzZXRJZAkAAlkAAAABCQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABBQAAAApBc3NldElkS2V5AAAAAA5iZnRDb2VmZmljaWVudAkBAAAADmdldE51bWJlckJ5S2V5AAAAAQUAAAARQmZ0Q29lZmZpY2llbnRLZXkBAAAAC2dldFJxU3RhdHVzAAAAAQAAAAlyZXF1ZXN0SWQJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAAA5nZXRScVN0YXR1c0tleQAAAAEFAAAACXJlcXVlc3RJZAEAAAAJZ2V0UnFUeXBlAAAAAQAAAAlyZXF1ZXN0SWQJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAAAxnZXRScVR5cGVLZXkAAAABBQAAAAlyZXF1ZXN0SWQBAAAACmdldFJxT3duZXIAAAABAAAACXJlcXVlc3RJZAkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQkBAAAADWdldFJxT3duZXJLZXkAAAABBQAAAAlyZXF1ZXN0SWQBAAAAC2dldFJxVGFyZ2V0AAAAAQAAAAlyZXF1ZXN0SWQJAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEJAQAAAA5nZXRScVRhcmdldEtleQAAAAEFAAAACXJlcXVlc3RJZAEAAAALZ2V0UnFBbW91bnQAAAABAAAACXJlcXVlc3RJZAkBAAAADmdldE51bWJlckJ5S2V5AAAAAQkBAAAADmdldFJxQW1vdW50S2V5AAAAAQUAAAAJcmVxdWVzdElkAAAAAwAAAAFpAQAAABFjcmVhdGVMb2NrUmVxdWVzdAAAAAEAAAAJcmVjaXBpZW50BAAAAANwbXQJAQAAAAdleHRyYWN0AAAAAQgFAAAAAWkAAAAHcGF5bWVudAQAAAAJcmVxdWVzdElkCQACWAAAAAEJAAH1AAAAAQkAAMsAAAACCQAAywAAAAIJAADLAAAAAgkAAlkAAAABCQAEJQAAAAEFAAAABHRoaXMICAUAAAABaQAAAAZjYWxsZXIAAAAFYnl0ZXMIBQAAAAFpAAAADXRyYW5zYWN0aW9uSWQJAAGbAAAAAQUAAAAJcmVjaXBpZW50AwkBAAAAAiE9AAAAAggFAAAAA3BtdAAAAAdhc3NldElkBQAAAAdhc3NldElkCQAAAgAAAAECAAAAEmNhbiB1c2Ugd2F2ZXMgb25seQMJAQAAAAIhPQAAAAIJAQAAAApnZXRScU93bmVyAAAAAQUAAAAJcmVxdWVzdElkAgAAAAAJAAACAAAAAQIAAAAOcmVxdWVzdCBleGlzdHMJAQAAAAhXcml0ZVNldAAAAAEJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIJAQAAAA5nZXRScVN0YXR1c0tleQAAAAEFAAAACXJlcXVlc3RJZAUAAAADTkVXCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAAMZ2V0UnFUeXBlS2V5AAAAAQUAAAAJcmVxdWVzdElkBQAAAARMT0NLCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAANZ2V0UnFPd25lcktleQAAAAEFAAAACXJlcXVlc3RJZAkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIJAQAAAA5nZXRScUhlaWdodEtleQAAAAEFAAAACXJlcXVlc3RJZAUAAAAGaGVpZ2h0CQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAAOZ2V0UnFUYXJnZXRLZXkAAAABBQAAAAlyZXF1ZXN0SWQFAAAACXJlY2lwaWVudAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgkBAAAADmdldFJxQW1vdW50S2V5AAAAAQUAAAAJcmVxdWVzdElkCAUAAAADcG10AAAABmFtb3VudAUAAAADbmlsAAAAAWkBAAAADGNoYW5nZVN0YXR1cwAAAAMAAAALcmVxdWVzdEhhc2gAAAALc2lnbnNTdHJpbmcAAAAGc3RhdHVzBAAAAAVzaWducwkABLUAAAACBQAAAAtzaWduc1N0cmluZwIAAAABLAQAAAADbXNnCQABLAAAAAIJAAEsAAAAAgUAAAALcmVxdWVzdEhhc2gCAAAAAV8JAAGkAAAAAQUAAAAGc3RhdHVzBAAAAAVjb3VudAkAAGQAAAACCQAAZAAAAAIJAABkAAAAAgkAAGQAAAACAwkAAfQAAAADCQABmwAAAAEFAAAAA21zZwkAAlkAAAABCQABkQAAAAIFAAAABXNpZ25zAAAAAAAAAAAACQACWQAAAAEJAAGRAAAAAgUAAAAGYWRtaW5zAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAwkAAfQAAAADCQABmwAAAAEFAAAAA21zZwkAAlkAAAABCQABkQAAAAIFAAAABXNpZ25zAAAAAAAAAAABCQACWQAAAAEJAAGRAAAAAgUAAAAGYWRtaW5zAAAAAAAAAAABAAAAAAAAAAABAAAAAAAAAAAAAwkAAfQAAAADCQABmwAAAAEFAAAAA21zZwkAAlkAAAABCQABkQAAAAIFAAAABXNpZ25zAAAAAAAAAAACCQACWQAAAAEJAAGRAAAAAgUAAAAGYWRtaW5zAAAAAAAAAAACAAAAAAAAAAABAAAAAAAAAAAAAwkAAfQAAAADCQABmwAAAAEFAAAAA21zZwkAAlkAAAABCQABkQAAAAIFAAAABXNpZ25zAAAAAAAAAAADCQACWQAAAAEJAAGRAAAAAgUAAAAGYWRtaW5zAAAAAAAAAAADAAAAAAAAAAABAAAAAAAAAAAAAwkAAfQAAAADCQABmwAAAAEFAAAAA21zZwkAAlkAAAABCQABkQAAAAIFAAAABXNpZ25zAAAAAAAAAAAECQACWQAAAAEJAAGRAAAAAgUAAAAGYWRtaW5zAAAAAAAAAAAEAAAAAAAAAAABAAAAAAAAAAAAAwkAAGYAAAACBQAAAA5iZnRDb2VmZmljaWVudAUAAAAFY291bnQJAAACAAAAAQIAAAAPY291bnQgaXMgbGVzcyAzAwkAAAAAAAACCQEAAAAKZ2V0UnFPd25lcgAAAAEFAAAAC3JlcXVlc3RIYXNoAgAAAAAJAAACAAAAAQIAAAAVcmVxdWVzdCBpcyBub3QgZXhpc3RzAwkBAAAAAiE9AAAAAgkBAAAAC2dldFJxU3RhdHVzAAAAAQUAAAALcmVxdWVzdEhhc2gFAAAAA05FVwkAAAIAAAABAgAAABVyZXF1ZXN0IGlzIG5vdCBleGlzdHMDAwkBAAAAAiE9AAAAAgUAAAAGc3RhdHVzBQAAAAdTVUNDRVNTCQEAAAACIT0AAAACBQAAAAZzdGF0dXMFAAAACFJFSkVDVEVEBwkAAAIAAAABAgAAAA5pbnZhbGlkIHN0YXR1cwQAAAAFb3duZXIJAQAAABxAZXh0clVzZXIoYWRkcmVzc0Zyb21TdHJpbmcpAAAAAQkBAAAACmdldFJxT3duZXIAAAABBQAAAAtyZXF1ZXN0SGFzaAQAAAAEdHlwZQkBAAAACWdldFJxVHlwZQAAAAEFAAAAC3JlcXVlc3RIYXNoBAAAAAZhbW91bnQJAQAAAAtnZXRScUFtb3VudAAAAAEFAAAAC3JlcXVlc3RIYXNoCQEAAAAMU2NyaXB0UmVzdWx0AAAAAgkBAAAACFdyaXRlU2V0AAAAAQkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgkBAAAADmdldFJxU3RhdHVzS2V5AAAAAQUAAAALcmVxdWVzdEhhc2gFAAAABnN0YXR1cwUAAAADbmlsCQEAAAALVHJhbnNmZXJTZXQAAAABCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMFAAAABW93bmVyAwMDCQAAAAAAAAIFAAAABnN0YXR1cwUAAAAIUkVKRUNURUQJAAAAAAAAAgUAAAAEdHlwZQUAAAAETE9DSwcGAwkAAAAAAAACBQAAAAZzdGF0dXMFAAAAB1NVQ0NFU1MJAAAAAAAAAgUAAAAEdHlwZQUAAAAGVU5MT0NLBwUAAAAGYW1vdW50AAAAAAAAAAAABQAAAAdhc3NldElkBQAAAANuaWwAAAABaQEAAAATY3JlYXRlVW5sb2NrUmVxdWVzdAAAAAIAAAAGc2VuZGVyAAAABmFtb3VudAQAAAAJcmVxdWVzdElkCQACWAAAAAEJAAH1AAAAAQkAAMsAAAACCQAAywAAAAIJAADLAAAAAgkAAMsAAAACCQACWQAAAAEJAAQlAAAAAQUAAAAEdGhpcwgIBQAAAAFpAAAABmNhbGxlcgAAAAVieXRlcwgFAAAAAWkAAAANdHJhbnNhY3Rpb25JZAkAAZsAAAABBQAAAAZzZW5kZXIJAAGaAAAAAQUAAAAGYW1vdW50AwkBAAAAAiE9AAAAAgkBAAAACmdldFJxT3duZXIAAAABBQAAAAlyZXF1ZXN0SWQCAAAAAAkAAAIAAAABAgAAAA5yZXF1ZXN0IGV4aXN0cwkBAAAACFdyaXRlU2V0AAAAAQkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgkBAAAADmdldFJxU3RhdHVzS2V5AAAAAQUAAAAJcmVxdWVzdElkBQAAAANORVcJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIJAQAAAAxnZXRScVR5cGVLZXkAAAABBQAAAAlyZXF1ZXN0SWQFAAAABlVOTE9DSwkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgkBAAAADWdldFJxT3duZXJLZXkAAAABBQAAAAlyZXF1ZXN0SWQJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAAOZ2V0UnFIZWlnaHRLZXkAAAABBQAAAAlyZXF1ZXN0SWQFAAAABmhlaWdodAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgkBAAAADmdldFJxVGFyZ2V0S2V5AAAAAQUAAAAJcmVxdWVzdElkBQAAAAZzZW5kZXIJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIJAQAAAA5nZXRScUFtb3VudEtleQAAAAEFAAAACXJlcXVlc3RJZAUAAAAGYW1vdW50BQAAAANuaWwAAAAA5sIrZA==", "chainId": 84, "height": 926659, "spentComplexity": 0 } View: original | compacted Prev: HHamjXGthfXmbd4g9usosegLtaR1rCDXzTmzTkj3GvK4 Next: none Diff:
Old | New | Differences | |
---|---|---|---|
17 | 17 | } | |
18 | 18 | ||
19 | 19 | ||
20 | - | func getBoolByKey (key) = match getBoolean(this, key) { | |
21 | - | case a: Boolean => | |
22 | - | a | |
23 | - | case _ => | |
24 | - | false | |
25 | - | } | |
20 | + | let NONE = 0 | |
21 | + | ||
22 | + | let NEW = 1 | |
23 | + | ||
24 | + | let REJECTED = 2 | |
25 | + | ||
26 | + | let SUCCESS = 3 | |
27 | + | ||
28 | + | let LOCK = 0 | |
29 | + | ||
30 | + | let UNLOCK = 1 | |
31 | + | ||
32 | + | let AssetIdKey = "asset_id" | |
33 | + | ||
34 | + | let AdminsKey = "admins" | |
35 | + | ||
36 | + | let BftCoefficientKey = "bftCoefficient" | |
37 | + | ||
38 | + | func getRqStatusKey (requestId) = ("status_" + requestId) | |
26 | 39 | ||
27 | 40 | ||
28 | - | func getNumberByAddressAndKey (address,key) = match getInteger(addressFromStringValue(address), key) { | |
29 | - | case a: Int => | |
30 | - | a | |
31 | - | case _ => | |
32 | - | 0 | |
33 | - | } | |
41 | + | func getRqHeightKey (requestId) = ("height_" + requestId) | |
34 | 42 | ||
35 | 43 | ||
36 | - | func getStringByAddressAndKey (address,key) = match getString(addressFromStringValue(address), key) { | |
37 | - | case a: String => | |
38 | - | a | |
39 | - | case _ => | |
40 | - | "" | |
41 | - | } | |
44 | + | func getRqTypeKey (requestId) = ("type_" + requestId) | |
42 | 45 | ||
43 | 46 | ||
44 | - | func getBoolByAddressAndKey (address,key) = match getBoolean(addressFromStringValue(address), key) { | |
45 | - | case a: Boolean => | |
46 | - | a | |
47 | - | case _ => | |
48 | - | false | |
49 | - | } | |
47 | + | func getRqOwnerKey (requestId) = ("owner_" + requestId) | |
50 | 48 | ||
51 | 49 | ||
52 | - | let SENDTXEXPIRE = 30 | |
53 | - | ||
54 | - | let LISTSPLITSYMBOL = "_" | |
55 | - | ||
56 | - | let LISTDATASYMBOL = "+" | |
57 | - | ||
58 | - | let WAVELET = 100000000 | |
59 | - | ||
60 | - | let PAULI = 100 | |
61 | - | ||
62 | - | let CRYTICALSHARE = 20 | |
63 | - | ||
64 | - | let LEASINGSHARE = 90 | |
65 | - | ||
66 | - | let LEASINTXCOUNT = 10 | |
67 | - | ||
68 | - | let DEFICITOFFSET = 10 | |
69 | - | ||
70 | - | let WAVESASSETID = "waves" | |
71 | - | ||
72 | - | let CANCELED = "canceled" | |
73 | - | ||
74 | - | let NEW = "new" | |
75 | - | ||
76 | - | let NeutrinoAssetIdKey = "neutrino_asset_id" | |
77 | - | ||
78 | - | let BondAssetIdKey = "bond_asset_id" | |
79 | - | ||
80 | - | let ReserveContractKey = "reserve_contract" | |
81 | - | ||
82 | - | let AuctionContractKey = "auction_contract" | |
83 | - | ||
84 | - | let LiquidationContractKey = "liquidation_contract" | |
85 | - | ||
86 | - | let RPDContractKey = "rpd_contract" | |
87 | - | ||
88 | - | let ContolContractKey = "control_contract" | |
89 | - | ||
90 | - | let BalanceLockIntervalKey = "balance_lock_interval" | |
91 | - | ||
92 | - | let MinWavesSwapAmountKey = "min_waves_swap_amount" | |
93 | - | ||
94 | - | let MinNeutrinoSwapAmountKey = "min_neutrino_swap_amount" | |
95 | - | ||
96 | - | let NodeAddressKey = "node_address" | |
97 | - | ||
98 | - | let NodeOracleProviderKey = "oracle_node_provider" | |
99 | - | ||
100 | - | let LeasingIntervalKey = "leasing_interval" | |
101 | - | ||
102 | - | let RPDBalanceKey = "rpd_balance" | |
103 | - | ||
104 | - | func getRPDContractBalanceKey (assetId) = ((RPDBalanceKey + "_") + toBase58String(assetId)) | |
50 | + | func getRqTargetKey (requestId) = ("target_" + requestId) | |
105 | 51 | ||
106 | 52 | ||
107 | - | let TotalOrderbookKey = "total_orderbook" | |
108 | - | ||
109 | - | let TotalLiquidationOrderbookKey = "total_liquidation_orderbook" | |
110 | - | ||
111 | - | let PriceKey = "price" | |
112 | - | ||
113 | - | let PriceIndexKey = "price_index" | |
114 | - | ||
115 | - | let IsBlockedKey = "is_blocked" | |
116 | - | ||
117 | - | let LeasingExpireBlockKey = "leasing_expire_block" | |
118 | - | ||
119 | - | let LeasingTxCountKey = "leasing_index" | |
120 | - | ||
121 | - | let LeasingAmountKey = "leasing_amount" | |
122 | - | ||
123 | - | func getPriceHistoryKey (block) = ((PriceKey + "_") + toString(block)) | |
53 | + | func getRqAmountKey (requestId) = ("amount_" + requestId) | |
124 | 54 | ||
125 | 55 | ||
126 | - | func getHeightPriceByIndexKey (index) = ((PriceIndexKey + "_") + toString(index)) | |
56 | + | let admins = split(getStringByKey(AdminsKey), ",") | |
57 | + | ||
58 | + | let assetId = fromBase58String(getStringByKey(AssetIdKey)) | |
59 | + | ||
60 | + | let bftCoefficient = getNumberByKey(BftCoefficientKey) | |
61 | + | ||
62 | + | func getRqStatus (requestId) = getNumberByKey(getRqStatusKey(requestId)) | |
127 | 63 | ||
128 | 64 | ||
129 | - | let RPDSyncIndexKey = "rpd_sync_index" | |
130 | - | ||
131 | - | let BalanceLocedkKey = "balance_lock_" | |
132 | - | ||
133 | - | let WavesLockedBalanceKey = (BalanceLocedkKey + "waves") | |
134 | - | ||
135 | - | let NeutrinoLockedBalanceKey = (BalanceLocedkKey + "neutrino") | |
136 | - | ||
137 | - | func getRPDSnapshotContractBalanceKey (count,assetId) = ((((RPDBalanceKey + "_") + toBase58String(assetId)) + "_") + toString(count)) | |
65 | + | func getRqType (requestId) = getNumberByKey(getRqTypeKey(requestId)) | |
138 | 66 | ||
139 | 67 | ||
140 | - | func | |
68 | + | func getRqOwner (requestId) = getStringByKey(getRqOwnerKey(requestId)) | |
141 | 69 | ||
142 | 70 | ||
143 | - | func | |
71 | + | func getRqTarget (requestId) = getStringByKey(getRqTargetKey(requestId)) | |
144 | 72 | ||
145 | 73 | ||
146 | - | func getNeutrinoLockedBalanceKey (owner) = ((NeutrinoLockedBalanceKey + "_") + owner) | |
147 | - | ||
148 | - | ||
149 | - | func getBalanceUnlockBlockKey (owner) = ("balance_unlock_block_" + owner) | |
150 | - | ||
151 | - | ||
152 | - | func getRPDProfitKey (count) = (("rpd_profit" + "_") + toString(count)) | |
153 | - | ||
154 | - | ||
155 | - | func getLeaseTxStatusKey (hash) = (("lease_tx_status" + "_") + hash) | |
156 | - | ||
157 | - | ||
158 | - | func getLeaseTxAmountByHashKey (hash) = ((LeasingAmountKey + "_") + hash) | |
159 | - | ||
160 | - | ||
161 | - | func getLeaseTxBytesByHashKey (hash) = (("lease_tx" + "_") + hash) | |
162 | - | ||
163 | - | ||
164 | - | func getLeaseTxExpireSendBlockKey (hash) = (("leasing_expire_send" + "_") + hash) | |
165 | - | ||
166 | - | ||
167 | - | func convertNeutrinoToWaves (amount,price) = ((((amount * 100) / price) * WAVELET) / PAULI) | |
168 | - | ||
169 | - | ||
170 | - | func convertWavesToNeutrino (amount,price) = ((((amount * price) / 100) * PAULI) / WAVELET) | |
171 | - | ||
172 | - | ||
173 | - | func convertNeutrinoToBond (amount) = (amount / PAULI) | |
174 | - | ||
175 | - | ||
176 | - | func convertBondToNeutrino (amount) = (amount * PAULI) | |
177 | - | ||
178 | - | ||
179 | - | func convertWavesToBond (amount,price) = convertNeutrinoToBond(convertWavesToNeutrino(amount, price)) | |
180 | - | ||
181 | - | ||
182 | - | let neutrinoLockedBalance = getNumberByKey(NeutrinoLockedBalanceKey) | |
183 | - | ||
184 | - | let wavesLockedBalance = getNumberByKey(WavesLockedBalanceKey) | |
185 | - | ||
186 | - | let liquidationContract = getStringByKey(LiquidationContractKey) | |
187 | - | ||
188 | - | let neutrinoAssetIdString = getStringByKey(NeutrinoAssetIdKey) | |
189 | - | ||
190 | - | let neutrinoAssetId = fromBase58String(neutrinoAssetIdString) | |
191 | - | ||
192 | - | let reserveContract = getStringByKey(ReserveContractKey) | |
193 | - | ||
194 | - | let auctionContract = getStringByKey(AuctionContractKey) | |
195 | - | ||
196 | - | let rpdContract = getStringByKey(RPDContractKey) | |
197 | - | ||
198 | - | let controlContract = getStringByKey(ContolContractKey) | |
199 | - | ||
200 | - | let currentPrice = getNumberByAddressAndKey(controlContract, PriceKey) | |
201 | - | ||
202 | - | let priceIndex = getNumberByAddressAndKey(controlContract, PriceIndexKey) | |
203 | - | ||
204 | - | let isBlocked = getBoolByAddressAndKey(controlContract, IsBlockedKey) | |
205 | - | ||
206 | - | let leasingTxCount = getNumberByKey(LeasingTxCountKey) | |
207 | - | ||
208 | - | let leasingInterval = getNumberByKey(LeasingIntervalKey) | |
209 | - | ||
210 | - | let leasingExpireBlock = getNumberByKey(LeasingExpireBlockKey) | |
211 | - | ||
212 | - | let leasingAmount = getNumberByKey(LeasingAmountKey) | |
213 | - | ||
214 | - | let nodeAddress = getStringByKey(NodeAddressKey) | |
215 | - | ||
216 | - | let nodeOracleProvider = getStringByKey(NodeOracleProviderKey) | |
217 | - | ||
218 | - | let rpdSyncIndex = getNumberByKey(RPDSyncIndexKey) | |
219 | - | ||
220 | - | let balanceLockInterval = getNumberByKey(BalanceLockIntervalKey) | |
221 | - | ||
222 | - | let minWavesSwapAmount = getNumberByKey(MinWavesSwapAmountKey) | |
223 | - | ||
224 | - | let minNeutrinoSwapAmount = getNumberByKey(MinNeutrinoSwapAmountKey) | |
225 | - | ||
226 | - | let reserve = (wavesBalance(this) - wavesLockedBalance) | |
227 | - | ||
228 | - | let reserveWithoutLeasing = (reserve - leasingAmount) | |
229 | - | ||
230 | - | let bondAssetId = fromBase58String(getStringByKey(BondAssetIdKey)) | |
231 | - | ||
232 | - | let bondSupply = (extract(assetInfo(bondAssetId)).quantity - assetBalance(this, bondAssetId)) | |
233 | - | ||
234 | - | let neutrinoSupply = ((extract(assetInfo(neutrinoAssetId)).quantity - assetBalance(this, neutrinoAssetId)) + neutrinoLockedBalance) | |
235 | - | ||
236 | - | let surplus = (convertWavesToNeutrino(reserve, currentPrice) - neutrinoSupply) | |
237 | - | ||
238 | - | let deficit = (neutrinoSupply - convertWavesToNeutrino(reserve, currentPrice)) | |
239 | - | ||
240 | - | func getRPDContractBalance (assetId) = getNumberByAddressAndKey(rpdContract, getRPDContractBalanceKey(assetId)) | |
241 | - | ||
242 | - | ||
243 | - | let totalLiquidationOrderbook = getNumberByAddressAndKey(auctionContract, TotalLiquidationOrderbookKey) | |
244 | - | ||
245 | - | let totalOrderbook = getNumberByAddressAndKey(auctionContract, TotalOrderbookKey) | |
246 | - | ||
247 | - | func getPriceHistory (block) = getNumberByAddressAndKey(controlContract, getPriceHistoryKey(block)) | |
248 | - | ||
249 | - | ||
250 | - | func getHeightPriceByIndex (index) = getNumberByAddressAndKey(controlContract, getHeightPriceByIndexKey(index)) | |
251 | - | ||
252 | - | ||
253 | - | func getCancelLeaseTxReserveFee (hash) = getNumberByKey(getCancelLeaseTxReserveFeeKey(hash)) | |
254 | - | ||
255 | - | ||
256 | - | func getWavesLockedBalance (owner) = getNumberByKey(getWavesLockedBalanceKey(owner)) | |
257 | - | ||
258 | - | ||
259 | - | func getNeutrinoLockedBalance (owner) = getNumberByKey(getNeutrinoLockedBalanceKey(owner)) | |
260 | - | ||
261 | - | ||
262 | - | func getUnlockBalanceBlock (owner) = getNumberByKey(getBalanceUnlockBlockKey(owner)) | |
263 | - | ||
264 | - | ||
265 | - | func getRPDProfit (count) = getNumberByKey(getRPDProfitKey(count)) | |
266 | - | ||
267 | - | ||
268 | - | func getLeaseTxStatus (hash) = getStringByKey(getLeaseTxStatusKey(hash)) | |
269 | - | ||
270 | - | ||
271 | - | func getLeaseTxAmountByHash (hash) = getNumberByKey(getLeaseTxAmountByHashKey(hash)) | |
272 | - | ||
273 | - | ||
274 | - | func getLeaseTxBytesByHash (hash) = getStringByKey(getLeaseTxBytesByHashKey(hash)) | |
275 | - | ||
276 | - | ||
277 | - | func getLeaseTxExpireSendBlock (hash) = getNumberByKey(getLeaseTxExpireSendBlockKey(hash)) | |
74 | + | func getRqAmount (requestId) = getNumberByKey(getRqAmountKey(requestId)) | |
278 | 75 | ||
279 | 76 | ||
280 | 77 | @Callable(i) | |
281 | - | func | |
78 | + | func createLockRequest (recipient) = { | |
282 | 79 | let pmt = extract(i.payment) | |
283 | - | let account = toString(i.caller) | |
284 | - | if ((minWavesSwapAmount > pmt.amount)) | |
285 | - | then throw((("an amount is less than min available amount: " + toString(minWavesSwapAmount)) + " wavelets")) | |
286 | - | else if (isDefined(pmt.assetId)) | |
287 | - | then throw("can use waves only") | |
288 | - | else if (isBlocked) | |
289 | - | then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles") | |
290 | - | else if ((getUnlockBalanceBlock(account) > height)) | |
291 | - | then throw((("await " + toString((getUnlockBalanceBlock(account) - height))) + " blocks")) | |
292 | - | else if (if ((getNeutrinoLockedBalance(account) != 0)) | |
293 | - | then true | |
294 | - | else (getWavesLockedBalance(account) != 0)) | |
295 | - | then throw("please withdraw locked funds first") | |
296 | - | else WriteSet([DataEntry(getWavesLockedBalanceKey(account), pmt.amount), DataEntry(getBalanceUnlockBlockKey(account), (height + balanceLockInterval)), DataEntry(WavesLockedBalanceKey, (wavesLockedBalance + pmt.amount))]) | |
80 | + | let requestId = toBase58String(keccak256((((fromBase58String(toString(this)) + i.caller.bytes) + i.transactionId) + toBytes(recipient)))) | |
81 | + | if ((pmt.assetId != assetId)) | |
82 | + | then throw("can use waves only") | |
83 | + | else if ((getRqOwner(requestId) != "")) | |
84 | + | then throw("request exists") | |
85 | + | else WriteSet([DataEntry(getRqStatusKey(requestId), NEW), DataEntry(getRqTypeKey(requestId), LOCK), DataEntry(getRqOwnerKey(requestId), toString(i.caller)), DataEntry(getRqHeightKey(requestId), height), DataEntry(getRqTargetKey(requestId), recipient), DataEntry(getRqAmountKey(requestId), pmt.amount)]) | |
297 | 86 | } | |
298 | 87 | ||
299 | 88 | ||
300 | 89 | ||
301 | 90 | @Callable(i) | |
302 | - | func swapNeutrinoToWaves () = { | |
303 | - | let pmt = extract(i.payment) | |
304 | - | let account = toString(i.caller) | |
305 | - | if ((minNeutrinoSwapAmount > pmt.amount)) | |
306 | - | then throw((("an amount is less than min available amount: " + toString(minNeutrinoSwapAmount)) + " neutrino cents")) | |
307 | - | else if (isBlocked) | |
308 | - | then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles") | |
309 | - | else if ((pmt.assetId != neutrinoAssetId)) | |
310 | - | then throw("can use appropriate neutrino tokens only") | |
311 | - | else if ((getUnlockBalanceBlock(account) > height)) | |
312 | - | then throw((("await " + toString((getUnlockBalanceBlock(account) - height))) + " blocks")) | |
313 | - | else if (if ((getNeutrinoLockedBalance(account) != 0)) | |
314 | - | then true | |
315 | - | else (getWavesLockedBalance(account) != 0)) | |
316 | - | then throw("please withdraw locked funds first") | |
317 | - | else WriteSet([DataEntry(getNeutrinoLockedBalanceKey(account), pmt.amount), DataEntry(getWavesLockedBalanceKey(account), (height + balanceLockInterval)), DataEntry(NeutrinoLockedBalanceKey, (neutrinoLockedBalance + pmt.amount))]) | |
91 | + | func changeStatus (requestHash,signsString,status) = { | |
92 | + | let signs = split(signsString, ",") | |
93 | + | let msg = ((requestHash + "_") + toString(status)) | |
94 | + | let count = (((((if (sigVerify(toBytes(msg), fromBase58String(signs[0]), fromBase58String(admins[0]))) | |
95 | + | then 1 | |
96 | + | else 0) + (if (sigVerify(toBytes(msg), fromBase58String(signs[1]), fromBase58String(admins[1]))) | |
97 | + | then 1 | |
98 | + | else 0)) + (if (sigVerify(toBytes(msg), fromBase58String(signs[2]), fromBase58String(admins[2]))) | |
99 | + | then 1 | |
100 | + | else 0)) + (if (sigVerify(toBytes(msg), fromBase58String(signs[3]), fromBase58String(admins[3]))) | |
101 | + | then 1 | |
102 | + | else 0)) + (if (sigVerify(toBytes(msg), fromBase58String(signs[4]), fromBase58String(admins[4]))) | |
103 | + | then 1 | |
104 | + | else 0)) | |
105 | + | if ((bftCoefficient > count)) | |
106 | + | then throw("count is less 3") | |
107 | + | else if ((getRqOwner(requestHash) == "")) | |
108 | + | then throw("request is not exists") | |
109 | + | else if ((getRqStatus(requestHash) != NEW)) | |
110 | + | then throw("request is not exists") | |
111 | + | else if (if ((status != SUCCESS)) | |
112 | + | then (status != REJECTED) | |
113 | + | else false) | |
114 | + | then throw("invalid status") | |
115 | + | else { | |
116 | + | let owner = addressFromStringValue(getRqOwner(requestHash)) | |
117 | + | let type = getRqType(requestHash) | |
118 | + | let amount = getRqAmount(requestHash) | |
119 | + | ScriptResult(WriteSet([DataEntry(getRqStatusKey(requestHash), status)]), TransferSet([ScriptTransfer(owner, if (if (if ((status == REJECTED)) | |
120 | + | then (type == LOCK) | |
121 | + | else false) | |
122 | + | then true | |
123 | + | else if ((status == SUCCESS)) | |
124 | + | then (type == UNLOCK) | |
125 | + | else false) | |
126 | + | then amount | |
127 | + | else 0, assetId)])) | |
128 | + | } | |
318 | 129 | } | |
319 | 130 | ||
320 | 131 | ||
321 | 132 | ||
322 | 133 | @Callable(i) | |
323 | - | func withdraw (account,index) = { | |
324 | - | let unlockHeight = getUnlockBalanceBlock(account) | |
325 | - | let userWavesLockedBalance = getWavesLockedBalance(account) | |
326 | - | let userNeutrinoLockedBalance = getNeutrinoLockedBalance(account) | |
327 | - | let indexHeight = getHeightPriceByIndex(index) | |
328 | - | let nextIndexHeight = getHeightPriceByIndex((index + 1)) | |
329 | - | let priceByIndex = getPriceHistory(indexHeight) | |
330 | - | let neutrinoAmount = convertWavesToNeutrino(userWavesLockedBalance, priceByIndex) | |
331 | - | let wavesAmount = convertNeutrinoToWaves(userNeutrinoLockedBalance, priceByIndex) | |
332 | - | if (isBlocked) | |
333 | - | then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles") | |
334 | - | else if ((unlockHeight > height)) | |
335 | - | then throw((("please wait for: " + toString(unlockHeight)) + " block height to withdraw WAVES funds")) | |
336 | - | else if (if (if ((index > priceIndex)) | |
337 | - | then true | |
338 | - | else (indexHeight > unlockHeight)) | |
339 | - | then true | |
340 | - | else if ((nextIndexHeight != 0)) | |
341 | - | then (unlockHeight >= nextIndexHeight) | |
342 | - | else false) | |
343 | - | then throw("invalid price history index") | |
344 | - | else if (if ((0 >= neutrinoAmount)) | |
345 | - | then (0 >= wavesAmount) | |
346 | - | else false) | |
347 | - | then throw("balance equals zero") | |
348 | - | else ScriptResult(WriteSet([DataEntry(getWavesLockedBalanceKey(account), 0), DataEntry(getNeutrinoLockedBalanceKey(account), 0), DataEntry(WavesLockedBalanceKey, (wavesLockedBalance - userWavesLockedBalance)), DataEntry(NeutrinoLockedBalanceKey, (neutrinoLockedBalance - userNeutrinoLockedBalance))]), TransferSet([ScriptTransfer(addressFromStringValue(account), wavesAmount, unit), ScriptTransfer(addressFromStringValue(account), neutrinoAmount, neutrinoAssetId)])) | |
134 | + | func createUnlockRequest (sender,amount) = { | |
135 | + | let requestId = toBase58String(keccak256(((((fromBase58String(toString(this)) + i.caller.bytes) + i.transactionId) + toBytes(sender)) + toBytes(amount)))) | |
136 | + | if ((getRqOwner(requestId) != "")) | |
137 | + | then throw("request exists") | |
138 | + | else WriteSet([DataEntry(getRqStatusKey(requestId), NEW), DataEntry(getRqTypeKey(requestId), UNLOCK), DataEntry(getRqOwnerKey(requestId), toString(i.caller)), DataEntry(getRqHeightKey(requestId), height), DataEntry(getRqTargetKey(requestId), sender), DataEntry(getRqAmountKey(requestId), amount)]) | |
349 | 139 | } | |
350 | 140 | ||
351 | - | ||
352 | - | ||
353 | - | @Callable(i) | |
354 | - | func transferToAuction () = { | |
355 | - | let deficitBondAmount = ((convertNeutrinoToBond(deficit) - assetBalance(addressFromStringValue(auctionContract), bondAssetId)) - totalLiquidationOrderbook) | |
356 | - | let surplusBond = ((convertNeutrinoToBond(surplus) - assetBalance(addressFromStringValue(auctionContract), neutrinoAssetId)) - totalOrderbook) | |
357 | - | if (isBlocked) | |
358 | - | then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles") | |
359 | - | else if ((deficitBondAmount >= ((convertNeutrinoToBond(neutrinoSupply) * DEFICITOFFSET) / 100))) | |
360 | - | then TransferSet([ScriptTransfer(addressFromStringValue(auctionContract), deficitBondAmount, bondAssetId)]) | |
361 | - | else if ((surplusBond > 0)) | |
362 | - | then TransferSet([ScriptTransfer(addressFromStringValue(liquidationContract), convertBondToNeutrino(surplusBond), neutrinoAssetId)]) | |
363 | - | else throw(((((("bond were generated or do not need it. Deficit:" + toString(deficitBondAmount)) + "|") + toString(((neutrinoSupply * DEFICITOFFSET) / 100))) + ". Surplus:") + toString(surplusBond))) | |
364 | - | } | |
365 | - | ||
366 | - | ||
367 | - | ||
368 | - | @Callable(i) | |
369 | - | func transfer (account) = { | |
370 | - | let pmt = extract(i.payment) | |
371 | - | TransferSet([ScriptTransfer(addressFromStringValue(account), pmt.amount, pmt.assetId)]) | |
372 | - | } | |
373 | - | ||
374 | - | ||
375 | - | ||
376 | - | @Callable(i) | |
377 | - | func nodeReward () = { | |
378 | - | let pmt = value(i.payment) | |
379 | - | if ((i.caller != addressFromStringValue(nodeAddress))) | |
380 | - | then throw("only node account is able to transfer staking rewards from main account") | |
381 | - | else if (isDefined(pmt.assetId)) | |
382 | - | then throw("waves tokens only allowed") | |
383 | - | else { | |
384 | - | let amount = convertWavesToNeutrino(pmt.amount, currentPrice) | |
385 | - | let newRpdSyncIndex = (rpdSyncIndex + 1) | |
386 | - | ScriptResult(WriteSet([DataEntry(RPDSyncIndexKey, newRpdSyncIndex), DataEntry(getRPDProfitKey(rpdSyncIndex), amount), DataEntry(getRPDSnapshotContractBalanceKey(rpdSyncIndex, neutrinoAssetId), getRPDContractBalance(neutrinoAssetId))]), TransferSet([ScriptTransfer(addressFromStringValue(rpdContract), amount, neutrinoAssetId)])) | |
387 | - | } | |
388 | - | } | |
389 | - | ||
390 | - | ||
391 | - | @Verifier(tx) | |
392 | - | func verify () = { | |
393 | - | let id = toBase58String(tx.id) | |
394 | - | match tx { | |
395 | - | case leasingTx: LeaseCancelTransaction|LeaseTransaction => | |
396 | - | if (sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)) | |
397 | - | then (addressFromString(nodeOracleProvider) == addressFromPublicKey(tx.senderPublicKey)) | |
398 | - | else false | |
399 | - | case _ => | |
400 | - | sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey) | |
401 | - | } | |
402 | - | } | |
403 | 141 |
Old | New | Differences | |
---|---|---|---|
1 | 1 | {-# STDLIB_VERSION 3 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | 4 | func getNumberByKey (key) = match getInteger(this, key) { | |
5 | 5 | case a: Int => | |
6 | 6 | a | |
7 | 7 | case _ => | |
8 | 8 | 0 | |
9 | 9 | } | |
10 | 10 | ||
11 | 11 | ||
12 | 12 | func getStringByKey (key) = match getString(this, key) { | |
13 | 13 | case a: String => | |
14 | 14 | a | |
15 | 15 | case _ => | |
16 | 16 | "" | |
17 | 17 | } | |
18 | 18 | ||
19 | 19 | ||
20 | - | func getBoolByKey (key) = match getBoolean(this, key) { | |
21 | - | case a: Boolean => | |
22 | - | a | |
23 | - | case _ => | |
24 | - | false | |
25 | - | } | |
20 | + | let NONE = 0 | |
21 | + | ||
22 | + | let NEW = 1 | |
23 | + | ||
24 | + | let REJECTED = 2 | |
25 | + | ||
26 | + | let SUCCESS = 3 | |
27 | + | ||
28 | + | let LOCK = 0 | |
29 | + | ||
30 | + | let UNLOCK = 1 | |
31 | + | ||
32 | + | let AssetIdKey = "asset_id" | |
33 | + | ||
34 | + | let AdminsKey = "admins" | |
35 | + | ||
36 | + | let BftCoefficientKey = "bftCoefficient" | |
37 | + | ||
38 | + | func getRqStatusKey (requestId) = ("status_" + requestId) | |
26 | 39 | ||
27 | 40 | ||
28 | - | func getNumberByAddressAndKey (address,key) = match getInteger(addressFromStringValue(address), key) { | |
29 | - | case a: Int => | |
30 | - | a | |
31 | - | case _ => | |
32 | - | 0 | |
33 | - | } | |
41 | + | func getRqHeightKey (requestId) = ("height_" + requestId) | |
34 | 42 | ||
35 | 43 | ||
36 | - | func getStringByAddressAndKey (address,key) = match getString(addressFromStringValue(address), key) { | |
37 | - | case a: String => | |
38 | - | a | |
39 | - | case _ => | |
40 | - | "" | |
41 | - | } | |
44 | + | func getRqTypeKey (requestId) = ("type_" + requestId) | |
42 | 45 | ||
43 | 46 | ||
44 | - | func getBoolByAddressAndKey (address,key) = match getBoolean(addressFromStringValue(address), key) { | |
45 | - | case a: Boolean => | |
46 | - | a | |
47 | - | case _ => | |
48 | - | false | |
49 | - | } | |
47 | + | func getRqOwnerKey (requestId) = ("owner_" + requestId) | |
50 | 48 | ||
51 | 49 | ||
52 | - | let SENDTXEXPIRE = 30 | |
53 | - | ||
54 | - | let LISTSPLITSYMBOL = "_" | |
55 | - | ||
56 | - | let LISTDATASYMBOL = "+" | |
57 | - | ||
58 | - | let WAVELET = 100000000 | |
59 | - | ||
60 | - | let PAULI = 100 | |
61 | - | ||
62 | - | let CRYTICALSHARE = 20 | |
63 | - | ||
64 | - | let LEASINGSHARE = 90 | |
65 | - | ||
66 | - | let LEASINTXCOUNT = 10 | |
67 | - | ||
68 | - | let DEFICITOFFSET = 10 | |
69 | - | ||
70 | - | let WAVESASSETID = "waves" | |
71 | - | ||
72 | - | let CANCELED = "canceled" | |
73 | - | ||
74 | - | let NEW = "new" | |
75 | - | ||
76 | - | let NeutrinoAssetIdKey = "neutrino_asset_id" | |
77 | - | ||
78 | - | let BondAssetIdKey = "bond_asset_id" | |
79 | - | ||
80 | - | let ReserveContractKey = "reserve_contract" | |
81 | - | ||
82 | - | let AuctionContractKey = "auction_contract" | |
83 | - | ||
84 | - | let LiquidationContractKey = "liquidation_contract" | |
85 | - | ||
86 | - | let RPDContractKey = "rpd_contract" | |
87 | - | ||
88 | - | let ContolContractKey = "control_contract" | |
89 | - | ||
90 | - | let BalanceLockIntervalKey = "balance_lock_interval" | |
91 | - | ||
92 | - | let MinWavesSwapAmountKey = "min_waves_swap_amount" | |
93 | - | ||
94 | - | let MinNeutrinoSwapAmountKey = "min_neutrino_swap_amount" | |
95 | - | ||
96 | - | let NodeAddressKey = "node_address" | |
97 | - | ||
98 | - | let NodeOracleProviderKey = "oracle_node_provider" | |
99 | - | ||
100 | - | let LeasingIntervalKey = "leasing_interval" | |
101 | - | ||
102 | - | let RPDBalanceKey = "rpd_balance" | |
103 | - | ||
104 | - | func getRPDContractBalanceKey (assetId) = ((RPDBalanceKey + "_") + toBase58String(assetId)) | |
50 | + | func getRqTargetKey (requestId) = ("target_" + requestId) | |
105 | 51 | ||
106 | 52 | ||
107 | - | let TotalOrderbookKey = "total_orderbook" | |
108 | - | ||
109 | - | let TotalLiquidationOrderbookKey = "total_liquidation_orderbook" | |
110 | - | ||
111 | - | let PriceKey = "price" | |
112 | - | ||
113 | - | let PriceIndexKey = "price_index" | |
114 | - | ||
115 | - | let IsBlockedKey = "is_blocked" | |
116 | - | ||
117 | - | let LeasingExpireBlockKey = "leasing_expire_block" | |
118 | - | ||
119 | - | let LeasingTxCountKey = "leasing_index" | |
120 | - | ||
121 | - | let LeasingAmountKey = "leasing_amount" | |
122 | - | ||
123 | - | func getPriceHistoryKey (block) = ((PriceKey + "_") + toString(block)) | |
53 | + | func getRqAmountKey (requestId) = ("amount_" + requestId) | |
124 | 54 | ||
125 | 55 | ||
126 | - | func getHeightPriceByIndexKey (index) = ((PriceIndexKey + "_") + toString(index)) | |
56 | + | let admins = split(getStringByKey(AdminsKey), ",") | |
57 | + | ||
58 | + | let assetId = fromBase58String(getStringByKey(AssetIdKey)) | |
59 | + | ||
60 | + | let bftCoefficient = getNumberByKey(BftCoefficientKey) | |
61 | + | ||
62 | + | func getRqStatus (requestId) = getNumberByKey(getRqStatusKey(requestId)) | |
127 | 63 | ||
128 | 64 | ||
129 | - | let RPDSyncIndexKey = "rpd_sync_index" | |
130 | - | ||
131 | - | let BalanceLocedkKey = "balance_lock_" | |
132 | - | ||
133 | - | let WavesLockedBalanceKey = (BalanceLocedkKey + "waves") | |
134 | - | ||
135 | - | let NeutrinoLockedBalanceKey = (BalanceLocedkKey + "neutrino") | |
136 | - | ||
137 | - | func getRPDSnapshotContractBalanceKey (count,assetId) = ((((RPDBalanceKey + "_") + toBase58String(assetId)) + "_") + toString(count)) | |
65 | + | func getRqType (requestId) = getNumberByKey(getRqTypeKey(requestId)) | |
138 | 66 | ||
139 | 67 | ||
140 | - | func | |
68 | + | func getRqOwner (requestId) = getStringByKey(getRqOwnerKey(requestId)) | |
141 | 69 | ||
142 | 70 | ||
143 | - | func | |
71 | + | func getRqTarget (requestId) = getStringByKey(getRqTargetKey(requestId)) | |
144 | 72 | ||
145 | 73 | ||
146 | - | func getNeutrinoLockedBalanceKey (owner) = ((NeutrinoLockedBalanceKey + "_") + owner) | |
147 | - | ||
148 | - | ||
149 | - | func getBalanceUnlockBlockKey (owner) = ("balance_unlock_block_" + owner) | |
150 | - | ||
151 | - | ||
152 | - | func getRPDProfitKey (count) = (("rpd_profit" + "_") + toString(count)) | |
153 | - | ||
154 | - | ||
155 | - | func getLeaseTxStatusKey (hash) = (("lease_tx_status" + "_") + hash) | |
156 | - | ||
157 | - | ||
158 | - | func getLeaseTxAmountByHashKey (hash) = ((LeasingAmountKey + "_") + hash) | |
159 | - | ||
160 | - | ||
161 | - | func getLeaseTxBytesByHashKey (hash) = (("lease_tx" + "_") + hash) | |
162 | - | ||
163 | - | ||
164 | - | func getLeaseTxExpireSendBlockKey (hash) = (("leasing_expire_send" + "_") + hash) | |
165 | - | ||
166 | - | ||
167 | - | func convertNeutrinoToWaves (amount,price) = ((((amount * 100) / price) * WAVELET) / PAULI) | |
168 | - | ||
169 | - | ||
170 | - | func convertWavesToNeutrino (amount,price) = ((((amount * price) / 100) * PAULI) / WAVELET) | |
171 | - | ||
172 | - | ||
173 | - | func convertNeutrinoToBond (amount) = (amount / PAULI) | |
174 | - | ||
175 | - | ||
176 | - | func convertBondToNeutrino (amount) = (amount * PAULI) | |
177 | - | ||
178 | - | ||
179 | - | func convertWavesToBond (amount,price) = convertNeutrinoToBond(convertWavesToNeutrino(amount, price)) | |
180 | - | ||
181 | - | ||
182 | - | let neutrinoLockedBalance = getNumberByKey(NeutrinoLockedBalanceKey) | |
183 | - | ||
184 | - | let wavesLockedBalance = getNumberByKey(WavesLockedBalanceKey) | |
185 | - | ||
186 | - | let liquidationContract = getStringByKey(LiquidationContractKey) | |
187 | - | ||
188 | - | let neutrinoAssetIdString = getStringByKey(NeutrinoAssetIdKey) | |
189 | - | ||
190 | - | let neutrinoAssetId = fromBase58String(neutrinoAssetIdString) | |
191 | - | ||
192 | - | let reserveContract = getStringByKey(ReserveContractKey) | |
193 | - | ||
194 | - | let auctionContract = getStringByKey(AuctionContractKey) | |
195 | - | ||
196 | - | let rpdContract = getStringByKey(RPDContractKey) | |
197 | - | ||
198 | - | let controlContract = getStringByKey(ContolContractKey) | |
199 | - | ||
200 | - | let currentPrice = getNumberByAddressAndKey(controlContract, PriceKey) | |
201 | - | ||
202 | - | let priceIndex = getNumberByAddressAndKey(controlContract, PriceIndexKey) | |
203 | - | ||
204 | - | let isBlocked = getBoolByAddressAndKey(controlContract, IsBlockedKey) | |
205 | - | ||
206 | - | let leasingTxCount = getNumberByKey(LeasingTxCountKey) | |
207 | - | ||
208 | - | let leasingInterval = getNumberByKey(LeasingIntervalKey) | |
209 | - | ||
210 | - | let leasingExpireBlock = getNumberByKey(LeasingExpireBlockKey) | |
211 | - | ||
212 | - | let leasingAmount = getNumberByKey(LeasingAmountKey) | |
213 | - | ||
214 | - | let nodeAddress = getStringByKey(NodeAddressKey) | |
215 | - | ||
216 | - | let nodeOracleProvider = getStringByKey(NodeOracleProviderKey) | |
217 | - | ||
218 | - | let rpdSyncIndex = getNumberByKey(RPDSyncIndexKey) | |
219 | - | ||
220 | - | let balanceLockInterval = getNumberByKey(BalanceLockIntervalKey) | |
221 | - | ||
222 | - | let minWavesSwapAmount = getNumberByKey(MinWavesSwapAmountKey) | |
223 | - | ||
224 | - | let minNeutrinoSwapAmount = getNumberByKey(MinNeutrinoSwapAmountKey) | |
225 | - | ||
226 | - | let reserve = (wavesBalance(this) - wavesLockedBalance) | |
227 | - | ||
228 | - | let reserveWithoutLeasing = (reserve - leasingAmount) | |
229 | - | ||
230 | - | let bondAssetId = fromBase58String(getStringByKey(BondAssetIdKey)) | |
231 | - | ||
232 | - | let bondSupply = (extract(assetInfo(bondAssetId)).quantity - assetBalance(this, bondAssetId)) | |
233 | - | ||
234 | - | let neutrinoSupply = ((extract(assetInfo(neutrinoAssetId)).quantity - assetBalance(this, neutrinoAssetId)) + neutrinoLockedBalance) | |
235 | - | ||
236 | - | let surplus = (convertWavesToNeutrino(reserve, currentPrice) - neutrinoSupply) | |
237 | - | ||
238 | - | let deficit = (neutrinoSupply - convertWavesToNeutrino(reserve, currentPrice)) | |
239 | - | ||
240 | - | func getRPDContractBalance (assetId) = getNumberByAddressAndKey(rpdContract, getRPDContractBalanceKey(assetId)) | |
241 | - | ||
242 | - | ||
243 | - | let totalLiquidationOrderbook = getNumberByAddressAndKey(auctionContract, TotalLiquidationOrderbookKey) | |
244 | - | ||
245 | - | let totalOrderbook = getNumberByAddressAndKey(auctionContract, TotalOrderbookKey) | |
246 | - | ||
247 | - | func getPriceHistory (block) = getNumberByAddressAndKey(controlContract, getPriceHistoryKey(block)) | |
248 | - | ||
249 | - | ||
250 | - | func getHeightPriceByIndex (index) = getNumberByAddressAndKey(controlContract, getHeightPriceByIndexKey(index)) | |
251 | - | ||
252 | - | ||
253 | - | func getCancelLeaseTxReserveFee (hash) = getNumberByKey(getCancelLeaseTxReserveFeeKey(hash)) | |
254 | - | ||
255 | - | ||
256 | - | func getWavesLockedBalance (owner) = getNumberByKey(getWavesLockedBalanceKey(owner)) | |
257 | - | ||
258 | - | ||
259 | - | func getNeutrinoLockedBalance (owner) = getNumberByKey(getNeutrinoLockedBalanceKey(owner)) | |
260 | - | ||
261 | - | ||
262 | - | func getUnlockBalanceBlock (owner) = getNumberByKey(getBalanceUnlockBlockKey(owner)) | |
263 | - | ||
264 | - | ||
265 | - | func getRPDProfit (count) = getNumberByKey(getRPDProfitKey(count)) | |
266 | - | ||
267 | - | ||
268 | - | func getLeaseTxStatus (hash) = getStringByKey(getLeaseTxStatusKey(hash)) | |
269 | - | ||
270 | - | ||
271 | - | func getLeaseTxAmountByHash (hash) = getNumberByKey(getLeaseTxAmountByHashKey(hash)) | |
272 | - | ||
273 | - | ||
274 | - | func getLeaseTxBytesByHash (hash) = getStringByKey(getLeaseTxBytesByHashKey(hash)) | |
275 | - | ||
276 | - | ||
277 | - | func getLeaseTxExpireSendBlock (hash) = getNumberByKey(getLeaseTxExpireSendBlockKey(hash)) | |
74 | + | func getRqAmount (requestId) = getNumberByKey(getRqAmountKey(requestId)) | |
278 | 75 | ||
279 | 76 | ||
280 | 77 | @Callable(i) | |
281 | - | func | |
78 | + | func createLockRequest (recipient) = { | |
282 | 79 | let pmt = extract(i.payment) | |
283 | - | let account = toString(i.caller) | |
284 | - | if ((minWavesSwapAmount > pmt.amount)) | |
285 | - | then throw((("an amount is less than min available amount: " + toString(minWavesSwapAmount)) + " wavelets")) | |
286 | - | else if (isDefined(pmt.assetId)) | |
287 | - | then throw("can use waves only") | |
288 | - | else if (isBlocked) | |
289 | - | then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles") | |
290 | - | else if ((getUnlockBalanceBlock(account) > height)) | |
291 | - | then throw((("await " + toString((getUnlockBalanceBlock(account) - height))) + " blocks")) | |
292 | - | else if (if ((getNeutrinoLockedBalance(account) != 0)) | |
293 | - | then true | |
294 | - | else (getWavesLockedBalance(account) != 0)) | |
295 | - | then throw("please withdraw locked funds first") | |
296 | - | else WriteSet([DataEntry(getWavesLockedBalanceKey(account), pmt.amount), DataEntry(getBalanceUnlockBlockKey(account), (height + balanceLockInterval)), DataEntry(WavesLockedBalanceKey, (wavesLockedBalance + pmt.amount))]) | |
80 | + | let requestId = toBase58String(keccak256((((fromBase58String(toString(this)) + i.caller.bytes) + i.transactionId) + toBytes(recipient)))) | |
81 | + | if ((pmt.assetId != assetId)) | |
82 | + | then throw("can use waves only") | |
83 | + | else if ((getRqOwner(requestId) != "")) | |
84 | + | then throw("request exists") | |
85 | + | else WriteSet([DataEntry(getRqStatusKey(requestId), NEW), DataEntry(getRqTypeKey(requestId), LOCK), DataEntry(getRqOwnerKey(requestId), toString(i.caller)), DataEntry(getRqHeightKey(requestId), height), DataEntry(getRqTargetKey(requestId), recipient), DataEntry(getRqAmountKey(requestId), pmt.amount)]) | |
297 | 86 | } | |
298 | 87 | ||
299 | 88 | ||
300 | 89 | ||
301 | 90 | @Callable(i) | |
302 | - | func swapNeutrinoToWaves () = { | |
303 | - | let pmt = extract(i.payment) | |
304 | - | let account = toString(i.caller) | |
305 | - | if ((minNeutrinoSwapAmount > pmt.amount)) | |
306 | - | then throw((("an amount is less than min available amount: " + toString(minNeutrinoSwapAmount)) + " neutrino cents")) | |
307 | - | else if (isBlocked) | |
308 | - | then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles") | |
309 | - | else if ((pmt.assetId != neutrinoAssetId)) | |
310 | - | then throw("can use appropriate neutrino tokens only") | |
311 | - | else if ((getUnlockBalanceBlock(account) > height)) | |
312 | - | then throw((("await " + toString((getUnlockBalanceBlock(account) - height))) + " blocks")) | |
313 | - | else if (if ((getNeutrinoLockedBalance(account) != 0)) | |
314 | - | then true | |
315 | - | else (getWavesLockedBalance(account) != 0)) | |
316 | - | then throw("please withdraw locked funds first") | |
317 | - | else WriteSet([DataEntry(getNeutrinoLockedBalanceKey(account), pmt.amount), DataEntry(getWavesLockedBalanceKey(account), (height + balanceLockInterval)), DataEntry(NeutrinoLockedBalanceKey, (neutrinoLockedBalance + pmt.amount))]) | |
91 | + | func changeStatus (requestHash,signsString,status) = { | |
92 | + | let signs = split(signsString, ",") | |
93 | + | let msg = ((requestHash + "_") + toString(status)) | |
94 | + | let count = (((((if (sigVerify(toBytes(msg), fromBase58String(signs[0]), fromBase58String(admins[0]))) | |
95 | + | then 1 | |
96 | + | else 0) + (if (sigVerify(toBytes(msg), fromBase58String(signs[1]), fromBase58String(admins[1]))) | |
97 | + | then 1 | |
98 | + | else 0)) + (if (sigVerify(toBytes(msg), fromBase58String(signs[2]), fromBase58String(admins[2]))) | |
99 | + | then 1 | |
100 | + | else 0)) + (if (sigVerify(toBytes(msg), fromBase58String(signs[3]), fromBase58String(admins[3]))) | |
101 | + | then 1 | |
102 | + | else 0)) + (if (sigVerify(toBytes(msg), fromBase58String(signs[4]), fromBase58String(admins[4]))) | |
103 | + | then 1 | |
104 | + | else 0)) | |
105 | + | if ((bftCoefficient > count)) | |
106 | + | then throw("count is less 3") | |
107 | + | else if ((getRqOwner(requestHash) == "")) | |
108 | + | then throw("request is not exists") | |
109 | + | else if ((getRqStatus(requestHash) != NEW)) | |
110 | + | then throw("request is not exists") | |
111 | + | else if (if ((status != SUCCESS)) | |
112 | + | then (status != REJECTED) | |
113 | + | else false) | |
114 | + | then throw("invalid status") | |
115 | + | else { | |
116 | + | let owner = addressFromStringValue(getRqOwner(requestHash)) | |
117 | + | let type = getRqType(requestHash) | |
118 | + | let amount = getRqAmount(requestHash) | |
119 | + | ScriptResult(WriteSet([DataEntry(getRqStatusKey(requestHash), status)]), TransferSet([ScriptTransfer(owner, if (if (if ((status == REJECTED)) | |
120 | + | then (type == LOCK) | |
121 | + | else false) | |
122 | + | then true | |
123 | + | else if ((status == SUCCESS)) | |
124 | + | then (type == UNLOCK) | |
125 | + | else false) | |
126 | + | then amount | |
127 | + | else 0, assetId)])) | |
128 | + | } | |
318 | 129 | } | |
319 | 130 | ||
320 | 131 | ||
321 | 132 | ||
322 | 133 | @Callable(i) | |
323 | - | func withdraw (account,index) = { | |
324 | - | let unlockHeight = getUnlockBalanceBlock(account) | |
325 | - | let userWavesLockedBalance = getWavesLockedBalance(account) | |
326 | - | let userNeutrinoLockedBalance = getNeutrinoLockedBalance(account) | |
327 | - | let indexHeight = getHeightPriceByIndex(index) | |
328 | - | let nextIndexHeight = getHeightPriceByIndex((index + 1)) | |
329 | - | let priceByIndex = getPriceHistory(indexHeight) | |
330 | - | let neutrinoAmount = convertWavesToNeutrino(userWavesLockedBalance, priceByIndex) | |
331 | - | let wavesAmount = convertNeutrinoToWaves(userNeutrinoLockedBalance, priceByIndex) | |
332 | - | if (isBlocked) | |
333 | - | then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles") | |
334 | - | else if ((unlockHeight > height)) | |
335 | - | then throw((("please wait for: " + toString(unlockHeight)) + " block height to withdraw WAVES funds")) | |
336 | - | else if (if (if ((index > priceIndex)) | |
337 | - | then true | |
338 | - | else (indexHeight > unlockHeight)) | |
339 | - | then true | |
340 | - | else if ((nextIndexHeight != 0)) | |
341 | - | then (unlockHeight >= nextIndexHeight) | |
342 | - | else false) | |
343 | - | then throw("invalid price history index") | |
344 | - | else if (if ((0 >= neutrinoAmount)) | |
345 | - | then (0 >= wavesAmount) | |
346 | - | else false) | |
347 | - | then throw("balance equals zero") | |
348 | - | else ScriptResult(WriteSet([DataEntry(getWavesLockedBalanceKey(account), 0), DataEntry(getNeutrinoLockedBalanceKey(account), 0), DataEntry(WavesLockedBalanceKey, (wavesLockedBalance - userWavesLockedBalance)), DataEntry(NeutrinoLockedBalanceKey, (neutrinoLockedBalance - userNeutrinoLockedBalance))]), TransferSet([ScriptTransfer(addressFromStringValue(account), wavesAmount, unit), ScriptTransfer(addressFromStringValue(account), neutrinoAmount, neutrinoAssetId)])) | |
134 | + | func createUnlockRequest (sender,amount) = { | |
135 | + | let requestId = toBase58String(keccak256(((((fromBase58String(toString(this)) + i.caller.bytes) + i.transactionId) + toBytes(sender)) + toBytes(amount)))) | |
136 | + | if ((getRqOwner(requestId) != "")) | |
137 | + | then throw("request exists") | |
138 | + | else WriteSet([DataEntry(getRqStatusKey(requestId), NEW), DataEntry(getRqTypeKey(requestId), UNLOCK), DataEntry(getRqOwnerKey(requestId), toString(i.caller)), DataEntry(getRqHeightKey(requestId), height), DataEntry(getRqTargetKey(requestId), sender), DataEntry(getRqAmountKey(requestId), amount)]) | |
349 | 139 | } | |
350 | 140 | ||
351 | - | ||
352 | - | ||
353 | - | @Callable(i) | |
354 | - | func transferToAuction () = { | |
355 | - | let deficitBondAmount = ((convertNeutrinoToBond(deficit) - assetBalance(addressFromStringValue(auctionContract), bondAssetId)) - totalLiquidationOrderbook) | |
356 | - | let surplusBond = ((convertNeutrinoToBond(surplus) - assetBalance(addressFromStringValue(auctionContract), neutrinoAssetId)) - totalOrderbook) | |
357 | - | if (isBlocked) | |
358 | - | then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles") | |
359 | - | else if ((deficitBondAmount >= ((convertNeutrinoToBond(neutrinoSupply) * DEFICITOFFSET) / 100))) | |
360 | - | then TransferSet([ScriptTransfer(addressFromStringValue(auctionContract), deficitBondAmount, bondAssetId)]) | |
361 | - | else if ((surplusBond > 0)) | |
362 | - | then TransferSet([ScriptTransfer(addressFromStringValue(liquidationContract), convertBondToNeutrino(surplusBond), neutrinoAssetId)]) | |
363 | - | else throw(((((("bond were generated or do not need it. Deficit:" + toString(deficitBondAmount)) + "|") + toString(((neutrinoSupply * DEFICITOFFSET) / 100))) + ". Surplus:") + toString(surplusBond))) | |
364 | - | } | |
365 | - | ||
366 | - | ||
367 | - | ||
368 | - | @Callable(i) | |
369 | - | func transfer (account) = { | |
370 | - | let pmt = extract(i.payment) | |
371 | - | TransferSet([ScriptTransfer(addressFromStringValue(account), pmt.amount, pmt.assetId)]) | |
372 | - | } | |
373 | - | ||
374 | - | ||
375 | - | ||
376 | - | @Callable(i) | |
377 | - | func nodeReward () = { | |
378 | - | let pmt = value(i.payment) | |
379 | - | if ((i.caller != addressFromStringValue(nodeAddress))) | |
380 | - | then throw("only node account is able to transfer staking rewards from main account") | |
381 | - | else if (isDefined(pmt.assetId)) | |
382 | - | then throw("waves tokens only allowed") | |
383 | - | else { | |
384 | - | let amount = convertWavesToNeutrino(pmt.amount, currentPrice) | |
385 | - | let newRpdSyncIndex = (rpdSyncIndex + 1) | |
386 | - | ScriptResult(WriteSet([DataEntry(RPDSyncIndexKey, newRpdSyncIndex), DataEntry(getRPDProfitKey(rpdSyncIndex), amount), DataEntry(getRPDSnapshotContractBalanceKey(rpdSyncIndex, neutrinoAssetId), getRPDContractBalance(neutrinoAssetId))]), TransferSet([ScriptTransfer(addressFromStringValue(rpdContract), amount, neutrinoAssetId)])) | |
387 | - | } | |
388 | - | } | |
389 | - | ||
390 | - | ||
391 | - | @Verifier(tx) | |
392 | - | func verify () = { | |
393 | - | let id = toBase58String(tx.id) | |
394 | - | match tx { | |
395 | - | case leasingTx: LeaseCancelTransaction|LeaseTransaction => | |
396 | - | if (sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)) | |
397 | - | then (addressFromString(nodeOracleProvider) == addressFromPublicKey(tx.senderPublicKey)) | |
398 | - | else false | |
399 | - | case _ => | |
400 | - | sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey) | |
401 | - | } | |
402 | - | } | |
403 | 141 |
github/deemru/w8io/026f985 49.38 ms ◑