Skip to content

Commit 0a6c27b

Browse files
authored
Merge pull request #698 from bancorprotocol/improve-pool-deficit-calculation
Improve the pool-deficit calculation
2 parents fe71d41 + 12e2927 commit 0a6c27b

File tree

1 file changed

+26
-19
lines changed

1 file changed

+26
-19
lines changed

contracts/liquidity-protection/LiquidityProtection.sol

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -681,28 +681,37 @@ contract LiquidityProtection is ILiquidityProtection, Utils, Owned, ReentrancyGu
681681
// deduct the position IL from the target amount
682682
targetAmount = _deductIL(Math.max(reserveAmount, targetAmount), loss);
683683

684-
// check if the pool can accomodate all withdrawals
684+
// get the pool deficit
685+
Fraction memory poolDeficit = _poolDeficit(poolToken);
685686

686-
// get the pool deficit PPM
687-
uint256 deficitPPM = poolDeficitPPM(poolToken);
687+
// calculate the missing portion
688+
Fraction memory missingPortion = Fraction({ n: poolDeficit.n - poolDeficit.d, d: poolDeficit.d});
688689

689-
// if the pool is not in deficit, it can support withdrawing the target amount
690-
if (deficitPPM == 0) {
691-
return (targetAmount, targetAmount);
692-
}
693-
694-
// the pool is in deficit, reduce the target amount
695-
return (_mulDivF(targetAmount, uint256(PPM_RESOLUTION).sub(deficitPPM), PPM_RESOLUTION), targetAmount);
690+
// return the amount the provider will receive for removing liquidity
691+
// as well as the specific position value (before deficit reduction
692+
return (_mulDivF(targetAmount, missingPortion.n, missingPortion.d), targetAmount);
696693
}
697694

698695
/**
699696
* @dev returns the pool deficit based on the total protected amount vs. total
700697
* positions value, in PPM
701698
*/
702699
function poolDeficitPPM(IDSToken poolToken)
703-
public
700+
external
704701
view
705702
returns (uint256)
703+
{
704+
Fraction memory poolDeficit = _poolDeficit(poolToken);
705+
return _mulDivF(PPM_RESOLUTION, poolDeficit.n, poolDeficit.d);
706+
}
707+
708+
/**
709+
* @dev returns the protected liquidity amount and the total positions value
710+
*/
711+
function _poolDeficit(IDSToken poolToken)
712+
private
713+
view
714+
returns (Fraction memory)
706715
{
707716
// get the converter balance
708717
IConverter converter = IConverter(payable(_ownedBy(poolToken)));
@@ -717,14 +726,12 @@ contract LiquidityProtection is ILiquidityProtection, Utils, Owned, ReentrancyGu
717726
// get the total positions value
718727
uint256 totalValue = totalPositionsValue(poolToken);
719728

720-
// if the protected liquidity is higher or equal to the total positions value,
721-
// the pool is not in deficit
722-
if (protectedLiquidity >= totalValue) {
723-
return 0;
724-
}
725-
726-
// the pool is in deficit
727-
return uint256(PPM_RESOLUTION).mul(totalValue.sub(protectedLiquidity)).div(totalValue);
729+
// the pool is in deficit if and only if
730+
// the protected liquidity amount is lower than the total positions value
731+
return Fraction({
732+
n: totalValue - Math.min(protectedLiquidity, totalValue),
733+
d: totalValue
734+
});
728735
}
729736

730737
/**

0 commit comments

Comments
 (0)