Guest User

Untitled

a guest
Sep 24th, 2018
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.40 KB | None | 0 0
  1. let NetworkProxy = artifacts.require("./KyberNetworkProxy.sol");
  2. let ConversionRates = artifacts.require("./mockContracts/MockConversionRate.sol");
  3. let TestToken = artifacts.require("./mockContracts/TestToken.sol");
  4. let Reserve = artifacts.require("./KyberReserve.sol");
  5. let Network = artifacts.require("./KyberNetwork.sol");
  6. let WhiteList = artifacts.require("./WhiteList.sol");
  7. let ExpectedRate = artifacts.require("./ExpectedRate.sol");
  8. let FeeBurner = artifacts.require("./FeeBurner.sol");
  9.  
  10. let Helper = require("./helper.js");
  11. let BigNumber = require('bignumber.js');
  12.  
  13. // Global Variables
  14. let precisionUnits = (new BigNumber(10).pow(18));
  15. let ethAddress = '0x00eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee';
  16. let gasPrice = (new BigNumber(10).pow(9).mul(50));
  17. let negligibleRateDiff = 11;
  18.  
  19. // Balances
  20. let expectedReserveBalanceWei = 0;
  21. let reserveTokenBalance = [];
  22. let reserveTokenImbalance = [];
  23. let reserveStartTokenBalance = [];
  24.  
  25. //permission groups
  26. let admin;
  27. let operator;
  28. let user;
  29. let walletId;
  30.  
  31. // Contracts
  32. let conversionRates; // Previously pricing2
  33. let reserve; // Previously reserve2
  34. let whiteList;
  35. let expectedRate;
  36. let network;
  37. let networkProxy;
  38. let feeBurner;
  39.  
  40. // Block data
  41. let priceUpdateBlock;
  42. let currentBlock;
  43. let validRateDurationInBlocks = 5100;
  44.  
  45. // Token data
  46. let numTokens = 2;
  47. let tokens = [];
  48. let tokenAddress = [];
  49. let tokenDecimals = [];
  50.  
  51. // imbalance data
  52. let minimalRecordResolution = 2; // low resolution so I don't lose too much data. then easier to compare calculated imbalance values.
  53. let maxPerBlockImbalance = 4000;
  54. let maxTotalImbalance = maxPerBlockImbalance * 12;
  55.  
  56. // all price steps in bps (basic price steps).
  57. // 100 bps means rate change will be: price * (100 + 10000) / 10000 == raise rate in 1%
  58. // higher rate is better for user. will get more dst quantity for his tokens.
  59. // all x values represent token imbalance. y values represent equivalent steps in bps.
  60. // buyImbalance represents coin shortage. higher buy imbalance = more tokens were bought.
  61. // generally. speaking, if imbalance is higher we want to have:
  62. // - smaller buy bps (negative) to lower rate when buying token with ether.
  63. // - bigger sell bps to have higher rate when buying ether with token.
  64. ////////////////////
  65.  
  66. //base buy and sell rates (prices)
  67. let baseBuyRate1 = [];
  68. let baseBuyRate2 = [];
  69. let baseSellRate1 = [];
  70. let baseSellRate2 = [];
  71.  
  72. //quantity buy steps
  73. let qtyBuyStepX = [0, 150, 350, 700, 1400];
  74. let qtyBuyStepY = [0, 0, -70, -160, -3000];
  75.  
  76. //imbalance buy steps
  77. let imbalanceBuyStepX = [-8500, -2800, -1500, 0, 1500, 2800, 4500];
  78. let imbalanceBuyStepY = [ 1300, 130, 43, 0, 0, -110, -1600];
  79.  
  80. //sell
  81. //sell price will be 1 / buy (assuming no spread) so sell is actually buy price in other direction
  82. let qtySellStepX = [0, 150, 350, 700, 1400];
  83. let qtySellStepY = [0, 0, 120, 170, 3000];
  84.  
  85. //sell imbalance step
  86. let imbalanceSellStepX = [-8500, -2800, -1500, 0, 1500, 2800, 4500];
  87. let imbalanceSellStepY = [-1500, -320, -75, 0, 0, 110, 650];
  88.  
  89. //compact data.
  90. let sells = [];
  91. let buys = [];
  92. let indices = [];
  93. let compactBuyArr = [];
  94. let compactSellArr = [];
  95.  
  96.  
  97. contract('KyberNetworkProxy', function(accounts) {
  98. it("Set Accounts, deploy ConversionRates, Tokens, and enable tokens for trade with basic data per token.", async function () {
  99. // set account addresses
  100. admin = accounts[0];
  101. operator = accounts[1];
  102. user = accounts[3];
  103. walletId = accounts[4];
  104.  
  105. currentBlock = priceUpdateBlock = await Helper.getCurrentBlock();
  106.  
  107. // Initialize ConversionRates contract
  108. conversionRates = await ConversionRates.new(admin, {});
  109.  
  110. // Deploy tokens and add to ConversionRates
  111. for (let i = 0; i < numTokens; ++i) {
  112. tokenDecimals[i] = 15 * 1 + 1 * i;
  113. token = await TestToken.new("Token " + i, "TOKEN_ " + i, tokenDecimals[i]);
  114. tokens[i] = token;
  115. tokenAddress[i] = token.address;
  116.  
  117. await conversionRates.addToken(token.address);
  118. await conversionRates.setTokenControlInfo(
  119. token.address,
  120. minimalRecordResolution,
  121. maxPerBlockImbalance,
  122. maxTotalImbalance
  123. );
  124. await conversionRates.enableTokenTrade(token.address);
  125. }
  126.  
  127. assert.equal(tokens.length, numTokens, "Invalid number of tokens");
  128.  
  129. await conversionRates.addOperator(operator);
  130. });
  131.  
  132. it("Set base rates, compact data rate factor, and step function for all tokens.", async function () {
  133. // buy is ether to token rate. sale is token to ether rate. so sell == 1 / buy. assuming we have no spread.
  134. let tokensPerEther;
  135. let ethersPerToken;
  136.  
  137. for (i = 0; i < numTokens; ++i) {
  138. tokensPerEther = (new BigNumber(precisionUnits.mul((i + 1) * 3)).floor());
  139. ethersPerToken = (new BigNumber(precisionUnits.div((i + 1) * 3)).floor());
  140. baseBuyRate1.push(tokensPerEther.valueOf());
  141. baseBuyRate2.push(tokensPerEther.valueOf() * 10100 / 10000);
  142. baseSellRate1.push(ethersPerToken.valueOf());
  143. baseSellRate2.push(ethersPerToken.div(1000).mul(980));
  144. }
  145.  
  146. assert.equal(baseBuyRate1.length, tokens.length);
  147. assert.equal(baseBuyRate2.length, tokens.length);
  148. assert.equal(baseSellRate1.length, tokens.length);
  149. assert.equal(baseSellRate2.length, tokens.length);
  150.  
  151. buys.length = sells.length = indices.length = 0;
  152.  
  153. await conversionRates.setBaseRate(tokenAddress, baseBuyRate2, baseSellRate2, buys, sells, currentBlock, indices, {from: operator});
  154.  
  155. // Set compact data
  156. compactBuyArr = [0, 0, 0, 0, 0, 06, 07, 08, 09, 1, 0, 11, 12, 13, 14];
  157. let compactBuyHex = Helper.bytesToHex(compactBuyArr);
  158. buys.push(compactBuyHex);
  159.  
  160. compactSellArr = [0, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34];
  161. let compactSellHex = Helper.bytesToHex(compactSellArr);
  162. sells.push(compactSellHex);
  163.  
  164. indices[0] = 0;
  165.  
  166. assert.equal(indices.length, sells.length, "bad sells array size");
  167. assert.equal(indices.length, buys.length, "bad buys array size");
  168.  
  169. await conversionRates.setCompactData(buys, sells, currentBlock, indices, {from: operator});
  170.  
  171. // Set pricing step functions
  172. let zeroArr = [0];
  173. for (let i = 0; i < numTokens; ++i) {
  174. await conversionRates.setQtyStepFunction(
  175. tokenAddress[i],
  176. qtyBuyStepX,
  177. qtyBuyStepY,
  178. qtySellStepX,
  179. qtySellStepY,
  180. { from: operator }
  181. );
  182.  
  183. await conversionRates.setImbalanceStepFunction(
  184. tokenAddress[i],
  185. imbalanceBuyStepX,
  186. imbalanceBuyStepY,
  187. imbalanceSellStepX,
  188. imbalanceSellStepY,
  189. { from: operator }
  190. );
  191. }
  192. });
  193.  
  194. it("Deploy Network and Reserve Contract and set Reserve data including balances.", async function () {
  195. network = await Network.new(admin);
  196. await network.addOperator(operator);
  197.  
  198. reserve = await Reserve.new(network.address, conversionRates.address, admin);
  199. await conversionRates.setReserveAddress(reserve.address);
  200.  
  201. for (i = 0; i < numTokens; ++i) {
  202. await reserve.approveWithdrawAddress(tokenAddress[i], accounts[0], true);
  203. }
  204.  
  205. // Set reserve balance: 10 ** 18 wei ether + per token 10**18 wei ether value according to base rate.
  206. let reserveEtherInit = (new BigNumber(10)).pow(19);
  207. await Helper.sendEtherWithPromise(accounts[9], reserve.address, reserveEtherInit);
  208.  
  209. // Transfer tokens to the reserve, each token same wei balance
  210. for (let i = 0; i < numTokens; ++i) {
  211. token = tokens[i];
  212.  
  213. let amount2 = (new BigNumber(reserveEtherInit)).div(precisionUnits).mul(baseBuyRate2[i]).floor();
  214. reserveStartTokenBalance[i] = amount2
  215. await token.transfer(reserve.address, amount2.valueOf());
  216.  
  217. reserveTokenBalance.push(amount2);
  218. reserveTokenImbalance.push(0);
  219. }
  220. });
  221.  
  222. it("Deploy KyberNetworkProxy, Fee Burner, Genesis Token, Whitelist, Expected Rate, and list token pairs.", async function () {
  223. // Authorize reserves
  224. await network.addReserve(reserve.address, true);
  225. networkProxy = await NetworkProxy.new(admin);
  226. await network.setKyberProxy(networkProxy.address);
  227. await networkProxy.setKyberNetworkContract(network.address);
  228.  
  229. // Set contracts
  230. feeBurner = await FeeBurner.new(admin, tokenAddress[0], network.address);
  231.  
  232. let kgtToken = await TestToken.new("Kyber Genesis Token", "KGT", 0);
  233. whiteList = await WhiteList.new(admin, kgtToken.address);
  234. await whiteList.addOperator(operator);
  235. await whiteList.setCategoryCap(0, 1000, { from: operator });
  236. await whiteList.setSgdToEthRate(30000, { from: operator });
  237.  
  238. expectedRate = await ExpectedRate.new(network.address, admin);
  239. await network.setWhiteList(whiteList.address);
  240. await network.setExpectedRate(expectedRate.address);
  241. await network.setFeeBurner(feeBurner.address);
  242. await network.setParams(gasPrice.valueOf(), negligibleRateDiff);
  243. await network.setEnable(true);
  244.  
  245. let price = await network.maxGasPrice();
  246. assert.equal(price.valueOf(), gasPrice.valueOf());
  247.  
  248. // List tokens per reserve
  249. for (let i = 0; i < numTokens; i++) {
  250. await network.listPairForReserve(
  251. reserve.address,
  252. tokenAddress[i],
  253. true,
  254. true,
  255. true
  256. );
  257. }
  258. });
  259.  
  260. it("Swaps an ERC20 token for another ERC20 token.", async function () {
  261. let sourceTokenIndex = 1;
  262. let destinationTokenIndex = 0;
  263. let sourceToken = tokens[sourceTokenIndex];
  264. let destinationToken = tokens[destinationTokenIndex];
  265. let sourceAmountTwei = 1450 * 1;
  266. let maxDestAmount = (new BigNumber(10)).pow(18);
  267.  
  268. // Reset max imbalance values for working with higher numbers
  269. buys.length = sells.length = indices.length = 0;
  270.  
  271. // Set compact data
  272. compactBuyArr = [0, 0, 0, 0, 0, 06, 07, 08, 09, 10, 11, 12, 13, 14];
  273. let compactBuyHex = Helper.bytesToHex(compactBuyArr);
  274. buys.push(compactBuyHex);
  275.  
  276. compactSellArr = [0, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34];
  277. let compactSellHex = Helper.bytesToHex(compactSellArr);
  278. sells.push(compactSellHex);
  279.  
  280. indices[0] = 0;
  281. currentBlock = await Helper.getCurrentBlock();
  282. await conversionRates.setBaseRate(
  283. tokenAddress,
  284. baseBuyRate2,
  285. baseSellRate2,
  286. buys,
  287. sells,
  288. currentBlock,
  289. indices,
  290. { from: operator }
  291. );
  292.  
  293. priceUpdateBlock = currentBlock;
  294.  
  295. maxPerBlockImbalance = 60000000;
  296. maxTotalImbalance = 12 * maxPerBlockImbalance;
  297.  
  298. // Set higher imbalance values and set local imbalance values to 0 since we update compact data
  299. for (let i = 0; i < numTokens; ++i) {
  300. await conversionRates.setTokenControlInfo(
  301. tokenAddress[i],
  302. minimalRecordResolution,
  303. maxPerBlockImbalance,
  304. maxTotalImbalance
  305. );
  306.  
  307. // Update balance in imbalance values
  308. reserveTokenBalance[i] = new BigNumber(await tokens[i].balanceOf(reserve.address));
  309. reserveTokenImbalance[i] = new BigNumber(0);
  310. }
  311.  
  312. try {
  313. // Verify base rate
  314. let buyRate = await networkProxy.getExpectedRate(
  315. tokenAddress[sourceTokenIndex],
  316. tokenAddress[destinationTokenIndex],
  317. sourceAmountTwei
  318. );
  319.  
  320. // First Token to Eth rate
  321. let expected = calculateRateAmount(false, sourceTokenIndex, sourceAmountTwei, 2);
  322. let expectedSellRate = expected[0];
  323. let expectedEthQtyWei = expected[1];
  324.  
  325. // Eth to Token rate
  326. expected = calculateRateAmount(true, destinationTokenIndex, expectedEthQtyWei, 2);
  327. let expectedBuyRate = expected[0];
  328. expectedDestTokensTwei = expected[1];
  329.  
  330. // Calculate combined rate
  331. let combinedRate = calcCombinedRate(
  332. sourceAmountTwei,
  333. expectedSellRate,
  334. expectedBuyRate,
  335. tokenDecimals[sourceTokenIndex],
  336. tokenDecimals[destinationTokenIndex],
  337. expectedDestTokensTwei
  338. );
  339.  
  340. // Check correct rate calculated
  341. assert.equal(buyRate[0].valueOf(), combinedRate.valueOf(), "Unexpected Combined Rate.");
  342.  
  343. //
  344. // Perform trade
  345. //
  346.  
  347. // REQUIRED: Transfer funds to user (issuance order maker)
  348. await sourceToken.transfer(user, sourceAmountTwei);
  349.  
  350. // REQUIRED: Approve funds to network for all trades
  351. // await sourceToken.approve(
  352. // networkProxy.address,
  353. // sourceAmountTwei,
  354. // { from: user }
  355. // );
  356.  
  357. let startBalanceDestinationTokenUser = await destinationToken.balanceOf(user);
  358. let startBalanceSourceTokenUser = await sourceToken.balanceOf(user);
  359.  
  360. let destinationTokenuserExistingBalance = await destinationToken.balanceOf(user);
  361. console.log(destinationTokenuserExistingBalance.valueOf());
  362.  
  363. //
  364. // REQUIRED: Trade
  365. //
  366.  
  367. // let result = await networkProxy.trade(
  368. // tokenAddress[sourceTokenIndex], // sourceToken
  369. // sourceAmountTwei, // sourceTokenAmount
  370. // tokenAddress[destinationTokenIndex], // destinationToken
  371. // user, // destinationAddress
  372. // maxDestAmount, // maxDestAmount
  373. // buyRate[1].valueOf(), // minConversionRate
  374. // walletId, // walletId
  375. // { from: user }
  376. // );
  377.  
  378. // Update Balance and Imbalance
  379. reserveTokenBalance[sourceTokenIndex] = (reserveTokenBalance[sourceTokenIndex]).add(sourceAmountTwei);
  380. reserveTokenImbalance[sourceTokenIndex] = reserveTokenImbalance[sourceTokenIndex].sub(sourceAmountTwei);
  381. reserveTokenBalance[destinationTokenIndex] = reserveTokenBalance[destinationTokenIndex].sub(expectedDestTokensTwei);
  382. reserveTokenImbalance[destinationTokenIndex] = reserveTokenImbalance[destinationTokenIndex].add(expectedDestTokensTwei); //more missing tokens
  383.  
  384. //
  385. // Check token balances
  386. //
  387.  
  388. // Check higher destinationToken balance on user
  389. // let rate = new BigNumber(buyRate[0].valueOf());
  390. // let destinationTokenUserBalance = await destinationToken.balanceOf(user);
  391. // let expectedBalancedestinationTokenuser = startBalanceDestinationTokenUser.add(expectedDestTokensTwei);
  392. // assert.equal(expectedBalancedestinationTokenuser.valueOf(), destinationTokenUserBalance.valueOf(), "bad token balance");
  393.  
  394. // Check lower sourceToken balance on user
  395. // let sourceTokenUserBalance = await sourceToken.balanceOf(user);
  396. // let expectedBalancesourceTokenUser = startBalanceSourceTokenUser.sub(sourceAmountTwei);
  397. // assert.equal(sourceTokenUserBalance.valueOf(), expectedBalancesourceTokenUser.valueOf(), "bad token balance");
  398.  
  399. // Check source token balance on reserve
  400. // reportedBalance = await sourceToken.balanceOf(reserve.address);
  401. // assert.equal(reportedBalance.valueOf(), reserveTokenBalance[sourceTokenIndex].valueOf(), "Invalid source token balance on reserve");
  402.  
  403. // Check destination token balance on reserve
  404. // reportedBalance = await destinationToken.balanceOf(reserve.address);
  405. // assert.equal(reportedBalance.valueOf(), reserveTokenBalance[destinationTokenIndex].valueOf(), "Invalid destination token balance on reserve");
  406.  
  407. // Print out contract addresses
  408. console.log("KyberNetworkProxy Address: ", networkProxy.address);
  409. console.log("Source Token Address: ", tokenAddress[sourceTokenIndex]);
  410. console.log("Destination Token Address: ", tokenAddress[destinationTokenIndex]);
  411. console.log("Buy Rate: ", buyRate[1].valueOf());
  412. console.log("Source Amount: ", sourceAmountTwei);
  413. console.log("Max Destination Amount: ", maxDestAmount);
  414. } catch(e) {
  415. throw(e);
  416. }
  417. });
  418. });
  419.  
  420. function convertRateToConversionRatesRate (baseRate) {
  421. // conversion rate in pricing is in precision units (10 ** 18) so
  422. // rate 1 to 50 is 50 * 10 ** 18
  423. // rate 50 to 1 is 1 / 50 * 10 ** 18 = 10 ** 18 / 50a
  424. return ((new BigNumber(10).pow(18)).mul(baseRate).floor());
  425. };
  426.  
  427. function getExtraBpsForBuyQuantity(qty) {
  428. for (let i = 0; i < qtyBuyStepX.length; i++) {
  429. if (qty <= qtyBuyStepX[i]) return qtyBuyStepY[i];
  430. }
  431. return qtyBuyStepY[qtyBuyStepY.length - 1];
  432. };
  433.  
  434. function getExtraBpsForSellQuantity(qty) {
  435. for (let i = 0; i < qtySellStepX.length; i++) {
  436. if (qty <= qtySellStepX[i]) return qtySellStepY[i];
  437. }
  438. return qtySellStepY[qtySellStepY.length - 1];
  439. };
  440.  
  441. function getExtraBpsForImbalanceBuyQuantity(qty) {
  442. for (let i = 0; i < imbalanceBuyStepX.length; i++) {
  443. if (qty <= imbalanceBuyStepX[i]) return imbalanceBuyStepY[i];
  444. }
  445. return (imbalanceBuyStepY[imbalanceBuyStepY.length - 1]);
  446. };
  447.  
  448. function getExtraBpsForImbalanceSellQuantity(qty) {
  449. for (let i = 0; i < imbalanceSellStepX.length; i++) {
  450. if (qty <= imbalanceSellStepX[i]) return imbalanceSellStepY[i];
  451. }
  452. return (imbalanceSellStepY[imbalanceSellStepY.length - 1]);
  453. };
  454.  
  455. function addBps (rate, bps) {
  456. return (rate.mul(10000 + bps).div(10000));
  457. };
  458.  
  459. function compareRates (receivedRate, expectedRate) {
  460. expectedRate = expectedRate - (expectedRate % 10);
  461. receivedRate = receivedRate - (receivedRate % 10);
  462. assert.equal(expectedRate, receivedRate, "different rates");
  463. };
  464.  
  465. function calculateRateAmount(isBuy, tokenInd, srcQty, reserveIndex, maxDestAmount) {
  466. let expectedRate;
  467. let expectedAmount;
  468. let baseArray;
  469. let imbalanceArray;
  470. let expected = [];
  471.  
  472. if (isBuy) {
  473. baseArray = baseBuyRate2;
  474. imbalanceArray = reserveTokenImbalance;
  475. } else {
  476. imbalanceArray = reserveTokenImbalance;
  477. baseArray = baseSellRate2;
  478. }
  479.  
  480. if (isBuy) {
  481. expectedRate = (new BigNumber(baseArray[tokenInd]));
  482. let dstQty = calcDstQty(srcQty, 18, tokenDecimals[tokenInd], expectedRate);
  483. let extraBps = getExtraBpsForBuyQuantity(dstQty);
  484. expectedRate = addBps(expectedRate, extraBps);
  485. let relevantImbalance = imbalanceArray[tokenInd] * 1 + dstQty * 1;
  486. extraBps = getExtraBpsForImbalanceBuyQuantity(relevantImbalance);
  487. expectedRate = addBps(expectedRate, extraBps);
  488. expectedAmount = calcDstQty(srcQty, 18, tokenDecimals[tokenInd], expectedRate);
  489. } else {
  490. expectedRate = (new BigNumber(baseArray[tokenInd]));
  491. let extraBps = getExtraBpsForSellQuantity(srcQty);
  492. expectedRate = addBps(expectedRate, extraBps);
  493. let relevantImbalance = imbalanceArray[tokenInd] - srcQty;
  494. extraBps = getExtraBpsForImbalanceSellQuantity(relevantImbalance.valueOf());
  495. expectedRate = addBps(expectedRate, extraBps);
  496. expectedAmount = calcDstQty(srcQty, tokenDecimals[tokenInd], 18, expectedRate);
  497. }
  498. expectedAmount = expectedAmount.floor();
  499. expectedRate = expectedRate.floor();
  500.  
  501. expected = [expectedRate, expectedAmount];
  502. return expected;
  503. }
  504.  
  505. function calcDstQty(srcQty, srcDecimals, dstDecimals, rate) {
  506. rate = new BigNumber(rate);
  507. if (dstDecimals >= srcDecimals) {
  508. let decimalDiff = (new BigNumber(10)).pow(dstDecimals - srcDecimals);
  509. return (rate.mul(srcQty).mul(decimalDiff).div(precisionUnits)).floor();
  510. } else {
  511. let decimalDiff = (new BigNumber(10)).pow(srcDecimals - dstDecimals);
  512. return (rate.mul(srcQty).div(decimalDiff.mul(precisionUnits))).floor();
  513. }
  514. }
  515.  
  516. function calcSrcQty(dstQty, srcDecimals, dstDecimals, rate) {
  517. //source quantity is rounded up. to avoid dest quantity being too low.
  518. let srcQty;
  519. let numerator;
  520. let denominator;
  521. if (srcDecimals >= dstDecimals) {
  522. numerator = precisionUnits.mul(dstQty).mul((new BigNumber(10)).pow(srcDecimals - dstDecimals));
  523. denominator = new BigNumber(rate);
  524. } else {
  525. numerator = precisionUnits.mul(dstQty);
  526. denominator = (new BigNumber(rate)).mul((new BigNumber(10)).pow(dstDecimals - srcDecimals));
  527. }
  528. srcQty = (numerator.add(denominator.sub(1))).div(denominator).floor(); //avoid rounding down errors
  529. return srcQty;
  530. }
  531.  
  532. function calcCombinedRate(srcQty, sellRate, buyRate, srcDecimals, dstDecimals, destQty) {
  533. let rate;
  534. if (false) {
  535. rate = (sellRate.mul(srcQty).div(precisionUnits).floor()).mul(buyRate).div(srcQty).floor();
  536. } else {
  537. if (dstDecimals >= srcDecimals) {
  538. rate = (precisionUnits.mul(destQty)).div(((new BigNumber(10)).pow(dstDecimals - srcDecimals)).mul(srcQty));
  539. } else {
  540. rate = (precisionUnits.mul(destQty).mul((new BigNumber(10)).pow(srcDecimals - dstDecimals))).div(srcQty);
  541. }
  542. }
  543. return rate.floor();
  544. }
  545.  
  546. function log (string) {
  547. console.log(string);
  548. };
Add Comment
Please, Sign In to add comment