Skip to content

Commit

Permalink
Merge pull request #1803 from zeitgeistpm/tr-creator-math
Browse files Browse the repository at this point in the history
Creator math
  • Loading branch information
Robiquet authored Sep 27, 2023
2 parents 012c6f0 + ac26778 commit db6787c
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 60 deletions.
68 changes: 36 additions & 32 deletions components/trade-form/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,6 @@ const Inner = ({
marketId: getMarketIdOf(tradeItem.assetId),
});

const { data: constants } = useChainConstants();

const {
poolBaseBalance,
baseWeight,
Expand Down Expand Up @@ -257,18 +255,25 @@ const Inner = ({

const changeByPercentage = useCallback(
(percentage: Decimal) => {
if (tradeItemState == null) {
const [balanceIn, weightIn, balanceOut, weightOut] = [
poolBaseBalance,
baseWeight,
poolAssetBalance,
assetWeight,
];

if (
tradeItemState == null ||
balanceIn == null ||
weightIn == null ||
balanceOut == null ||
weightOut == null
) {
return;
}
if (tradeItem.action === "buy") {
const amountOut = maxAssetAmountDecimal.mul(percentage);

const [balanceIn, weightIn, balanceOut, weightOut] = [
poolBaseBalance,
baseWeight,
poolAssetBalance,
assetWeight,
];
if (tradeItem.action === "buy" && balanceIn) {
const amountOut = maxAssetAmountDecimal.mul(percentage);

const amountIn = calcInGivenOut(
balanceIn,
Expand All @@ -277,6 +282,7 @@ const Inner = ({
weightOut,
amountOut.mul(ZTG),
tradeItemState.swapFee,
market?.creatorFee ?? 0,
);

setValue(
Expand All @@ -287,20 +293,14 @@ const Inner = ({
} else if (tradeItem.action === "sell") {
const amountOut = maxBaseAmountDecimal.mul(percentage);

const [balanceIn, weightIn, balanceOut, weightOut] = [
poolBaseBalance,
baseWeight,
poolAssetBalance,
assetWeight,
];

const amountIn = calcInGivenOut(
balanceOut,
weightOut,
balanceIn,
weightIn,
amountOut.mul(ZTG),
tradeItemState.swapFee,
market?.creatorFee ?? 0,
);

setValue("baseAmount", amountOut.toFixed(4, Decimal.ROUND_DOWN));
Expand All @@ -320,7 +320,20 @@ const Inner = ({

const changeByAssetAmount = useCallback(
(assetAmount: Decimal) => {
if (tradeItemState == null) {
const [balanceIn, weightIn, balanceOut, weightOut] = [
poolBaseBalance,
baseWeight,
poolAssetBalance,
assetWeight,
];
if (
tradeItemState == null ||
balanceIn == null ||
weightIn == null ||
balanceOut == null ||
weightOut == null ||
swapFee == null
) {
return;
}

Expand All @@ -329,19 +342,14 @@ const Inner = ({
: new Decimal(0);

if (tradeItem.action === "buy") {
const [balanceIn, weightIn, balanceOut, weightOut] = [
poolBaseBalance,
baseWeight,
poolAssetBalance,
assetWeight,
];
const amountIn = calcInGivenOut(
balanceIn,
weightIn,
balanceOut,
weightOut,
assetAmount.mul(ZTG),
swapFee,
market?.creatorFee ?? 0,
);

setValue(
Expand All @@ -350,20 +358,14 @@ const Inner = ({
);
setPercentageDisplay(percentage.toString());
} else if (tradeItem.action === "sell") {
const [balanceIn, weightIn, balanceOut, weightOut] = [
poolAssetBalance,
assetWeight,
poolBaseBalance,
baseWeight,
];

const amountOut = calcOutGivenIn(
balanceIn,
weightIn,
balanceOut,
weightOut,
assetAmount.mul(ZTG),
swapFee,
market?.creatorFee ?? 0,
);
setValue(
"baseAmount",
Expand Down Expand Up @@ -412,6 +414,7 @@ const Inner = ({
weightOut,
baseAmount.mul(ZTG),
swapFee,
market?.creatorFee ?? 0,
);
setValue(
"assetAmount",
Expand All @@ -433,6 +436,7 @@ const Inner = ({
weightOut,
baseAmount.mul(ZTG),
swapFee,
market?.creatorFee ?? 0,
);

setValue(
Expand Down
1 change: 0 additions & 1 deletion lib/hooks/queries/useTradeItemState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ export const tradeItemStateRootQueryKey = "trade-item-state";
export const useTradeItemState = (item: TradeItem) => {
const [sdk, id] = useSdkv2();
const wallet = useWallet();
const signer = wallet.activeAccount ? wallet.activeAccount : null;
const slippage = 1;

const marketId = getMarketIdOf(item.assetId);
Expand Down
12 changes: 11 additions & 1 deletion lib/hooks/trade.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ export const useTradeItem = () => {

export const useTradeMaxBaseAmount = (item: TradeItem): Decimal => {
const { data: itemState } = useTradeItemState(item);

if (!itemState) {
return new Decimal(0);
}
Expand All @@ -50,6 +49,7 @@ export const useTradeMaxBaseAmount = (item: TradeItem): Decimal => {
swapFee,
traderAssetBalance,
traderBaseBalance,
market,
} = itemState;

let maxAmountBase: Decimal = new Decimal(0);
Expand All @@ -66,6 +66,7 @@ export const useTradeMaxBaseAmount = (item: TradeItem): Decimal => {
assetWeight,
tradeablePoolAssetBalance,
swapFee,
market.creatorFee ?? 0,
);
return maxAmountBase.gt(traderBaseBalance)
? traderBaseBalance
Expand All @@ -83,6 +84,7 @@ export const useTradeMaxBaseAmount = (item: TradeItem): Decimal => {
baseWeight,
maxAssetIn,
swapFee,
market.creatorFee ?? 0,
);
return maxAmountBase;
}
Expand All @@ -107,6 +109,7 @@ export const useTradeMaxAssetAmount = (item: TradeItem): Decimal => {
tradeablePoolAssetBalance,
swapFee,
traderBaseBalance,
market,
} = itemState;

let maxAmountAsset: Decimal = new Decimal(0);
Expand All @@ -119,6 +122,7 @@ export const useTradeMaxAssetAmount = (item: TradeItem): Decimal => {
assetWeight,
maxBaseAmount,
swapFee,
market.creatorFee ?? 0,
);
}
if (item.action === "sell") {
Expand All @@ -129,6 +133,7 @@ export const useTradeMaxAssetAmount = (item: TradeItem): Decimal => {
baseWeight,
maxBaseAmount,
swapFee,
market.creatorFee ?? 0,
);
}

Expand Down Expand Up @@ -166,6 +171,7 @@ export const useTradeTransaction = (
slippage,
baseAssetId,
assetId,
market,
} = itemState;

let transaction:
Expand All @@ -186,6 +192,7 @@ export const useTradeTransaction = (
assetWeight,
amountDecimal,
swapFee,
market.creatorFee ?? 0,
).mul(new Decimal(1 - slippage / 100));

if (!minAmountOut.isNaN() && minAmountOut.greaterThanOrEqualTo(0)) {
Expand All @@ -206,6 +213,7 @@ export const useTradeTransaction = (
assetWeight,
amountDecimal,
swapFee,
market.creatorFee ?? 0,
).mul(new Decimal(slippage / 100 + 1));

if (!maxAmountIn.isNaN() && maxAmountIn.greaterThanOrEqualTo(0)) {
Expand Down Expand Up @@ -234,6 +242,7 @@ export const useTradeTransaction = (
baseWeight,
amountDecimal,
swapFee,
market.creatorFee ?? 0,
).mul(new Decimal(slippage / 100 + 1));

if (!maxAmountIn.isNaN() && maxAmountIn.greaterThanOrEqualTo(0)) {
Expand All @@ -254,6 +263,7 @@ export const useTradeTransaction = (
baseWeight,
amountDecimal,
swapFee,
market.creatorFee ?? 0,
).mul(new Decimal(1 - slippage / 100));

if (!minAmountOut.isNaN() && minAmountOut.greaterThanOrEqualTo(0)) {
Expand Down
44 changes: 32 additions & 12 deletions lib/math.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,50 @@ describe("math", () => {
});

describe("calcOutGivenIn", () => {
test("should calculate correctly", () => {
const out = calcOutGivenIn(50, 50, 50, 50, 25, 0);
describe("without creator fees", () => {
test("should calculate correctly", () => {
const out = calcOutGivenIn(50, 50, 50, 50, 25, 0, 0);

expect(out.toFixed(1)).toEqual("16.7");
expect(out.toFixed(1)).toEqual("16.7");
});

test("should calculate correctly with fees", () => {
const out = calcOutGivenIn(50, 50, 50, 50, 25, 0.1, 0);

expect(out.toFixed(1)).toEqual("15.5");
});
});

test("should calculate correctly with fees", () => {
const out = calcOutGivenIn(50, 50, 50, 50, 25, 0.1);
describe("with creator fees", () => {
test("should calculate correctly", () => {
const out = calcOutGivenIn(50, 50, 50, 50, 25, 0.01, 0.01);

expect(out.toFixed(1)).toEqual("15.5");
expect(out.toFixed(1)).toEqual("16.4");
});
});
});

describe("calcInGivenOut", () => {
test("should calculate correctly", () => {
const amountIn = calcInGivenOut(50, 50, 50, 50, 10, 0);
describe("without creator fees", () => {
test("should calculate correctly", () => {
const amountIn = calcInGivenOut(50, 50, 50, 50, 10, 0, 0);

expect(amountIn.toFixed(1)).toEqual("12.5");
});

test("should calculate correctly with fees", () => {
const amountIn = calcInGivenOut(50, 50, 50, 50, 10, 0.05, 0);

expect(amountIn.toFixed(1)).toEqual("12.5");
expect(amountIn.toFixed(1)).toEqual("13.2");
});
});

test("should calculate correctly with fees", () => {
const amountIn = calcInGivenOut(50, 50, 50, 50, 10, 0.05);
describe("with creator fees", () => {
test("should calculate correctly", () => {
const amountIn = calcInGivenOut(50, 50, 50, 50, 10, 0.01, 0.01);

expect(amountIn.toFixed(1)).toEqual("13.2");
expect(amountIn.toFixed(1)).toEqual("12.8");
});
});
});
});
32 changes: 18 additions & 14 deletions lib/math.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,20 @@ export const calcSpotPrice = (
};

export const calcOutGivenIn = (
tokenBalanceIn, // amount of 'in' asset in the pool
tokenWeightIn, // weight of 'in' asset on the pool
tokenBalanceOut, // amount of 'out' asset in the pool
tokenWeightOut, // weight of 'out' asset on the pool
tokenAmountIn, // amount in for the swap
swapFee,
tokenBalanceIn: Decimal | string | number, // amount of 'in' asset in the pool
tokenWeightIn: Decimal | string | number, // weight of 'in' asset on the pool
tokenBalanceOut: Decimal | string | number, // amount of 'out' asset in the pool
tokenWeightOut: Decimal | string | number, // weight of 'out' asset on the pool
tokenAmountIn: Decimal | string | number, // amount in for the swap
swapFee: Decimal | string | number, // 0.01 is 1%
creatorFee: Decimal | string | number, // 0.01 is 1%
) => {
const totalFee = new Decimal(swapFee).plus(creatorFee);
const weightRatio = new Decimal(tokenWeightIn).div(
new Decimal(tokenWeightOut),
);
const adjustedIn = new Decimal(tokenAmountIn).times(
new Decimal(1).minus(new Decimal(swapFee)),
new Decimal(1).minus(new Decimal(totalFee)),
);
const y = new Decimal(tokenBalanceIn).div(
new Decimal(tokenBalanceIn).plus(adjustedIn),
Expand All @@ -39,13 +41,15 @@ export const calcOutGivenIn = (
};

export const calcInGivenOut = (
tokenBalanceIn,
tokenWeightIn,
tokenBalanceOut,
tokenWeightOut,
tokenAmountOut,
swapFee,
tokenBalanceIn: Decimal | string | number,
tokenWeightIn: Decimal | string | number,
tokenBalanceOut: Decimal | string | number,
tokenWeightOut: Decimal | string | number,
tokenAmountOut: Decimal | string | number,
swapFee: Decimal | string | number, // 0.01 is 1%
creatorFee: Decimal | string | number, // 0.01 is 1%
) => {
const totalFee = new Decimal(swapFee).plus(creatorFee);
const weightRatio = new Decimal(tokenWeightOut).div(
new Decimal(tokenWeightIn),
);
Expand All @@ -54,6 +58,6 @@ export const calcInGivenOut = (
const foo = y.pow(weightRatio).minus(new Decimal(1));
const tokenAmountIn = new Decimal(tokenBalanceIn)
.times(foo)
.div(new Decimal(1).minus(new Decimal(swapFee)));
.div(new Decimal(1).minus(new Decimal(totalFee)));
return tokenAmountIn;
};

0 comments on commit db6787c

Please sign in to comment.