Skip to content
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

reduce allocations in risk code #1004

Open
wants to merge 3 commits into
base: deploy
Choose a base branch
from
Open
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
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@
"@typescript-eslint/parser": "^8.0.1",
"axios": "^1.4.0",
"chai": "^4.3.4",
"cli-table3": "^0.6.3",
"console-table-printer": "^2.11.1",
"eslint": "^9.9.0",
"eslint-config-prettier": "^9.1.0",
"fast-csv": "^4.3.6",
Expand Down
72 changes: 29 additions & 43 deletions ts/client/src/accounts/healthCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,22 @@
// ██████████████████████████████████████████
// warning: this code is copy pasta from rust, keep in sync with health.rs

/**
* WARNING this potentially modifies health & starting spot inplace
*/
function spotAmountTakenForHealthZero(
health: I80F48,
startingSpot: I80F48,
assetWeightedPrice: I80F48,
liabWeightedPrice: I80F48,
): I80F48 {
if (health.lte(ZERO_I80F48())) {
if (!health.isPos()) {
return ZERO_I80F48();
}

let takenSpot = ZERO_I80F48();
if (startingSpot.gt(ZERO_I80F48())) {
if (assetWeightedPrice.gt(ZERO_I80F48())) {
if (startingSpot.isPos()) {
if (assetWeightedPrice.isPos()) {
const assetMax = health.div(assetWeightedPrice);
if (assetMax.lte(startingSpot)) {
return assetMax;
Expand All @@ -65,29 +68,15 @@
takenSpot = startingSpot;
health.isub(startingSpot.mul(assetWeightedPrice));
}
if (health.gt(ZERO_I80F48())) {
if (liabWeightedPrice.lte(ZERO_I80F48())) {
if (health.isPos()) {
if (!liabWeightedPrice.isPos()) {
throw new Error('LiabWeightedPrice must be greater than 0!');
}
takenSpot.iadd(health.div(liabWeightedPrice));
}
return takenSpot;
}

function _spotAmountGivenForHealthZero(
health: I80F48,
startingSpot: I80F48,
assetWeightedPrice: I80F48,
liabWeightedPrice: I80F48,
): I80F48 {
return spotAmountTakenForHealthZero(
health.neg(),
startingSpot.neg(),
liabWeightedPrice,
assetWeightedPrice,
);
}

export class HealthCache {
constructor(
public tokenInfos: TokenInfo[],
Expand Down Expand Up @@ -193,7 +182,7 @@
quoteAsset.div(baseLiab),
);
let allReservedAsBase;
if (!info.reservedQuoteAsBaseHighestBid.eq(ZERO_I80F48())) {
if (!info.reservedQuoteAsBaseHighestBid.isZero()) {
allReservedAsBase = reservedBase.add(
reservedQuoteAsBaseOracle.min(info.reservedQuoteAsBaseHighestBid),
);
Expand All @@ -207,7 +196,7 @@
baseAsset.div(quoteLiab),
);
let allReservedAsQuote;
if (!info.reservedBaseAsQuoteLowestAsk.eq(ZERO_I80F48())) {
if (!info.reservedBaseAsQuoteLowestAsk.isZero()) {
allReservedAsQuote = reservedQuote.add(
reservedBaseAsQuoteOracle.min(info.reservedBaseAsQuoteLowestAsk),
);
Expand Down Expand Up @@ -249,7 +238,7 @@
);
const perpSettleToken = tokenBalances[settleTokenIndex];
const healthUnsettled = perpInfo.healthUnsettledPnl(healthType);
if (!ignoreNegativePerp || healthUnsettled.gt(ZERO_I80F48())) {
if (!ignoreNegativePerp || healthUnsettled.isPos()) {
perpSettleToken.spotAndPerp.iadd(healthUnsettled);
}
}
Expand Down Expand Up @@ -287,7 +276,7 @@
group.getMintDecimalsByTokenIndex(perpInfo.settleTokenIndex),
),
});
if (!ignoreNegativePerp || healthUnsettled.gt(ZERO_I80F48())) {
if (!ignoreNegativePerp || healthUnsettled.isPos()) {
perpSettleToken.spotAndPerp.iadd(healthUnsettled);
}
}
Expand Down Expand Up @@ -509,11 +498,11 @@

public healthRatio(healthType: HealthType): I80F48 {
const res = this.healthAssetsAndLiabsStableLiabs(healthType);
const hundred = I80F48.fromNumber(100);
// console.log(`assets ${res.assets}`);
// console.log(`liabs ${res.liabs}`);
if (res.liabs.gt(I80F48.fromNumber(0.001))) {
return hundred.mul(res.assets.sub(res.liabs)).div(res.liabs);
const hundred = I80F48.fromNumber(100);
return hundred.imul(res.assets.sub(res.liabs)).idiv(res.liabs);
}
return MAX_I80F48();
}
Expand Down Expand Up @@ -931,10 +920,7 @@
targetFn: (cache) => I80F48,
): I80F48 {
if (
sourceBank.initLiabWeight
.sub(targetBank.initAssetWeight)
.abs()
.lte(ZERO_I80F48())
!sourceBank.initLiabWeight.sub(targetBank.initAssetWeight).abs().isPos()
) {
return ZERO_I80F48();
}
Expand Down Expand Up @@ -979,7 +965,7 @@
.mul(price),
);

if (finalHealthSlope.gte(ZERO_I80F48())) {
if (!finalHealthSlope.isNeg()) {
return MAX_I80F48();
}

Expand Down Expand Up @@ -1044,9 +1030,9 @@
const healthAtMaxValue = cacheAfterSwap(amountForMaxValue).health(
HealthType.init,
);
if (healthAtMaxValue.eq(ZERO_I80F48())) {
if (healthAtMaxValue.isZero()) {
return amountForMaxValue;
} else if (healthAtMaxValue.lt(ZERO_I80F48())) {
} else if (healthAtMaxValue.isNeg()) {
return ZERO_I80F48();
}
const zeroHealthEstimate = amountForMaxValue.sub(
Expand Down Expand Up @@ -1106,7 +1092,7 @@
const initialAmount = ZERO_I80F48();
const initialHealth = this.health(HealthType.init);
const initialRatio = this.healthRatio(HealthType.init);
if (initialRatio.lte(ZERO_I80F48())) {
if (!initialRatio.isPos()) {
return ZERO_I80F48();
}

Expand All @@ -1121,7 +1107,7 @@
// and when its a bid, then quote->bid
let zeroAmount;
if (side == Serum3Side.ask) {
const quoteBorrows = quote.balanceSpot.lt(ZERO_I80F48())
const quoteBorrows = quote.balanceSpot.isNeg()
? quote.balanceSpot.abs().mul(quote.prices.liab(HealthType.init))
: ZERO_I80F48();
const max = base.balanceSpot.mul(base.prices.oracle).max(quoteBorrows);
Expand All @@ -1138,7 +1124,7 @@
// console.log(` - quoteBorrows ${quoteBorrows.toLocaleString()}`);
// console.log(` - max ${max.toLocaleString()}`);
} else {
const baseBorrows = base.balanceSpot.lt(ZERO_I80F48())
const baseBorrows = base.balanceSpot.isNeg()
? base.balanceSpot.abs().mul(base.prices.liab(HealthType.init))
: ZERO_I80F48();
const max = quote.balanceSpot.mul(quote.prices.oracle).max(baseBorrows);
Expand Down Expand Up @@ -1170,7 +1156,7 @@
// adjustedCache.logHealthCache(` before placing order ${amount}`);
// TODO: there should also be some issue with oracle vs stable price here;
// probably better to pass in not the quote amount but the base or quote native amount
side === Serum3Side.ask

Check warning on line 1159 in ts/client/src/accounts/healthCache.ts

View workflow job for this annotation

GitHub Actions / Lint

Expected an assignment or function call and instead saw an expression
? adjustedCache.tokenInfos[baseIndex].balanceSpot.isub(
amount.div(base.prices.oracle),
)
Expand Down Expand Up @@ -1220,7 +1206,7 @@
const healthCacheClone: HealthCache = deepClone<HealthCache>(this);

const initialRatio = this.healthRatio(HealthType.init);
if (initialRatio.lt(ZERO_I80F48())) {
if (initialRatio.isNeg()) {
return ZERO_I80F48();
}

Expand All @@ -1243,7 +1229,7 @@
.neg()
.mul(prices.liab(HealthType.init))
.add(price);
if (finalHealthSlope.gte(ZERO_I80F48())) {
if (!finalHealthSlope.isNeg()) {
return MAX_I80F48();
}
finalHealthSlope.imul(settleInfo.liabWeightedPrice(HealthType.init));
Expand Down Expand Up @@ -1277,8 +1263,8 @@
// 1. We are increasing abs(baseLots)
// 2. We are bringing the base position to 0, and then going to case 1.
const hasCase2 =
(initialBaseLots.gt(ZERO_I80F48()) && direction == -1) ||
(initialBaseLots.lt(ZERO_I80F48()) && direction == 1);
(initialBaseLots.isPos() && direction == -1) ||
(initialBaseLots.isNeg() && direction == 1);

let case1Start: I80F48, case1StartRatio: I80F48;
if (hasCase2) {
Expand Down Expand Up @@ -1309,7 +1295,7 @@
settleInfo.initAssetWeight = settleInfo.initLiabWeight;
settleInfo.initScaledAssetWeight = settleInfo.initScaledLiabWeight;
const startHealth = startCache.health(HealthType.init);
if (startHealth.lte(ZERO_I80F48())) {
if (!startHealth.isPos()) {
return ZERO_I80F48();
}

Expand Down Expand Up @@ -1372,7 +1358,7 @@
if (perpPosition.getBasePosition(perpMarket).isPos()) {
const zero = ZERO_I80F48();
const healthAtPriceZero = healthAfterPriceChange(zero);
if (healthAtPriceZero.gt(ZERO_I80F48())) {
if (healthAtPriceZero.isPos()) {
return null;
}

Expand Down Expand Up @@ -1793,7 +1779,7 @@
if (this.settleTokenIndex !== settleToken.tokenIndex) {
throw new Error('Settle token index should match!');
}
if (unweighted.gt(ZERO_I80F48())) {
if (unweighted.isPos()) {
return (
healthType == HealthType.init
? settleToken.initScaledAssetWeight
Expand All @@ -1819,7 +1805,7 @@
unweighted: I80F48,
healthType: HealthType | undefined,
): I80F48 {
if (unweighted.gt(ZERO_I80F48())) {
if (unweighted.isPos()) {
return (
healthType == HealthType.init || healthType == HealthType.liquidationEnd
? this.initOverallAssetWeight
Expand Down
4 changes: 2 additions & 2 deletions ts/client/src/accounts/mangoAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -311,10 +311,10 @@ export class MangoAccount {
)) {
const oo = this.serum3OosMapByMarketIndex.get(serum3Market.marketIndex);
if (serum3Market.baseTokenIndex == bank.tokenIndex && oo) {
bal.add(I80F48.fromI64(oo.baseTokenFree));
bal.iadd(I80F48.fromI64(oo.baseTokenFree));
}
if (serum3Market.quoteTokenIndex == bank.tokenIndex && oo) {
bal.add(I80F48.fromI64(oo.quoteTokenFree));
bal.iadd(I80F48.fromI64(oo.quoteTokenFree));
}
}
return bal;
Expand Down
26 changes: 0 additions & 26 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,6 @@
dependencies:
"@soncodi/signal" "~2.0.7"

"@colors/colors@1.5.0":
version "1.5.0"
resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9"
integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==

"@coral-xyz/anchor-30@npm:@coral-xyz/anchor@0.30.1", "switchboard-anchor@npm:@coral-xyz/anchor@0.30.1":
version "0.30.1"
resolved "https://registry.yarnpkg.com/@coral-xyz/anchor/-/anchor-0.30.1.tgz#17f3e9134c28cd0ea83574c6bab4e410bcecec5d"
Expand Down Expand Up @@ -1577,15 +1572,6 @@ chokidar@^3.6.0:
optionalDependencies:
fsevents "~2.3.2"

cli-table3@^0.6.3:
version "0.6.5"
resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.5.tgz#013b91351762739c16a9567c21a04632e449bf2f"
integrity sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==
dependencies:
string-width "^4.2.0"
optionalDependencies:
"@colors/colors" "1.5.0"

cliui@^7.0.2:
version "7.0.4"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f"
Expand Down Expand Up @@ -1639,13 +1625,6 @@ consola@^3.2.3:
resolved "https://registry.yarnpkg.com/consola/-/consola-3.2.3.tgz#0741857aa88cfa0d6fd53f1cff0375136e98502f"
integrity sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==

console-table-printer@^2.11.1:
version "2.12.1"
resolved "https://registry.yarnpkg.com/console-table-printer/-/console-table-printer-2.12.1.tgz#4a9646537a246a6d8de57075d4fae1e08abae267"
integrity sha512-wKGOQRRvdnd89pCeH96e2Fn4wkbenSP6LMHfjfyNLMbGuHEFbMqQNuxXqd0oXG9caIOQ1FTvc5Uijp9/4jujnQ==
dependencies:
simple-wcswidth "^1.0.1"

crc@^4.1.0:
version "4.3.2"
resolved "https://registry.yarnpkg.com/crc/-/crc-4.3.2.tgz#49b7821cbf2cf61dfd079ed93863bbebd5469b9a"
Expand Down Expand Up @@ -3145,11 +3124,6 @@ signal-exit@^4.0.1:
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04"
integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==

simple-wcswidth@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/simple-wcswidth/-/simple-wcswidth-1.0.1.tgz#8ab18ac0ae342f9d9b629604e54d2aa1ecb018b2"
integrity sha512-xMO/8eNREtaROt7tJvWJqHBDTMFN4eiQ5I4JRMuilwfnFcV5W9u7RUkueNkdw0jPqGMX36iCywelS5yilTuOxg==

slash@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
Expand Down
Loading