4 | | - | let version = "1.0.0" |
---|
5 | | - | |
---|
6 | | - | let keyVersion = "version" |
---|
7 | | - | |
---|
8 | | - | let keyActive = "active" |
---|
9 | | - | |
---|
10 | | - | let keyAssetIdA = "A_asset_id" |
---|
11 | | - | |
---|
12 | | - | let keyAssetIdB = "B_asset_id" |
---|
13 | | - | |
---|
14 | | - | let keyBalanceA = "A_asset_balance" |
---|
15 | | - | |
---|
16 | | - | let keyBalanceB = "B_asset_balance" |
---|
17 | | - | |
---|
18 | | - | let keyBalanceInitA = "A_asset_init" |
---|
19 | | - | |
---|
20 | | - | let keyBalanceInitB = "B_asset_init" |
---|
21 | | - | |
---|
22 | | - | let keyShareAssetId = "share_asset_id" |
---|
23 | | - | |
---|
24 | | - | let keyShareAssetSupply = "share_asset_supply" |
---|
25 | | - | |
---|
26 | | - | let keyCommission = "commission" |
---|
27 | | - | |
---|
28 | | - | let keyCommissionScaleDelimiter = "commission_scale_delimiter" |
---|
29 | | - | |
---|
30 | | - | let keyCause = "shutdown_cause" |
---|
31 | | - | |
---|
32 | | - | let keyFirstHarvest = "first_harvest" |
---|
33 | | - | |
---|
34 | | - | let keyFirstHarvestHeight = "first_harvest_height" |
---|
35 | | - | |
---|
36 | | - | let kShareLimit = "share_limit_on_first_harvest" |
---|
37 | | - | |
---|
38 | | - | let kBasePeriod = "base_period" |
---|
39 | | - | |
---|
40 | | - | let kPeriodLength = "period_length" |
---|
41 | | - | |
---|
42 | | - | let kStartHeight = "start_height" |
---|
43 | | - | |
---|
44 | | - | let kFirstHarvestHeight = "first_harvest_height" |
---|
45 | | - | |
---|
46 | | - | let keyAdminPubKey1 = "admin_pub_1" |
---|
47 | | - | |
---|
48 | | - | let keyAdminPubKey2 = "admin_pub_2" |
---|
49 | | - | |
---|
50 | | - | let keyAdminPubKey3 = "admin_pub_3" |
---|
51 | | - | |
---|
52 | | - | let oracle = Address(base58'3PEbqViERCoKnmcSULh6n2aiMvUdSQdCsom') |
---|
53 | | - | |
---|
54 | | - | func getAdminPub (keyAdminPub) = match getString(oracle, keyAdminPub) { |
---|
55 | | - | case string: String => |
---|
56 | | - | fromBase58String(string) |
---|
57 | | - | case nothing => |
---|
58 | | - | throw("Admin public key is empty") |
---|
59 | | - | } |
---|
60 | | - | |
---|
61 | | - | |
---|
62 | | - | let adminPubKey1 = getAdminPub(keyAdminPubKey1) |
---|
63 | | - | |
---|
64 | | - | let adminPubKey2 = getAdminPub(keyAdminPubKey2) |
---|
65 | | - | |
---|
66 | | - | let adminPubKey3 = getAdminPub(keyAdminPubKey3) |
---|
67 | | - | |
---|
68 | | - | let adminPubKeyStartStop = base58'EtVkT6ed8GtbUiVVEqdmEqsp2J4qbb3rre2HFgxeVYdg' |
---|
69 | | - | |
---|
70 | | - | let adminPubKeyStaking = base58'Czn4yoAuUZCVCLJDRfskn8URfkwpknwBTZDbs1wFrY7h' |
---|
71 | | - | |
---|
72 | | - | let walletAddress = Address(base58'3P6J84oH51DzY6xk2mT5TheXRbrCwBMxonp') |
---|
73 | | - | |
---|
74 | | - | let votingAddress = Address(base58'3PQZWxShKGRgBN1qoJw6B4s9YWS9FneZTPg') |
---|
75 | | - | |
---|
76 | | - | let USDN = base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p' |
---|
77 | | - | |
---|
78 | | - | let NSBT = base58'6nSpVyNH7yM69eg446wrQR94ipbbcmZMU1ENPwanC97g' |
---|
79 | | - | |
---|
80 | | - | let SWOP = base58'Ehie5xYpeN8op1Cctc6aGUrqx8jq3jtf1DSjXDbfm7aT' |
---|
81 | | - | |
---|
82 | | - | let EURN = base58'DUk2YTxhRoAqMJLus4G2b3fR8hMHVh6eiyFx5r29VR6t' |
---|
83 | | - | |
---|
84 | | - | let stakingUSDNNSBTAddress = Address(base58'3PNikM6yp4NqcSU8guxQtmR5onr2D4e8yTJ') |
---|
85 | | - | |
---|
86 | | - | let stakingEURNAddress = Address(base58'3PFhcMmEZoQTQ6ohA844c7C9M8ZJ18P8dDj') |
---|
87 | | - | |
---|
88 | | - | let USDNToWavesExchanger = Address(base58'3PHaNgomBkrvEL2QnuJarQVJa71wjw9qiqG') |
---|
89 | | - | |
---|
90 | | - | let USDNToNSBTExchanger = Address(base58'3P2V63Xd6BviDkeMzxhUw2SJyojByRz8a8m') |
---|
91 | | - | |
---|
92 | | - | let stakingFeeInUSDN = 270000 |
---|
93 | | - | |
---|
94 | | - | let stakingFeeInEURN = 234000 |
---|
95 | | - | |
---|
96 | | - | let basePeriod = valueOrErrorMessage(getInteger(votingAddress, kBasePeriod), "Empty kBasePeriod") |
---|
97 | | - | |
---|
98 | | - | let startHeight = valueOrErrorMessage(getInteger(votingAddress, kStartHeight), "Empty kStartHeight") |
---|
99 | | - | |
---|
100 | | - | let periodLength = valueOrErrorMessage(getInteger(votingAddress, kPeriodLength), "Empty kPeriodLength") |
---|
101 | | - | |
---|
102 | | - | let firstHarvestEndPeriod = ((basePeriod + ((height - startHeight) / periodLength)) + 3) |
---|
103 | | - | |
---|
104 | | - | let isActive = getBooleanValue(this, keyActive) |
---|
105 | | - | |
---|
106 | | - | let strAssetIdA = getStringValue(this, keyAssetIdA) |
---|
107 | | - | |
---|
108 | | - | let strAssetIdB = getStringValue(this, keyAssetIdB) |
---|
109 | | - | |
---|
110 | | - | let assetIdA = if ((strAssetIdA == "WAVES")) |
---|
111 | | - | then unit |
---|
112 | | - | else fromBase58String(strAssetIdA) |
---|
113 | | - | |
---|
114 | | - | let assetIdB = if ((strAssetIdB == "WAVES")) |
---|
115 | | - | then unit |
---|
116 | | - | else fromBase58String(strAssetIdB) |
---|
117 | | - | |
---|
118 | | - | let assetNameA = match assetIdA { |
---|
119 | | - | case id: ByteVector => |
---|
120 | | - | value(assetInfo(id)).name |
---|
121 | | - | case waves: Unit => |
---|
122 | | - | "WAVES" |
---|
123 | | - | case _ => |
---|
124 | | - | throw("Match error") |
---|
125 | | - | } |
---|
126 | | - | |
---|
127 | | - | let assetNameB = match assetIdB { |
---|
128 | | - | case id: ByteVector => |
---|
129 | | - | value(assetInfo(id)).name |
---|
130 | | - | case waves: Unit => |
---|
131 | | - | "WAVES" |
---|
132 | | - | case _ => |
---|
133 | | - | throw("Match error") |
---|
134 | | - | } |
---|
135 | | - | |
---|
136 | | - | let balanceA = getIntegerValue(this, keyBalanceA) |
---|
137 | | - | |
---|
138 | | - | let balanceB = getIntegerValue(this, keyBalanceB) |
---|
139 | | - | |
---|
140 | | - | let shareAssetId = fromBase58String(getStringValue(this, keyShareAssetId)) |
---|
141 | | - | |
---|
142 | | - | let shareAssetSupply = getIntegerValue(this, keyShareAssetSupply) |
---|
143 | | - | |
---|
144 | | - | let commission = 3000 |
---|
145 | | - | |
---|
146 | | - | let commissionGovernance = 1200 |
---|
147 | | - | |
---|
148 | | - | let commissionScaleDelimiter = 1000000 |
---|
149 | | - | |
---|
150 | | - | let scaleValue3 = 1000 |
---|
151 | | - | |
---|
152 | | - | let scaleValue8 = 100000000 |
---|
153 | | - | |
---|
154 | | - | let slippageToleranceDelimiter = 1000 |
---|
155 | | - | |
---|
156 | | - | let scaleValue8Digits = 8 |
---|
157 | | - | |
---|
158 | | - | func accountBalance (assetId) = match assetId { |
---|
159 | | - | case id: ByteVector => |
---|
160 | | - | assetBalance(this, id) |
---|
161 | | - | case waves: Unit => |
---|
162 | | - | wavesBalance(this).available |
---|
163 | | - | case _ => |
---|
164 | | - | throw("Match error") |
---|
165 | | - | } |
---|
166 | | - | |
---|
167 | | - | |
---|
168 | | - | func stakedAmount (assetId) = { |
---|
169 | | - | let stakedAmountCalculated = match assetId { |
---|
170 | | - | case aId: ByteVector => |
---|
171 | | - | if (if ((aId == USDN)) |
---|
172 | | - | then true |
---|
173 | | - | else (aId == NSBT)) |
---|
174 | | - | then getInteger(stakingUSDNNSBTAddress, ((("rpd_balance_" + toBase58String(aId)) + "_") + toString(this))) |
---|
175 | | - | else if ((aId == EURN)) |
---|
176 | | - | then getInteger(stakingEURNAddress, ((("%s%s%s__stakingBalance__" + toBase58String(aId)) + "__") + toString(this))) |
---|
177 | | - | else 0 |
---|
178 | | - | case _: Unit => |
---|
179 | | - | 0 |
---|
180 | | - | case _ => |
---|
181 | | - | throw("Match error") |
---|
182 | | - | } |
---|
183 | | - | match stakedAmountCalculated { |
---|
184 | | - | case i: Int => |
---|
185 | | - | i |
---|
186 | | - | case _ => |
---|
187 | | - | 0 |
---|
188 | | - | } |
---|
189 | | - | } |
---|
190 | | - | |
---|
191 | | - | |
---|
192 | | - | let stakedAmountA = stakedAmount(assetIdA) |
---|
193 | | - | |
---|
194 | | - | let stakedAmountB = stakedAmount(assetIdB) |
---|
195 | | - | |
---|
196 | | - | let assetInitA = getIntegerValue(this, keyBalanceInitA) |
---|
197 | | - | |
---|
198 | | - | let assetInitB = getIntegerValue(this, keyBalanceInitB) |
---|
199 | | - | |
---|
200 | | - | let availableBalanceA = (balanceA - stakedAmountA) |
---|
201 | | - | |
---|
202 | | - | let availableBalanceB = (balanceB - stakedAmountB) |
---|
203 | | - | |
---|
204 | | - | let accountBalanceWithStakedA = (accountBalance(assetIdA) + stakedAmountA) |
---|
205 | | - | |
---|
206 | | - | let accountBalanceWithStakedB = (accountBalance(assetIdB) + stakedAmountB) |
---|
207 | | - | |
---|
208 | | - | let hasEnoughBalance = if ((accountBalanceWithStakedA >= balanceA)) |
---|
209 | | - | then (accountBalanceWithStakedB >= balanceB) |
---|
210 | | - | else false |
---|
211 | | - | |
---|
212 | | - | func getAssetInfo (assetId) = match assetId { |
---|
213 | | - | case id: ByteVector => |
---|
214 | | - | let stringId = toBase58String(id) |
---|
215 | | - | let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist")) |
---|
216 | | - | $Tuple3(stringId, info.name, info.decimals) |
---|
217 | | - | case waves: Unit => |
---|
218 | | - | $Tuple3("WAVES", "WAVES", 8) |
---|
219 | | - | case _ => |
---|
220 | | - | throw("Match error") |
---|
221 | | - | } |
---|
222 | | - | |
---|
223 | | - | |
---|
224 | | - | func getAssetInfoFromString (assetStr) = if ((assetStr == "WAVES")) |
---|
225 | | - | then $Tuple3("WAVES", "WAVES", 8) |
---|
226 | | - | else { |
---|
227 | | - | let stringId = assetStr |
---|
228 | | - | let id = fromBase58String(assetStr) |
---|
229 | | - | let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist")) |
---|
230 | | - | $Tuple3(stringId, info.name, info.decimals) |
---|
231 | | - | } |
---|
232 | | - | |
---|
233 | | - | |
---|
234 | | - | func suspend (cause) = [BooleanEntry(keyActive, false), StringEntry(keyCause, cause)] |
---|
235 | | - | |
---|
236 | | - | |
---|
237 | | - | func deductStakingFee (amount,assetId,secondAssetId) = if (if ((assetId == USDN)) |
---|
238 | | - | then true |
---|
239 | | - | else (assetId == EURN)) |
---|
240 | | - | then { |
---|
241 | | - | let stakinFee = if ((assetId == USDN)) |
---|
242 | | - | then (stakingFeeInUSDN * (if ((secondAssetId == NSBT)) |
---|
243 | | - | then 2 |
---|
244 | | - | else 1)) |
---|
245 | | - | else if ((assetId == EURN)) |
---|
246 | | - | then stakingFeeInEURN |
---|
247 | | - | else 0 |
---|
248 | | - | let result = (amount - stakinFee) |
---|
249 | | - | if ((0 >= result)) |
---|
250 | | - | then throw((((("Insufficient amount " + toString(amount)) + " to deduct staking fee ") + toString(stakinFee)) + "USDN/EURN")) |
---|
251 | | - | else result |
---|
252 | | - | } |
---|
253 | | - | else amount |
---|
254 | | - | |
---|
255 | | - | |
---|
256 | | - | func getStakingFee (assetId,secondAssetId) = if ((assetId == USDN)) |
---|
257 | | - | then (stakingFeeInUSDN * (if ((secondAssetId == NSBT)) |
---|
258 | | - | then 2 |
---|
259 | | - | else 1)) |
---|
260 | | - | else if ((assetId == EURN)) |
---|
261 | | - | then stakingFeeInEURN |
---|
262 | | - | else 0 |
---|
263 | | - | |
---|
264 | | - | |
---|
265 | | - | func throwInsufficientAvailableBalance (amount,available,assetName) = throw((((((((("Insufficient DApp balance to pay " + toString(amount)) + " ") + assetName) + " due to staking. Available: ") + toString(available)) + " ") + assetName) + ". Please contact support in Telegram: https://t.me/swopfisupport")) |
---|
266 | | - | |
---|
267 | | - | |
---|
268 | | - | func throwInsufficientAvailableBalances (amountA,amountB) = throw((((((((((((((((("Insufficient DApp balance to pay " + toString(amountA)) + " ") + assetNameA) + " and ") + toString(amountB)) + " ") + assetNameB) + " due to staking. Available: ") + toString(availableBalanceA)) + " ") + assetNameA) + " and ") + toString(availableBalanceB)) + " ") + assetNameB) + ". Please contact support in Telegram: https://t.me/swopfisupport")) |
---|
269 | | - | |
---|
270 | | - | |
---|
271 | | - | func suspendSuspicious () = suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(accountBalanceWithStakedA)) + " ") + assetNameA) + ", ") + toString(accountBalanceWithStakedB)) + " ") + assetNameB) + ". State: ") + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB)) |
---|
275 | | - | func init (firstHarvest) = { |
---|
276 | | - | let $t080008077 = $Tuple2(i.payments[0].amount, i.payments[0].assetId) |
---|
277 | | - | let pmtAmountA = $t080008077._1 |
---|
278 | | - | let pmtAssetIdA = $t080008077._2 |
---|
279 | | - | let $t080828159 = $Tuple2(i.payments[1].amount, i.payments[1].assetId) |
---|
280 | | - | let pmtAmountB = $t080828159._1 |
---|
281 | | - | let pmtAssetIdB = $t080828159._2 |
---|
282 | | - | let $t081648241 = getAssetInfo(pmtAssetIdA) |
---|
283 | | - | let pmtStrAssetIdA = $t081648241._1 |
---|
284 | | - | let pmtAssetNameA = $t081648241._2 |
---|
285 | | - | let pmtDecimalsA = $t081648241._3 |
---|
286 | | - | let $t082468502 = getAssetInfo(pmtAssetIdB) |
---|
287 | | - | let pmtStrAssetIdB = $t082468502._1 |
---|
288 | | - | let pmtAssetNameB = $t082468502._2 |
---|
289 | | - | let pmtDecimalsB = $t082468502._3 |
---|
290 | | - | if (isDefined(getBoolean(this, keyActive))) |
---|
291 | | - | then throw("DApp is already active") |
---|
292 | | - | else if ((pmtAssetIdA == pmtAssetIdB)) |
---|
293 | | - | then throw("Assets must be different") |
---|
294 | | - | else { |
---|
295 | | - | let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7)) |
---|
296 | | - | let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this)) |
---|
297 | | - | let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2) |
---|
298 | | - | let arg1 = pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN) |
---|
299 | | - | let arg2 = pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN) |
---|
300 | | - | let arg3 = pow(10, 0, shareDecimals, 0, 0, DOWN) |
---|
301 | | - | let shareInitialSupply = fraction(arg1, arg2, arg3) |
---|
302 | | - | let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true) |
---|
303 | | - | let shareIssueId = calculateAssetId(shareIssue) |
---|
304 | | - | let baseEntry = [StringEntry(keyVersion, version), BooleanEntry(keyActive, true), StringEntry(keyAssetIdA, pmtStrAssetIdA), StringEntry(keyAssetIdB, pmtStrAssetIdB), IntegerEntry(keyBalanceA, pmtAmountA), IntegerEntry(keyBalanceB, pmtAmountB), IntegerEntry(keyCommission, commission), IntegerEntry(keyCommissionScaleDelimiter, commissionScaleDelimiter), shareIssue, StringEntry(keyShareAssetId, toBase58String(shareIssueId)), IntegerEntry(keyShareAssetSupply, shareInitialSupply), ScriptTransfer(i.caller, shareInitialSupply, shareIssueId)] |
---|
305 | | - | if (firstHarvest) |
---|
306 | | - | then (baseEntry ++ [BooleanEntry(keyFirstHarvest, firstHarvest), IntegerEntry(keyFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))]) |
---|
307 | | - | else baseEntry |
---|
308 | | - | } |
---|
309 | | - | } |
---|
| 7 | + | func routingTrade (exchangers,args,assetPay,minAmountToReceive) = { |
---|
| 8 | + | let $t0624699 = $Tuple2(i.payments[0].amount, i.payments[0].assetId) |
---|
| 9 | + | let pmtAmount = $t0624699._1 |
---|
| 10 | + | let pmtAssetId = $t0624699._2 |
---|
| 11 | + | let routingSize = size(exchangers) |
---|
| 12 | + | func exchangeFold (accumulated,exchanger) = if ((routingSize > accumulated)) |
---|
| 13 | + | then { |
---|
| 14 | + | let exchangerAddress = addressFromStringValue(exchanger) |
---|
| 15 | + | let inv = invoke(exchangerAddress, "exchange", [args[accumulated]], [AttachedPayment(pmtAssetId, pmtAmount)]) |
---|
| 16 | + | if ((inv == inv)) |
---|
| 17 | + | then (accumulated + 1) |
---|
| 18 | + | else throw("Strict value is not equal to itself.") |
---|
| 19 | + | } |
---|
| 20 | + | else accumulated |
---|
313 | | - | @Callable(i) |
---|
314 | | - | func initWithInitRatio (amtAssetA,amtAssetB,strAssetIdA,strAssetIdB,firstHarvest) = { |
---|
315 | | - | let $t01057910666 = getAssetInfoFromString(strAssetIdA) |
---|
316 | | - | let pmtStrAssetIdA = $t01057910666._1 |
---|
317 | | - | let pmtAssetNameA = $t01057910666._2 |
---|
318 | | - | let pmtDecimalsA = $t01057910666._3 |
---|
319 | | - | let $t01067110758 = getAssetInfoFromString(strAssetIdB) |
---|
320 | | - | let pmtStrAssetIdB = $t01067110758._1 |
---|
321 | | - | let pmtAssetNameB = $t01067110758._2 |
---|
322 | | - | let pmtDecimalsB = $t01067110758._3 |
---|
323 | | - | if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey))) |
---|
324 | | - | then throw("Only admin can call this function") |
---|
325 | | - | else if (isDefined(getBoolean(this, keyActive))) |
---|
326 | | - | then throw("DApp is already active") |
---|
327 | | - | else if ((strAssetIdA == strAssetIdB)) |
---|
328 | | - | then throw("Assets must be different") |
---|
329 | | - | else { |
---|
330 | | - | let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7)) |
---|
331 | | - | let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this)) |
---|
332 | | - | let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2) |
---|
333 | | - | let shareInitialSupply = 0 |
---|
334 | | - | let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true) |
---|
335 | | - | let shareIssueId = calculateAssetId(shareIssue) |
---|
336 | | - | let baseEntry = [StringEntry(keyVersion, version), BooleanEntry(keyActive, true), StringEntry(keyAssetIdA, pmtStrAssetIdA), StringEntry(keyAssetIdB, pmtStrAssetIdB), IntegerEntry(keyBalanceInitA, amtAssetA), IntegerEntry(keyBalanceInitB, amtAssetB), IntegerEntry(keyBalanceA, 0), IntegerEntry(keyBalanceB, 0), IntegerEntry(keyCommission, commission), IntegerEntry(keyCommissionScaleDelimiter, commissionScaleDelimiter), shareIssue, StringEntry(keyShareAssetId, toBase58String(shareIssueId)), IntegerEntry(keyShareAssetSupply, shareInitialSupply)] |
---|
337 | | - | if (firstHarvest) |
---|
338 | | - | then (baseEntry ++ [BooleanEntry(keyFirstHarvest, firstHarvest), IntegerEntry(keyFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))]) |
---|
339 | | - | else baseEntry |
---|
340 | | - | } |
---|
341 | | - | } |
---|
342 | | - | |
---|
343 | | - | |
---|
344 | | - | |
---|
345 | | - | @Callable(i) |
---|
346 | | - | func keepLimitForFirstHarvest (shareLimit) = if (!(isActive)) |
---|
347 | | - | then throw("DApp is inactive at this moment") |
---|
348 | | - | else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey))) |
---|
349 | | - | then throw("Only admin can call this function") |
---|
350 | | - | else [IntegerEntry(kShareLimit, shareLimit)] |
---|
351 | | - | |
---|
352 | | - | |
---|
353 | | - | |
---|
354 | | - | @Callable(i) |
---|
355 | | - | func replenishWithTwoTokens (slippageTolerance) = { |
---|
356 | | - | let pmtAssetIdA = i.payments[0].assetId |
---|
357 | | - | let pmtAssetIdB = i.payments[1].assetId |
---|
358 | | - | let pmtAmountA = deductStakingFee(i.payments[0].amount, pmtAssetIdA, pmtAssetIdB) |
---|
359 | | - | let pmtAmountB = deductStakingFee(i.payments[1].amount, pmtAssetIdB, pmtAssetIdA) |
---|
360 | | - | if (if ((balanceA == 0)) |
---|
361 | | - | then (balanceB == 0) |
---|
362 | | - | else false) |
---|
| 34 | + | 2(1(1(1(1(1($acc0, 0), 1), 2), 3), 4), 5) |
---|
| 35 | + | } |
---|
| 36 | + | if ((routing == routingSize)) |
---|
364 | | - | let $t01346913546 = getAssetInfo(pmtAssetIdA) |
---|
365 | | - | let pmtStrAssetIdA = $t01346913546._1 |
---|
366 | | - | let pmtAssetNameA = $t01346913546._2 |
---|
367 | | - | let pmtDecimalsA = $t01346913546._3 |
---|
368 | | - | let $t01355513632 = getAssetInfo(pmtAssetIdB) |
---|
369 | | - | let pmtStrAssetIdB = $t01355513632._1 |
---|
370 | | - | let pmtAssetNameB = $t01355513632._2 |
---|
371 | | - | let pmtDecimalsB = $t01355513632._3 |
---|
372 | | - | let tokenRatio = fraction(fraction(assetInitA, scaleValue8, pmtAmountA), scaleValue3, fraction(assetInitB, scaleValue8, pmtAmountB)) |
---|
373 | | - | if ((pmtAssetIdA == pmtAssetIdB)) |
---|
374 | | - | then throw("Assets must be different") |
---|
375 | | - | else { |
---|
376 | | - | let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2) |
---|
377 | | - | let shareInitialSupply = fraction(pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN), pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN), pow(10, 0, shareDecimals, 0, 0, DOWN)) |
---|
378 | | - | if (!(isActive)) |
---|
379 | | - | then throw("DApp is inactive at this moment") |
---|
380 | | - | else if (if ((0 > slippageTolerance)) |
---|
381 | | - | then true |
---|
382 | | - | else (slippageTolerance > slippageToleranceDelimiter)) |
---|
383 | | - | then throw(((("Slippage tolerance must be between 0 and " + toString(slippageToleranceDelimiter)) + " inclusively. Actual: ") + toString(slippageTolerance))) |
---|
384 | | - | else if ((size(i.payments) != 2)) |
---|
385 | | - | then throw("Two attached assets expected") |
---|
386 | | - | else if (if ((((scaleValue3 * (slippageToleranceDelimiter - slippageTolerance)) / slippageToleranceDelimiter) > tokenRatio)) |
---|
387 | | - | then true |
---|
388 | | - | else (tokenRatio > ((scaleValue3 * (slippageToleranceDelimiter + slippageTolerance)) / slippageToleranceDelimiter))) |
---|
389 | | - | then throw("Incorrect assets amount: amounts must have the contract ratio") |
---|
390 | | - | else if (if ((pmtAssetIdA != assetIdA)) |
---|
391 | | - | then true |
---|
392 | | - | else (pmtAssetIdB != assetIdB)) |
---|
393 | | - | then throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB)) |
---|
394 | | - | else if ((shareInitialSupply == 0)) |
---|
395 | | - | then throw("Too small amount to replenish") |
---|
396 | | - | else if (!(hasEnoughBalance)) |
---|
397 | | - | then ([ScriptTransfer(i.caller, pmtAmountA, pmtAssetIdA), ScriptTransfer(i.caller, pmtAmountB, pmtAssetIdB)] ++ suspendSuspicious()) |
---|
398 | | - | else [Reissue(shareAssetId, shareInitialSupply, true), IntegerEntry(keyBalanceA, pmtAmountA), IntegerEntry(keyBalanceB, pmtAmountB), IntegerEntry(keyShareAssetSupply, shareInitialSupply), ScriptTransfer(i.caller, shareInitialSupply, shareAssetId)] |
---|
399 | | - | } |
---|
| 38 | + | let ammountToRecieve = assetBalance(this, assetPay[-1]) |
---|
| 39 | + | [ScriptTransfer(i.caller, ammountToRecieve, assetPay[-1])] |
---|
401 | | - | else { |
---|
402 | | - | let tokenRatio = fraction(fraction(balanceA, scaleValue8, pmtAmountA), scaleValue3, fraction(balanceB, scaleValue8, pmtAmountB)) |
---|
403 | | - | let ratioShareTokensInA = fraction(pmtAmountA, scaleValue8, balanceA) |
---|
404 | | - | let ratioShareTokensInB = fraction(pmtAmountB, scaleValue8, balanceB) |
---|
405 | | - | let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scaleValue8) |
---|
406 | | - | if (!(isActive)) |
---|
407 | | - | then throw("DApp is inactive at this moment") |
---|
408 | | - | else if (if ((0 > slippageTolerance)) |
---|
409 | | - | then true |
---|
410 | | - | else (slippageTolerance > slippageToleranceDelimiter)) |
---|
411 | | - | then throw(((("Slippage tolerance must be between 0 and " + toString(slippageToleranceDelimiter)) + " inclusively. Actual: ") + toString(slippageTolerance))) |
---|
412 | | - | else if ((size(i.payments) != 2)) |
---|
413 | | - | then throw("Two attached assets expected") |
---|
414 | | - | else if (if ((pmtAssetIdA != assetIdA)) |
---|
415 | | - | then true |
---|
416 | | - | else (pmtAssetIdB != assetIdB)) |
---|
417 | | - | then throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB)) |
---|
418 | | - | else if (if ((((scaleValue3 * (slippageToleranceDelimiter - slippageTolerance)) / slippageToleranceDelimiter) > tokenRatio)) |
---|
419 | | - | then true |
---|
420 | | - | else (tokenRatio > ((scaleValue3 * (slippageToleranceDelimiter + slippageTolerance)) / slippageToleranceDelimiter))) |
---|
421 | | - | then throw("Incorrect assets amount: amounts must have the contract ratio") |
---|
422 | | - | else if ((shareTokenToPayAmount == 0)) |
---|
423 | | - | then throw("Too small amount to replenish") |
---|
424 | | - | else if (!(hasEnoughBalance)) |
---|
425 | | - | then ([ScriptTransfer(i.caller, pmtAmountA, pmtAssetIdA), ScriptTransfer(i.caller, pmtAmountB, pmtAssetIdB)] ++ suspendSuspicious()) |
---|
426 | | - | else [IntegerEntry(keyBalanceA, (balanceA + pmtAmountA)), IntegerEntry(keyBalanceB, (balanceB + pmtAmountB)), IntegerEntry(keyShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId)] |
---|
427 | | - | } |
---|
428 | | - | } |
---|
429 | | - | |
---|
430 | | - | |
---|
431 | | - | |
---|
432 | | - | @Callable(i) |
---|
433 | | - | func withdraw () = { |
---|
434 | | - | let $t01803118181 = $Tuple2(i.payments[0].amount, i.payments[0].assetId) |
---|
435 | | - | let pmtAmount = $t01803118181._1 |
---|
436 | | - | let pmtAssetId = $t01803118181._2 |
---|
437 | | - | let amountToPayA = deductStakingFee(fraction(pmtAmount, balanceA, shareAssetSupply), assetIdA, assetIdB) |
---|
438 | | - | let amountToPayB = deductStakingFee(fraction(pmtAmount, balanceB, shareAssetSupply), assetIdB, assetIdA) |
---|
439 | | - | if (!(isActive)) |
---|
440 | | - | then throw("DApp is inactive at this moment") |
---|
441 | | - | else if ((size(i.payments) != 1)) |
---|
442 | | - | then throw("One attached payment expected") |
---|
443 | | - | else if ((pmtAssetId != shareAssetId)) |
---|
444 | | - | then throw(("Incorrect asset attached. Expected: " + toBase58String(shareAssetId))) |
---|
445 | | - | else if (!(hasEnoughBalance)) |
---|
446 | | - | then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious()) |
---|
447 | | - | else if (if ((amountToPayA > availableBalanceA)) |
---|
448 | | - | then true |
---|
449 | | - | else (amountToPayB > availableBalanceB)) |
---|
450 | | - | then throwInsufficientAvailableBalances(amountToPayA, amountToPayB) |
---|
451 | | - | else [IntegerEntry(keyBalanceA, (balanceA - amountToPayA)), IntegerEntry(keyBalanceB, (balanceB - amountToPayB)), IntegerEntry(keyShareAssetSupply, (shareAssetSupply - pmtAmount)), Burn(shareAssetId, pmtAmount), ScriptTransfer(i.caller, amountToPayA, assetIdA), ScriptTransfer(i.caller, amountToPayB, assetIdB)] |
---|
452 | | - | } |
---|
453 | | - | |
---|
454 | | - | |
---|
455 | | - | |
---|
456 | | - | @Callable(i) |
---|
457 | | - | func exchange (minAmountToReceive) = { |
---|
458 | | - | let $t01940719482 = $Tuple2(i.payments[0].amount, i.payments[0].assetId) |
---|
459 | | - | let pmtAmount = $t01940719482._1 |
---|
460 | | - | let pmtAssetId = $t01940719482._2 |
---|
461 | | - | func calculateFees (tokenFrom,tokenTo) = { |
---|
462 | | - | let amountWithoutFee = fraction(tokenTo, pmtAmount, (pmtAmount + tokenFrom)) |
---|
463 | | - | let amountWithFee = fraction(amountWithoutFee, (commissionScaleDelimiter - commission), commissionScaleDelimiter) |
---|
464 | | - | let governanceReward = fraction(amountWithoutFee, commissionGovernance, commissionScaleDelimiter) |
---|
465 | | - | if ((minAmountToReceive > amountWithFee)) |
---|
466 | | - | then throw(((("Calculated amount to receive " + toString(amountWithFee)) + " is less than specified minimum ") + toString(minAmountToReceive))) |
---|
467 | | - | else $Tuple3(amountWithoutFee, amountWithFee, governanceReward) |
---|
468 | | - | } |
---|
469 | | - | |
---|
470 | | - | if (!(isActive)) |
---|
471 | | - | then throw("DApp is inactive at this moment") |
---|
472 | | - | else if (if ((balanceA == 0)) |
---|
473 | | - | then true |
---|
474 | | - | else (balanceB == 0)) |
---|
475 | | - | then throw("Can't exchange with zero balance") |
---|
476 | | - | else if ((0 >= minAmountToReceive)) |
---|
477 | | - | then throw(("Minimal amount to receive must be positive. Actual: " + toString(minAmountToReceive))) |
---|
478 | | - | else if ((size(i.payments) != 1)) |
---|
479 | | - | then throw("One attached payment expected") |
---|
480 | | - | else if (!(hasEnoughBalance)) |
---|
481 | | - | then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious()) |
---|
482 | | - | else if ((pmtAssetId == assetIdA)) |
---|
483 | | - | then { |
---|
484 | | - | let assetIdSend = assetIdB |
---|
485 | | - | let $t02075620847 = calculateFees(balanceA, balanceB) |
---|
486 | | - | let amountWithoutFee = $t02075620847._1 |
---|
487 | | - | let amountWithFee = $t02075620847._2 |
---|
488 | | - | let governanceReward = $t02075620847._3 |
---|
489 | | - | let newBalanceA = (balanceA + pmtAmount) |
---|
490 | | - | let newBalanceB = ((balanceB - amountWithFee) - governanceReward) |
---|
491 | | - | if (if ((stakedAmountA >= newBalanceA)) |
---|
492 | | - | then true |
---|
493 | | - | else (stakedAmountB >= newBalanceB)) |
---|
494 | | - | then throwInsufficientAvailableBalance(amountWithFee, availableBalanceB, assetNameB) |
---|
495 | | - | else [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(walletAddress, governanceReward, assetIdSend)] |
---|
496 | | - | } |
---|
497 | | - | else if ((pmtAssetId == assetIdB)) |
---|
498 | | - | then { |
---|
499 | | - | let assetIdSend = assetIdA |
---|
500 | | - | let $t02166621757 = calculateFees(balanceB, balanceA) |
---|
501 | | - | let amountWithoutFee = $t02166621757._1 |
---|
502 | | - | let amountWithFee = $t02166621757._2 |
---|
503 | | - | let governanceReward = $t02166621757._3 |
---|
504 | | - | let newBalanceA = ((balanceA - amountWithFee) - governanceReward) |
---|
505 | | - | let newBalanceB = (balanceB + pmtAmount) |
---|
506 | | - | if (if ((stakedAmountA >= newBalanceA)) |
---|
507 | | - | then true |
---|
508 | | - | else (stakedAmountB >= newBalanceB)) |
---|
509 | | - | then throwInsufficientAvailableBalance(amountWithFee, availableBalanceA, assetNameA) |
---|
510 | | - | else [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(walletAddress, governanceReward, assetIdSend)] |
---|
511 | | - | } |
---|
512 | | - | else throw(((("Incorrect asset attached. Expected: " + strAssetIdA) + " or ") + strAssetIdB)) |
---|
513 | | - | } |
---|
514 | | - | |
---|
515 | | - | |
---|
516 | | - | |
---|
517 | | - | @Callable(i) |
---|
518 | | - | func shutdown () = if (!(isActive)) |
---|
519 | | - | then throw(("DApp is already suspended. Cause: " + valueOrElse(getString(this, keyCause), "the cause wasn't specified"))) |
---|
520 | | - | else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStartStop], i.callerPublicKey))) |
---|
521 | | - | then throw("Only admin can call this function") |
---|
522 | | - | else suspend("Paused by admin") |
---|
523 | | - | |
---|
524 | | - | |
---|
525 | | - | |
---|
526 | | - | @Callable(i) |
---|
527 | | - | func activate () = if (isActive) |
---|
528 | | - | then throw("DApp is already active") |
---|
529 | | - | else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStartStop], i.callerPublicKey))) |
---|
530 | | - | then throw("Only admin can call this function") |
---|
531 | | - | else [BooleanEntry(keyActive, true), DeleteEntry(keyCause)] |
---|
532 | | - | |
---|
533 | | - | |
---|
534 | | - | |
---|
535 | | - | @Callable(i) |
---|
536 | | - | func takeIntoAccountExtraFunds (amountLeave) = { |
---|
537 | | - | let uncountableAmountEnrollAssetA = (accountBalanceWithStakedA - balanceA) |
---|
538 | | - | let uncountableAmountEnrollAssetB = (accountBalanceWithStakedB - balanceB) |
---|
539 | | - | let amountEnrollA = (uncountableAmountEnrollAssetA - (if ((assetIdA == unit)) |
---|
540 | | - | then amountLeave |
---|
541 | | - | else 0)) |
---|
542 | | - | let amountEnrollB = (uncountableAmountEnrollAssetB - (if ((assetIdB == unit)) |
---|
543 | | - | then amountLeave |
---|
544 | | - | else 0)) |
---|
545 | | - | if (!(isActive)) |
---|
546 | | - | then throw("DApp is inactive at this moment") |
---|
547 | | - | else if ((i.caller != this)) |
---|
548 | | - | then throw("Only the DApp itself can call this function") |
---|
549 | | - | else if ((0 > amountLeave)) |
---|
550 | | - | then throw(("Argument 'amountLeave' cannot be negative. Actual: " + toString(amountLeave))) |
---|
551 | | - | else if (if ((0 > uncountableAmountEnrollAssetA)) |
---|
552 | | - | then true |
---|
553 | | - | else (0 > uncountableAmountEnrollAssetB)) |
---|
554 | | - | then suspend("Enroll amount negative") |
---|
555 | | - | else if (if ((0 > amountEnrollA)) |
---|
556 | | - | then true |
---|
557 | | - | else (0 > amountEnrollB)) |
---|
558 | | - | then throw("Too large amountLeave") |
---|
559 | | - | else [IntegerEntry(keyBalanceA, (balanceA + amountEnrollA)), IntegerEntry(keyBalanceB, (balanceB + amountEnrollB)), IntegerEntry(("last_income_" + strAssetIdA), amountEnrollA), IntegerEntry(("last_income_" + strAssetIdB), amountEnrollB)] |
---|
| 41 | + | else nil |
---|