Skip to content

Commit

Permalink
Merge pull request #67 from Polymarket/chore/amounts-calculation-testing
Browse files Browse the repository at this point in the history
ensuring correct maker and taker amounts
  • Loading branch information
poly-rodr authored Jan 13, 2023
2 parents 9cfa43e + 3ce45be commit cfa9d25
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 41 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ test:
--require jsdom-global/register \
--require ts-node/register 'tests/**/*.test.ts' \
--require tsconfig-paths/register \
--timeout 10000 \
--timeout 30000 \
--exit

.PHONY: lint
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@polymarket/clob-client",
"description": "Typescript client for Polymarket's CLOB",
"version": "1.1.17",
"version": "1.1.18",
"contributors": [
{
"name": "Jonathan Amenechi",
Expand Down
103 changes: 65 additions & 38 deletions src/order-builder/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,26 +33,16 @@ export const buildOrder = async (
return cTFExchangeOrderBuilder.buildSignedOrder(orderData);
};

/**
* Translate simple user order to args used to generate Orders
*/
export const buildOrderCreationArgs = async (
signer: string,
maker: string,
signatureType: SignatureType,
userOrder: UserOrder,
): Promise<OrderData> => {
let makerAmount: string;
let takerAmount: string;

let side: UtilsSide;

if (userOrder.side === Side.BUY) {
side = UtilsSide.BUY;

export const getOrderAmounts = (
side: Side,
size: number,
price: number,
): { side: UtilsSide; rawMakerAmt: number; rawTakerAmt: number } => {
const rawPrice = roundNormal(price, 2);

if (side === Side.BUY) {
// force 2 decimals places
const rawTakerAmt = roundDown(userOrder.size, 2);
const rawPrice = roundNormal(userOrder.price, 2); // prob can just round this normal
const rawTakerAmt = roundDown(size, 2);

let rawMakerAmt = rawTakerAmt * rawPrice;
if (decimalPlaces(rawMakerAmt) > 4) {
Expand All @@ -62,13 +52,13 @@ export const buildOrderCreationArgs = async (
}
}

makerAmount = parseUnits(rawMakerAmt.toString(), COLLATERAL_TOKEN_DECIMALS).toString();
takerAmount = parseUnits(rawTakerAmt.toString(), CONDITIONAL_TOKEN_DECIMALS).toString();
return {
side: UtilsSide.BUY,
rawMakerAmt,
rawTakerAmt,
};
} else {
side = UtilsSide.SELL;

const rawMakerAmt = roundDown(userOrder.size, 2);
const rawPrice = roundNormal(userOrder.price, 2);
const rawMakerAmt = roundDown(size, 2);

let rawTakerAmt = rawMakerAmt * rawPrice;
if (decimalPlaces(rawTakerAmt) > 4) {
Expand All @@ -78,9 +68,31 @@ export const buildOrderCreationArgs = async (
}
}

makerAmount = parseUnits(rawMakerAmt.toString(), CONDITIONAL_TOKEN_DECIMALS).toString();
takerAmount = parseUnits(rawTakerAmt.toString(), COLLATERAL_TOKEN_DECIMALS).toString();
return {
side: UtilsSide.SELL,
rawMakerAmt,
rawTakerAmt,
};
}
};

/**
* Translate simple user order to args used to generate Orders
*/
export const buildOrderCreationArgs = async (
signer: string,
maker: string,
signatureType: SignatureType,
userOrder: UserOrder,
): Promise<OrderData> => {
const { side, rawMakerAmt, rawTakerAmt } = getOrderAmounts(
userOrder.side,
userOrder.size,
userOrder.price,
);

const makerAmount = parseUnits(rawMakerAmt.toString(), COLLATERAL_TOKEN_DECIMALS).toString();
const takerAmount = parseUnits(rawTakerAmt.toString(), CONDITIONAL_TOKEN_DECIMALS).toString();

let taker;
if (typeof userOrder.taker !== "undefined" && userOrder.taker) {
Expand Down Expand Up @@ -140,18 +152,13 @@ export const createOrder = async (
return buildOrder(eoaSigner, clobContracts.Exchange, chainId, orderData);
};

/**
* Translate simple user market order to args used to generate Orders
*/
export const buildMarketBuyOrderCreationArgs = async (
signer: string,
maker: string,
signatureType: SignatureType,
userMarketOrder: UserMarketOrder,
): Promise<OrderData> => {
export const getMarketBuyOrderRawAmounts = (
amount: number,
price: number,
): { rawMakerAmt: number; rawTakerAmt: number } => {
// force 2 decimals places
const rawMakerAmt = roundDown(userMarketOrder.amount, 2);
const rawPrice = roundDown(userMarketOrder.price || 1, 2);
const rawMakerAmt = roundDown(amount, 2);
const rawPrice = roundDown(price, 2);

let rawTakerAmt = rawMakerAmt / rawPrice;
if (decimalPlaces(rawTakerAmt) > 4) {
Expand All @@ -161,6 +168,26 @@ export const buildMarketBuyOrderCreationArgs = async (
}
}

return {
rawMakerAmt,
rawTakerAmt,
};
};

/**
* Translate simple user market order to args used to generate Orders
*/
export const buildMarketBuyOrderCreationArgs = async (
signer: string,
maker: string,
signatureType: SignatureType,
userMarketOrder: UserMarketOrder,
): Promise<OrderData> => {
const { rawMakerAmt, rawTakerAmt } = getMarketBuyOrderRawAmounts(
userMarketOrder.amount,
userMarketOrder.price || 1,
);

const makerAmount = parseUnits(rawMakerAmt.toString(), COLLATERAL_TOKEN_DECIMALS).toString();
const takerAmount = parseUnits(rawTakerAmt.toString(), CONDITIONAL_TOKEN_DECIMALS).toString();

Expand Down
5 changes: 5 additions & 0 deletions src/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ export const decimalPlaces = (num: number): number => {
if (Number.isInteger(num)) {
return 0;
}

const arr = num.toString().split(".");
if (arr.length <= 1) {
return 0;
}

return arr[1].length;
};
62 changes: 61 additions & 1 deletion tests/order-builder/helpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
createOrder,
buildMarketBuyOrderCreationArgs,
createMarketBuyOrder,
getOrderAmounts,
getMarketBuyOrderRawAmounts,
} from "../../src/order-builder/helpers";
import {
OrderData,
Expand All @@ -16,7 +18,7 @@ import {
getContracts,
} from "@polymarket/order-utils";
import { Wallet } from "@ethersproject/wallet";
import { roundDown } from "../../src/utilities";
import { decimalPlaces, roundDown } from "../../src/utilities";

describe("helpers", () => {
const chainId = Chain.MUMBAI;
Expand Down Expand Up @@ -147,6 +149,44 @@ describe("helpers", () => {
});
});

describe("getOrderAmounts", async () => {
it("buy", async () => {
const delta = 0.01;
let size = 0.01;

for (; size <= 100; ) {
let price = 0.01;
for (; price <= 1; ) {
const { rawMakerAmt, rawTakerAmt } = getOrderAmounts(Side.BUY, size, price);

expect(decimalPlaces(rawMakerAmt)).to.lte(4);
expect(decimalPlaces(rawTakerAmt)).to.lte(2);

price += delta;
}
size += delta;
}
});

it("sell", async () => {
const delta = 0.01;
let size = 0.01;

for (; size <= 100; ) {
let price = 0.01;
for (; price <= 1; ) {
const { rawMakerAmt, rawTakerAmt } = getOrderAmounts(Side.SELL, size, price);

expect(decimalPlaces(rawMakerAmt)).to.lte(2);
expect(decimalPlaces(rawTakerAmt)).to.lte(4);

price += delta;
}
size += delta;
}
});
});

describe("buildOrderCreationArgs", () => {
it("buy order", async () => {
const order: UserOrder = {
Expand Down Expand Up @@ -463,6 +503,26 @@ describe("helpers", () => {
});
});

describe("getMarketBuyOrderRawAmounts", async () => {
it("market buy", async () => {
const delta = 0.01;
let size = 0.01;

for (; size <= 100; ) {
let price = 0.01;
for (; price <= 1; ) {
const { rawMakerAmt, rawTakerAmt } = getMarketBuyOrderRawAmounts(size, price);

expect(decimalPlaces(rawMakerAmt)).to.lte(2);
expect(decimalPlaces(rawTakerAmt)).to.lte(4);

price += delta;
}
size += delta;
}
});
});

describe("buildMarketBuyOrderCreationArgs", () => {
it("market buy order", async () => {
const order: UserMarketOrder = {
Expand Down
1 change: 1 addition & 0 deletions tests/utilities.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -514,5 +514,6 @@ describe("utilities", () => {

it("decimalPlaces", () => {
expect(decimalPlaces(949.9970999999999)).to.equal(13);
expect(decimalPlaces(949)).to.equal(0);
});
});

0 comments on commit cfa9d25

Please sign in to comment.