From e34f9be60a28540ad68cff71132b57e23c371f29 Mon Sep 17 00:00:00 2001 From: microwavedcola1 <89031858+microwavedcola1@users.noreply.github.com> Date: Fri, 6 Jan 2023 08:42:16 +0100 Subject: [PATCH] Apply loan origination fee only on loans (#364) * Apply loan origination fee only on loans Signed-off-by: microwavedcola1 * Fixes from review Signed-off-by: microwavedcola1 Signed-off-by: microwavedcola1 --- ts/client/src/accounts/mangoAccount.ts | 66 +++++++++++++++----------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/ts/client/src/accounts/mangoAccount.ts b/ts/client/src/accounts/mangoAccount.ts index 383fd348d..157207de8 100644 --- a/ts/client/src/accounts/mangoAccount.ts +++ b/ts/client/src/accounts/mangoAccount.ts @@ -516,23 +516,25 @@ export class MangoAccount { if (sourceMintPk.equals(targetMintPk)) { return 0; } - const s = group.getFirstBankByMint(sourceMintPk); - const t = group.getFirstBankByMint(targetMintPk); + const sourceBank = group.getFirstBankByMint(sourceMintPk); + const targetBank = group.getFirstBankByMint(targetMintPk); const hc = HealthCache.fromMangoAccount(group, this); - const maxSource = hc.getMaxSwapSource( - s, - t, + let maxSource = hc.getMaxSwapSource( + sourceBank, + targetBank, I80F48.fromNumber( slippageAndFeesFactor * - ((s.uiPrice / t.uiPrice) * - Math.pow(10, t.mintDecimals - s.mintDecimals)), - ), - ); - maxSource.idiv( - ONE_I80F48().add( - group.getFirstBankByMint(sourceMintPk).loanOriginationFeeRate, + ((sourceBank.uiPrice / targetBank.uiPrice) * + Math.pow(10, targetBank.mintDecimals - sourceBank.mintDecimals)), ), ); + const sourceBalance = this.getTokenBalance(sourceBank); + if (maxSource.gt(sourceBalance)) { + const sourceBorrow = maxSource.sub(sourceBalance); + maxSource = sourceBalance.add( + sourceBorrow.div(ONE_I80F48().add(sourceBank.loanOriginationFeeRate)), + ); + } return toUiDecimals(maxSource, group.getMintDecimals(sourceMintPk)); } @@ -650,23 +652,27 @@ export class MangoAccount { serum3Market.quoteTokenIndex, ); const hc = HealthCache.fromMangoAccount(group, this); - let nativeAmount = hc.getMaxSerum3OrderForHealthRatio( + const nativeAmount = hc.getMaxSerum3OrderForHealthRatio( baseBank, quoteBank, serum3Market, Serum3Side.bid, I80F48.fromNumber(2), ); + let quoteAmount = nativeAmount.div(quoteBank.price); // If its a bid then the reserved fund and potential loan is in base // also keep some buffer for fees, use taker fees for worst case simulation. - nativeAmount = nativeAmount - .div(quoteBank.price) - .div(ONE_I80F48().add(baseBank.loanOriginationFeeRate)) - .div(ONE_I80F48().add(I80F48.fromNumber(serum3Market.getFeeRates(true)))); - return toUiDecimals( - nativeAmount, - group.getFirstBankByTokenIndex(serum3Market.quoteTokenIndex).mintDecimals, + const quoteBalance = this.getTokenBalance(quoteBank); + if (quoteAmount.gt(quoteBalance)) { + const quoteBorrow = quoteAmount.sub(quoteBalance); + quoteAmount = quoteBalance.add( + quoteBorrow.div(ONE_I80F48().add(quoteBank.loanOriginationFeeRate)), + ); + } + quoteAmount = quoteAmount.div( + ONE_I80F48().add(I80F48.fromNumber(serum3Market.getFeeRates(true))), ); + return toUiDecimals(nativeAmount, quoteBank.mintDecimals); } /** @@ -688,23 +694,27 @@ export class MangoAccount { serum3Market.quoteTokenIndex, ); const hc = HealthCache.fromMangoAccount(group, this); - let nativeAmount = hc.getMaxSerum3OrderForHealthRatio( + const nativeAmount = hc.getMaxSerum3OrderForHealthRatio( baseBank, quoteBank, serum3Market, Serum3Side.ask, I80F48.fromNumber(2), ); + let baseAmount = nativeAmount.div(baseBank.price); // If its a ask then the reserved fund and potential loan is in base // also keep some buffer for fees, use taker fees for worst case simulation. - nativeAmount = nativeAmount - .div(baseBank.price) - .div(ONE_I80F48().add(baseBank.loanOriginationFeeRate)) - .div(ONE_I80F48().add(I80F48.fromNumber(serum3Market.getFeeRates(true)))); - return toUiDecimals( - nativeAmount, - group.getFirstBankByTokenIndex(serum3Market.baseTokenIndex).mintDecimals, + const baseBalance = this.getTokenBalance(baseBank); + if (baseAmount.gt(baseBalance)) { + const baseBorrow = baseAmount.sub(baseBalance); + baseAmount = baseBalance.add( + baseBorrow.div(ONE_I80F48().add(baseBank.loanOriginationFeeRate)), + ); + } + baseAmount = baseAmount.div( + ONE_I80F48().add(I80F48.fromNumber(serum3Market.getFeeRates(true))), ); + return toUiDecimals(baseAmount, baseBank.mintDecimals); } /**