Skip to content

Eslint bigint comp #1584

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: release-62
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"react/display-name": "off",
"local-rules/no-bigint-negation": "off",
"local-rules/no-logical-bigint": "off",
"local-rules/no-mixed-bigint-number-comparison": "off",

"es-x/no-bigint": "off",
"es-x/no-optional-chaining": "off",
Expand Down Expand Up @@ -113,7 +114,8 @@
"files": ["./src/**/*.ts", "./src/**/*.tsx", "./src/**/*.js", "./src/**/*.jsx"],
"rules": {
"local-rules/no-bigint-negation": "error",
"local-rules/no-logical-bigint": "error"
"local-rules/no-logical-bigint": "error",
"local-rules/no-mixed-bigint-number-comparison": "error"
},
"parserOptions": {
"project": ["./tsconfig.json"]
Expand Down
142 changes: 132 additions & 10 deletions eslint-local-rules.cjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
// @ts-check
const { ESLintUtils } = require("@typescript-eslint/experimental-utils");
const { TypeFlags } = require("typescript");

const createRule = ESLintUtils.RuleCreator((name) => `https://example.com/rule/${name}`);

Expand All @@ -9,15 +11,15 @@ module.exports = {
type: "problem",
docs: {
description: "Disallow negation of bigint or bigint | undefined variables",
category: "Possible Errors",
recommended: true,
recommended: "error",
},
schema: [],
messages: {
bigintNegation: "Negation of bigint is not allowed.",
bigintNegationDesc: "{{desc}}",
},
hasSuggestions: true,
fixable: true,
fixable: "code",
},
defaultOptions: [],
create(context) {
Expand All @@ -39,7 +41,10 @@ module.exports = {
messageId: "bigintNegation",
suggest: [
{
desc: "Use === undefined",
messageId: "bigintNegationDesc",
data: {
desc: "Use === undefined",
},
fix(fixer) {
return [
fixer.removeRange([node.range[0], node.range[0] + 1]),
Expand All @@ -48,7 +53,10 @@ module.exports = {
},
},
{
desc: "Use === null",
messageId: "bigintNegationDesc",
data: {
desc: "Use === null",
},
fix(fixer) {
return [
fixer.removeRange([node.range[0], node.range[0] + 1]),
Expand All @@ -57,7 +65,10 @@ module.exports = {
},
},
{
desc: "Use === 0n",
messageId: "bigintNegationDesc",
data: {
desc: "Use === 0n",
},
fix(fixer) {
return [
fixer.removeRange([node.range[0], node.range[0] + 1]),
Expand All @@ -79,15 +90,14 @@ module.exports = {
type: "problem",
docs: {
description: "Disallow using bigint type in logical expressions",
category: "Possible Errors",
recommended: true,
recommended: "error",
},
schema: [],
messages: {
logicalBigint: "Using bigint in logical expressions is not allowed.",
},
hasSuggestions: true,
fixable: true,
hasSuggestions: false,
fixable: undefined,
},
defaultOptions: [],
create(context) {
Expand All @@ -111,6 +121,118 @@ module.exports = {
};
},
}),
"no-mixed-bigint-number-comparison": createRule({
name: "no-mixed-bigint-number-comparison",
meta: {
type: "problem",
docs: {
description: "Disallow comparing bigint values with regular numbers using comparison operators",
recommended: "error",
},
schema: [],
messages: {
mixedZeroComparison: "Convert zero to bigint using 0n.",
mixedComparisonChangeNumber: "Convert number to bigint using BigInt(Math.trunc({{value}}))",
},
hasSuggestions: true,
fixable: "code",
},

defaultOptions: [],
create(context) {
const parserServices = ESLintUtils.getParserServices(context);
const checker = parserServices.program.getTypeChecker();

return {
BinaryExpression(node) {
if (["<", ">", "<=", ">="].includes(node.operator)) {
const leftTsNode = parserServices.esTreeNodeToTSNodeMap.get(node.left);
const rightTsNode = parserServices.esTreeNodeToTSNodeMap.get(node.right);

const leftType = checker.getTypeAtLocation(leftTsNode);

const rightType = checker.getTypeAtLocation(rightTsNode);

const leftTypeString = checker.typeToString(leftType);
const rightTypeString = checker.typeToString(rightType);
leftType.isNumberLiteral;
const leftIsBigInt =
leftTypeString === "bigint" ||
leftTypeString === "bigint | undefined" ||
leftTypeString === "bigint | null" ||
Boolean(leftType.flags & TypeFlags.BigIntLiteral);

const rightIsBigInt =
rightTypeString === "bigint" ||
rightTypeString === "bigint | undefined" ||
rightTypeString === "bigint | null" ||
Boolean(rightType.flags & TypeFlags.BigIntLiteral);

const leftIsNumber =
leftTypeString === "number" ||
leftTypeString === "number | undefined" ||
leftTypeString === "number | null" ||
leftType.isNumberLiteral();

const rightIsNumber =
rightTypeString === "number" ||
rightTypeString === "number | undefined" ||
rightTypeString === "number | null" ||
rightType.isNumberLiteral();

if ((leftIsBigInt && rightIsNumber) || (leftIsNumber && rightIsBigInt)) {
const leftText = context.getSourceCode().getText(node.left);
const rightText = context.getSourceCode().getText(node.right);

const leftIsZero = leftText === "0";
const rightIsZero = rightText === "0";

if (leftIsZero && rightIsBigInt) {
context.report({
node,
messageId: "mixedZeroComparison",
fix(fixer) {
return fixer.replaceText(node.left, "0n");
},
});
return;
} else if (rightIsZero && leftIsBigInt) {
context.report({
node,
messageId: "mixedZeroComparison",
fix(fixer) {
return fixer.replaceText(node.right, "0n");
},
});
return;
}

context.report({
node,
messageId: "mixedComparisonChangeNumber",
data: {
value: leftIsBigInt && rightIsNumber ? rightText : leftText,
},
fix(fixer) {
if (leftIsBigInt && rightIsNumber) {
return fixer.replaceText(
node.right,
`BigInt(Math.trunc(${context.getSourceCode().getText(node.right)}))`
);
} else {
return fixer.replaceText(
node.left,
`BigInt(Math.trunc(${context.getSourceCode().getText(node.left)}))`
);
}
},
});
}
}
},
};
},
}),
};

function checkBigInt(context, node) {
Expand Down
6 changes: 3 additions & 3 deletions sdk/src/modules/positions/positions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export class Positions extends Module {
return acc;
}

if (position.sizeInUsd > 0) {
if (position.sizeInUsd > 0n) {
acc[key] = position;
}

Expand Down Expand Up @@ -296,7 +296,7 @@ export class Positions extends Module {

const allowedAutoCancelOrders = Number(maxAutoCancelOrders) - 1;
autoCancelOrdersLimit = allowedAutoCancelOrders - existingAutoCancelOrders.length;
const canAddAutoCancelOrder = autoCancelOrdersLimit - draftOrdersCount > 0;
const canAddAutoCancelOrder = autoCancelOrdersLimit - draftOrdersCount > 0n;

if (!canAddAutoCancelOrder) {
warning = true;
Expand Down Expand Up @@ -557,7 +557,7 @@ export class Positions extends Module {
const positionFeeInfo = getPositionFee(
marketInfo,
position.sizeInUsd,
closingPriceImpactDeltaUsd > 0,
closingPriceImpactDeltaUsd > 0n,
userReferralInfo,
uiFeeFactor
);
Expand Down
6 changes: 3 additions & 3 deletions sdk/src/utils/fees/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export function getBorrowingFeeRateUsd(

export function getIsHighPriceImpact(positionPriceImpact?: FeeItem, swapPriceImpact?: FeeItem) {
const totalPriceImpact = getTotalFeeItem([positionPriceImpact, swapPriceImpact]);
return totalPriceImpact.deltaUsd < 0 && bigMath.abs(totalPriceImpact.bps) >= HIGH_PRICE_IMPACT_BPS;
return totalPriceImpact.deltaUsd < 0n && bigMath.abs(totalPriceImpact.bps) >= HIGH_PRICE_IMPACT_BPS;
}

export function getFeeItem(
Expand All @@ -119,8 +119,8 @@ export function getFeeItem(

return {
deltaUsd: feeDeltaUsd,
bps: basis !== undefined && basis > 0 ? getBasisPoints(feeDeltaUsd, basis, shouldRoundUp) : 0n,
precisePercentage: basis !== undefined && basis > 0 ? bigMath.mulDiv(feeDeltaUsd, PRECISION, basis) : 0n,
bps: basis !== undefined && basis > 0n ? getBasisPoints(feeDeltaUsd, basis, shouldRoundUp) : 0n,
precisePercentage: basis !== undefined && basis > 0n ? bigMath.mulDiv(feeDeltaUsd, PRECISION, basis) : 0n,
};
}

Expand Down
18 changes: 9 additions & 9 deletions sdk/src/utils/fees/priceImpact.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ export function applySwapImpactWithCap(marketInfo: MarketInfo, token: TokenData,
}

const isLongCollateral = tokenPoolType === "long";
const price = priceImpactDeltaUsd > 0 ? token.prices.maxPrice : token.prices.minPrice;
const price = priceImpactDeltaUsd > 0n ? token.prices.maxPrice : token.prices.minPrice;

let impactDeltaAmount: bigint;
let cappedDiffUsd = 0n;

if (priceImpactDeltaUsd > 0) {
if (priceImpactDeltaUsd > 0n) {
// round positive impactAmount down, this will be deducted from the swap impact pool for the user
impactDeltaAmount = convertToTokenAmount(priceImpactDeltaUsd, token.decimals, price)!;

Expand Down Expand Up @@ -73,7 +73,7 @@ export function getCappedPositionImpactUsd(
) {
const priceImpactDeltaUsd = getPriceImpactForPosition(marketInfo, sizeDeltaUsd, isLong, opts);

if (priceImpactDeltaUsd < 0) {
if (priceImpactDeltaUsd < 0n) {
return priceImpactDeltaUsd;
}

Expand Down Expand Up @@ -129,7 +129,7 @@ export function getPriceImpactForPosition(
fallbackToZero: opts.fallbackToZero,
});

if (priceImpactUsd > 0) {
if (priceImpactUsd > 0n) {
return priceImpactUsd;
}

Expand Down Expand Up @@ -201,14 +201,14 @@ export function getPriceImpactForSwap(
fallbackToZero: opts.fallbackToZero,
});

if (priceImpactUsd > 0) {
if (priceImpactUsd > 0n) {
return priceImpactUsd;
}

const virtualInventoryLong = marketInfo.virtualPoolAmountForLongToken;
const virtualInventoryShort = marketInfo.virtualPoolAmountForShortToken;

if (virtualInventoryLong <= 0 || virtualInventoryShort <= 0) {
if (virtualInventoryLong <= 0n || virtualInventoryShort <= 0n) {
return priceImpactUsd;
}

Expand Down Expand Up @@ -242,13 +242,13 @@ function getNextOpenInterestForVirtualInventory(p: { virtualInventory: bigint; u
let currentLongUsd = 0n;
let currentShortUsd = 0n;

if (virtualInventory > 0) {
if (virtualInventory > 0n) {
currentShortUsd = virtualInventory;
} else {
currentLongUsd = virtualInventory * -1n;
}

if (usdDelta < 0) {
if (usdDelta < 0n) {
const offset = bigMath.abs(usdDelta);
currentLongUsd = currentLongUsd + offset;
currentShortUsd = currentShortUsd + offset;
Expand Down Expand Up @@ -333,7 +333,7 @@ export function getPriceImpactUsd(p: {
}) {
const { nextLongUsd, nextShortUsd } = p;

if (nextLongUsd < 0 || nextShortUsd < 0) {
if (nextLongUsd < 0n || nextShortUsd < 0n) {
if (p.fallbackToZero) {
return 0n;
} else {
Expand Down
2 changes: 1 addition & 1 deletion sdk/src/utils/markets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export function getPoolUsdWithoutPnl(
export function getCappedPoolPnl(p: { marketInfo: MarketInfo; poolUsd: bigint; poolPnl: bigint; isLong: boolean }) {
const { marketInfo, poolUsd, poolPnl, isLong } = p;

if (poolPnl < 0) {
if (poolPnl < 0n) {
return poolPnl;
}

Expand Down
2 changes: 1 addition & 1 deletion sdk/src/utils/numbers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export function numberToBigint(value: number, decimals: number) {
}

export function bigintToNumber(value: bigint, decimals: number) {
const negative = value < 0;
const negative = value < 0n;
if (negative) value *= -1n;
const precision = 10n ** BigInt(decimals);
const int = value / precision;
Expand Down
Loading