From db6a40c75f9d1145dbca25328a265941007d16d2 Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" Date: Mon, 27 May 2019 14:03:29 +0100 Subject: [PATCH 1/6] =?UTF-8?q?Update=20rollup=20to=20the=20latest=20versi?= =?UTF-8?q?on=20=F0=9F=9A=80=20(#80)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(package): update rollup to version 1.12.4 * chore(package): update lockfile yarn.lock --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index a8d39874..cfdcb9a9 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "cross-env": "5.2", "eslint": "5.16.0", "mocha": "6.1.4", - "rollup": "1.12.3", + "rollup": "1.12.4", "rollup-plugin-node-builtins": "2.1.2", "rollup-plugin-node-globals": "1.4.0", "rollup-plugin-typescript2": "0.21.1", diff --git a/yarn.lock b/yarn.lock index d1d5fbac..be28aa92 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3515,10 +3515,10 @@ rollup-pluginutils@2.6.0, rollup-pluginutils@^2.3.1: estree-walker "^0.6.0" micromatch "^3.1.10" -rollup@1.12.3: - version "1.12.3" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-1.12.3.tgz#068b1957d5bebf6c0a758cfe42609b512add35a9" - integrity sha512-ueWhPijWN+GaPgD3l77hXih/gcDXmYph6sWeQegwBYtaqAE834e8u+MC2wT6FKIUsz1DBOyOXAQXUZB+rjWDoQ== +rollup@1.12.4: + version "1.12.4" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-1.12.4.tgz#f2cb825300cea6601f12a4c3d2f3918807b27403" + integrity sha512-sHg0F05oTMJzM592MWU8irsPx8LIFMKSCnEkcp6vp/gnj+oJ9GJEBW9hl8jUqy2L6Q2uUxFzPgvoExLbfuSODA== dependencies: "@types/estree" "0.0.39" "@types/node" "^12.0.2" From 897a06caf826b6456846dafeb7c746365dec6b47 Mon Sep 17 00:00:00 2001 From: Julia Ero Date: Thu, 30 May 2019 13:29:37 +0200 Subject: [PATCH 2/6] publish API documentation (#83) --- README.md | 2 +- generateDocs.sh | 22 ++++++ package.json | 9 ++- yarn.lock | 187 ++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 213 insertions(+), 7 deletions(-) create mode 100755 generateDocs.sh diff --git a/README.md b/README.md index 04bb78c0..7a684f86 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![Augmint](http://www.augmint.cc/android-chrome-192x192.png) +![Augmint](https://www.augmint.org/android-chrome-192x192.png) # Augmint - Stable Digital Tokens - Javascript Library (WIP) diff --git a/generateDocs.sh b/generateDocs.sh new file mode 100755 index 00000000..664569ef --- /dev/null +++ b/generateDocs.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +cat >./dist/sourcefile-map.json < Date: Wed, 5 Jun 2019 14:49:05 +0200 Subject: [PATCH 3/6] add toNumber to Wei (#85) --- src/units.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/units.ts b/src/units.ts index c2521763..61976aeb 100644 --- a/src/units.ts +++ b/src/units.ts @@ -125,6 +125,9 @@ export class Wei extends FixedPoint { return new Tokens(this.amount.mul(rate.amount).divRound(price.amount.mul(E12))); } + public toNumber(): number { + return this.amount.toNumber() / Wei.DIV_BN.toNumber() + } } export class Tokens extends FixedPoint { From dd890b114b4d17478225d26e562a14dc65a07809 Mon Sep 17 00:00:00 2001 From: Julia Ero Date: Sat, 8 Jun 2019 16:49:18 +0200 Subject: [PATCH 4/6] Market order matching estimates (#79) --- src/Exchange.ts | 65 ++++++++++++++++++++++++++++++++- src/units.ts | 7 +++- test/Exchange.simpleBuy.test.js | 65 +++++++++++++++++++++++++++++++++ test/LoanManager.test.js | 20 +--------- test/testHelpers/normalize.js | 21 +++++++++++ 5 files changed, 155 insertions(+), 23 deletions(-) create mode 100644 test/Exchange.simpleBuy.test.js create mode 100644 test/testHelpers/normalize.js diff --git a/src/Exchange.ts b/src/Exchange.ts index 5e9bc41e..38472fd1 100644 --- a/src/Exchange.ts +++ b/src/Exchange.ts @@ -10,6 +10,13 @@ import { Rates } from "./Rates"; import { Transaction } from "./Transaction"; import { Ratio, Tokens, Wei } from "./units"; +interface IMarketMatch { + filledTokens: Tokens; + filledEthers: Wei; + limitPrice?: Ratio; + averagePrice?: Ratio; +} + export class OrderBook { public static compareBuyOrders(o1: IBuyOrder, o2: IBuyOrder): number { @@ -22,6 +29,35 @@ export class OrderBook { return cmp !== 0 ? cmp : o1.id - o2.id; } + private static estimateMarketOrder(orders: T[], + tokens: Tokens, + rate: Tokens, + toTokens: (order: T) => Tokens): IMarketMatch { + const ret: IMarketMatch = { + filledTokens: Tokens.of(0), + filledEthers: Wei.of(0) + }; + + for (const order of orders) { + const remaining = tokens.sub(ret.filledTokens); + if (remaining.isZero()) { + break; + } + + const fillTokens: Tokens = Tokens.min(toTokens(order), remaining); + const fillEthers: Wei = fillTokens.toWeiAt(rate, order.price); + + ret.filledTokens = ret.filledTokens.add(fillTokens); + ret.filledEthers = ret.filledEthers.add(fillEthers); + ret.limitPrice = order.price; + } + if (ret.limitPrice) { + ret.averagePrice = rate.divToRatio(ret.filledTokens.toRate(ret.filledEthers)); + } + + return ret; + } + constructor(public buyOrders: IBuyOrder[], public sellOrders: ISellOrder[]) { buyOrders.sort(OrderBook.compareBuyOrders); sellOrders.sort(OrderBook.compareSellOrders); @@ -47,13 +83,16 @@ export class OrderBook { if (!this.hasMatchingOrders()) { return { buyIds, sellIds, gasEstimate: 0 }; } + const lowestSellPrice: Ratio = this.sellOrders[0].price; const highestBuyPrice: Ratio = this.buyOrders[0].price; const clone = o => Object.assign({}, o); - const buys: IBuyOrder[] = this.buyOrders.filter(o => o.price.gte(lowestSellPrice)).map(clone); + const buys: IBuyOrder[] = this.buyOrders + .filter(o => o.price.gte(lowestSellPrice)).map(clone); - const sells: ISellOrder[] = this.sellOrders.filter(o => o.price.lte(highestBuyPrice)).map(clone); + const sells: ISellOrder[] = this.sellOrders + .filter(o => o.price.lte(highestBuyPrice)).map(clone); let buyIdx: number = 0; let sellIdx: number = 0; @@ -98,6 +137,28 @@ export class OrderBook { return { buyIds, sellIds, gasEstimate }; } + + /** + * calculate price for n amount of token to buy + * @return {object} simple buy data { tokens, ethers, limitPrice, averagePrice } + * @param tokenAmount - amount of token to buy + * @param ethFiatRate - current rate + */ + public estimateMarketBuy(tokenAmount: Tokens, ethFiatRate: Tokens): IMarketMatch { + return OrderBook.estimateMarketOrder(this.sellOrders, tokenAmount, ethFiatRate, + order => order.amount); + } + + /** + * calculate price for n amount of token to sell + * @return {object} simple buy data { tokens, ethers, limitPrice, averagePrice } + * @param tokenAmount - amount of token to sell + * @param ethFiatRate - current rate + */ + public estimateMarketSell(tokenAmount: Tokens, ethFiatRate: Tokens): IMarketMatch { + return OrderBook.estimateMarketOrder(this.buyOrders, tokenAmount, ethFiatRate, + order => order.amount.toTokensAt(ethFiatRate, order.price)); + } } export interface IMatchingOrders { diff --git a/src/units.ts b/src/units.ts index 61976aeb..0b7c4bd8 100644 --- a/src/units.ts +++ b/src/units.ts @@ -40,6 +40,11 @@ abstract class FixedPoint { return this.create(ceilDiv(this.amount.mul(Ratio.DIV_BN), ratio.amount)); } + public divToRatio(other: this): Ratio { + this.check(other); + return new Ratio(this.amount.mul(Ratio.DIV_BN).divRound(other.amount)); + } + // // comparison // @@ -161,7 +166,6 @@ export class Tokens extends FixedPoint { this.check(ethers, Wei); return new Tokens(this.amount.mul(Wei.DIV_BN).divRound(ethers.amount)); } - } @@ -181,6 +185,5 @@ export class Ratio extends FixedPoint { public toNumber(): number { return this.amount.toNumber() / Ratio.DIV; } - } diff --git a/test/Exchange.simpleBuy.test.js b/test/Exchange.simpleBuy.test.js new file mode 100644 index 00000000..3069bea1 --- /dev/null +++ b/test/Exchange.simpleBuy.test.js @@ -0,0 +1,65 @@ +const { assert } = require("chai"); + +const { normalizeBN } = require("./testHelpers/normalize.js"); +const { Augmint, utils, Wei, Tokens, Ratio } = require("../dist/index.js"); +const loadEnv = require("./testHelpers/loadEnv.js"); +const OrderBook = Augmint.Exchange.OrderBook; + +const config = loadEnv(); + +if (config.LOG) { + utils.logger.level = config.LOG; +} + +const RATE = Tokens.of(400.00); + +describe("calculate market orders", () => { + it("should return matching info", () => { + const buyOrders = [ + { amount: Wei.of(0.0070), price: Ratio.of(1.2) }, + { amount: Wei.of(0.0094), price: Ratio.of(1) }, + { amount: Wei.of(0.0064), price: Ratio.of(0.7) } + ]; + + const sellOrders = [ + { amount: Tokens.of(1), price: Ratio.of(1.02) }, + { amount: Tokens.of(10), price: Ratio.of(1.03) } + ]; + + const orderBook = new OrderBook(buyOrders, sellOrders); + + const sellResult = { + filledTokens: Tokens.of(6), + filledEthers: Wei.of(0.016165), + limitPrice: Ratio.of(1), + averagePrice: Ratio.of(1.077673) + }; + + const sellMatches = orderBook.estimateMarketSell(Tokens.of(6), RATE); + + assert.deepEqual(normalizeBN(sellResult), normalizeBN(sellMatches)); + + const buyResult = { + filledTokens: Tokens.of(2), + filledEthers: Wei.of(0.005125), + limitPrice: Ratio.of(1.03), + averagePrice: Ratio.of(1.02501) + }; + + const buyMatches = orderBook.estimateMarketBuy(Tokens.of(2), RATE); + + assert.deepEqual(normalizeBN(buyMatches), normalizeBN(buyResult)); + }); + + it("should work on empty order book", () => { + const orderBook = new OrderBook([], []); + const exp = { + filledTokens: Tokens.of(0), + filledEthers: Wei.of(0) + }; + const buyMatches = orderBook.estimateMarketBuy(Tokens.of(100), RATE); + const sellMatches = orderBook.estimateMarketSell(Tokens.of(100), RATE) + assert.deepEqual(normalizeBN(buyMatches), normalizeBN(exp)); + assert.deepEqual(normalizeBN(sellMatches), normalizeBN(exp)); + }); +}); diff --git a/test/LoanManager.test.js b/test/LoanManager.test.js index a144ff2d..d9edc13b 100644 --- a/test/LoanManager.test.js +++ b/test/LoanManager.test.js @@ -2,11 +2,7 @@ const chai = require("chai"); const { assert, expect } = chai; chai.use(require("chai-exclude")); -const BN = require("bn.js"); -BN.prototype.inspect = function() { - return this.toString(); -}; - +const { normalizeBN } = require("./testHelpers/normalize.js"); const { takeSnapshot, revertSnapshot } = require("./testHelpers/ganache.js"); const { Augmint, utils, Wei, Tokens, Ratio } = require("../dist/index.js"); const { AugmintJsError } = Augmint.Errors; @@ -17,20 +13,6 @@ if (config.LOG) { utils.logger.level = config.LOG; } -// deeply normalize all BN properties so they can be compared with deepEquals -// NOTE: object graph must not have cycles -function normalizeBN(obj) { - Object.keys(obj).map((key, index) => { - const o = obj[key]; - if (o instanceof BN) { - obj[key] = new BN(o.toString()); - } else if (o instanceof Object) { - obj[key] = normalizeBN(o); - } - }); - return obj; -} - function mockProd( id, minDisbursedAmount, diff --git a/test/testHelpers/normalize.js b/test/testHelpers/normalize.js new file mode 100644 index 00000000..c19de8d3 --- /dev/null +++ b/test/testHelpers/normalize.js @@ -0,0 +1,21 @@ +const BN = require("bn.js"); + +BN.prototype.inspect = function() { + return this.toString(); +}; + +module.exports = { normalizeBN }; + +// deeply normalize all BN properties so they can be compared with deepEquals +// NOTE: object graph must not have cycles +function normalizeBN(obj) { + Object.keys(obj).map((key, index) => { + const o = obj[key]; + if (o instanceof BN) { + obj[key] = new BN(o.toString()); + } else if (o instanceof Object) { + obj[key] = normalizeBN(o); + } + }); + return obj; +} From d47880306f1a198ec5b4cf450f93f4545d319c19 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Sat, 8 Jun 2019 16:57:35 +0200 Subject: [PATCH 5/6] Bump fstream from 1.0.11 to 1.0.12 (#86) Bumps [fstream](https://github.com/npm/fstream) from 1.0.11 to 1.0.12. - [Release notes](https://github.com/npm/fstream/releases) - [Commits](https://github.com/npm/fstream/compare/v1.0.11...v1.0.12) Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 43fb901e..b89ce797 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1720,9 +1720,9 @@ fs.realpath@^1.0.0: integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= fstream@^1.0.2, fstream@^1.0.8: - version "1.0.11" - resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" - integrity sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE= + version "1.0.12" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" + integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== dependencies: graceful-fs "^4.1.2" inherits "~2.0.0" From 97f8ef4e5edcdd88f7caba589b1584111dfe4011 Mon Sep 17 00:00:00 2001 From: Robert Szaloki Date: Mon, 17 Jun 2019 11:01:49 +0200 Subject: [PATCH 6/6] new version of augmint js (#89) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9f7f7433..c54f1614 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@augmint/js", - "version": "0.3.2", + "version": "0.3.3", "description": "Augmint Javascript Library", "keywords": [ "augmint javascript library A-EUR stablecoin web3 dapp"