Apply loan origination fee only on loans (#364)

* Apply loan origination fee only on loans

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>

* Fixes from review

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>
This commit is contained in:
microwavedcola1 2023-01-06 08:42:16 +01:00 committed by GitHub
parent 292cc9a450
commit e34f9be60a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 38 additions and 28 deletions

View File

@ -516,23 +516,25 @@ export class MangoAccount {
if (sourceMintPk.equals(targetMintPk)) { if (sourceMintPk.equals(targetMintPk)) {
return 0; return 0;
} }
const s = group.getFirstBankByMint(sourceMintPk); const sourceBank = group.getFirstBankByMint(sourceMintPk);
const t = group.getFirstBankByMint(targetMintPk); const targetBank = group.getFirstBankByMint(targetMintPk);
const hc = HealthCache.fromMangoAccount(group, this); const hc = HealthCache.fromMangoAccount(group, this);
const maxSource = hc.getMaxSwapSource( let maxSource = hc.getMaxSwapSource(
s, sourceBank,
t, targetBank,
I80F48.fromNumber( I80F48.fromNumber(
slippageAndFeesFactor * slippageAndFeesFactor *
((s.uiPrice / t.uiPrice) * ((sourceBank.uiPrice / targetBank.uiPrice) *
Math.pow(10, t.mintDecimals - s.mintDecimals)), Math.pow(10, targetBank.mintDecimals - sourceBank.mintDecimals)),
),
);
maxSource.idiv(
ONE_I80F48().add(
group.getFirstBankByMint(sourceMintPk).loanOriginationFeeRate,
), ),
); );
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)); return toUiDecimals(maxSource, group.getMintDecimals(sourceMintPk));
} }
@ -650,23 +652,27 @@ export class MangoAccount {
serum3Market.quoteTokenIndex, serum3Market.quoteTokenIndex,
); );
const hc = HealthCache.fromMangoAccount(group, this); const hc = HealthCache.fromMangoAccount(group, this);
let nativeAmount = hc.getMaxSerum3OrderForHealthRatio( const nativeAmount = hc.getMaxSerum3OrderForHealthRatio(
baseBank, baseBank,
quoteBank, quoteBank,
serum3Market, serum3Market,
Serum3Side.bid, Serum3Side.bid,
I80F48.fromNumber(2), I80F48.fromNumber(2),
); );
let quoteAmount = nativeAmount.div(quoteBank.price);
// If its a bid then the reserved fund and potential loan is in base // 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. // also keep some buffer for fees, use taker fees for worst case simulation.
nativeAmount = nativeAmount const quoteBalance = this.getTokenBalance(quoteBank);
.div(quoteBank.price) if (quoteAmount.gt(quoteBalance)) {
.div(ONE_I80F48().add(baseBank.loanOriginationFeeRate)) const quoteBorrow = quoteAmount.sub(quoteBalance);
.div(ONE_I80F48().add(I80F48.fromNumber(serum3Market.getFeeRates(true)))); quoteAmount = quoteBalance.add(
return toUiDecimals( quoteBorrow.div(ONE_I80F48().add(quoteBank.loanOriginationFeeRate)),
nativeAmount, );
group.getFirstBankByTokenIndex(serum3Market.quoteTokenIndex).mintDecimals, }
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, serum3Market.quoteTokenIndex,
); );
const hc = HealthCache.fromMangoAccount(group, this); const hc = HealthCache.fromMangoAccount(group, this);
let nativeAmount = hc.getMaxSerum3OrderForHealthRatio( const nativeAmount = hc.getMaxSerum3OrderForHealthRatio(
baseBank, baseBank,
quoteBank, quoteBank,
serum3Market, serum3Market,
Serum3Side.ask, Serum3Side.ask,
I80F48.fromNumber(2), I80F48.fromNumber(2),
); );
let baseAmount = nativeAmount.div(baseBank.price);
// If its a ask then the reserved fund and potential loan is in base // 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. // also keep some buffer for fees, use taker fees for worst case simulation.
nativeAmount = nativeAmount const baseBalance = this.getTokenBalance(baseBank);
.div(baseBank.price) if (baseAmount.gt(baseBalance)) {
.div(ONE_I80F48().add(baseBank.loanOriginationFeeRate)) const baseBorrow = baseAmount.sub(baseBalance);
.div(ONE_I80F48().add(I80F48.fromNumber(serum3Market.getFeeRates(true)))); baseAmount = baseBalance.add(
return toUiDecimals( baseBorrow.div(ONE_I80F48().add(baseBank.loanOriginationFeeRate)),
nativeAmount, );
group.getFirstBankByTokenIndex(serum3Market.baseTokenIndex).mintDecimals, }
baseAmount = baseAmount.div(
ONE_I80F48().add(I80F48.fromNumber(serum3Market.getFeeRates(true))),
); );
return toUiDecimals(baseAmount, baseBank.mintDecimals);
} }
/** /**