Skip to content

Commit

Permalink
Prevent invariant overflow (#1690)
Browse files Browse the repository at this point in the history
* Add check to prevent invariant overflow

* Update pkg/pool-stable/contracts/ComposableStablePoolProtocolFees.sol

Co-authored-by: Tom French <[email protected]>

Co-authored-by: Tom French <[email protected]>
  • Loading branch information
nventuro and TomAFrench committed Nov 25, 2022
1 parent 93af2fd commit a5f3958
Showing 1 changed file with 25 additions and 8 deletions.
33 changes: 25 additions & 8 deletions pkg/pool-stable/contracts/ComposableStablePoolProtocolFees.sol
Original file line number Diff line number Diff line change
Expand Up @@ -258,15 +258,32 @@ abstract contract ComposableStablePoolProtocolFees is

uint256 postJoinExitInvariant = StableMath._calculateInvariant(currentAmp, balances);

uint256 protocolFeeAmount = InvariantGrowthProtocolSwapFees.calcDueProtocolFees(
postJoinExitInvariant.divDown(preJoinExitInvariant),
preJoinExitSupply,
postJoinExitSupply,
getProtocolFeePercentageCache(ProtocolFeeType.SWAP)
);
// Compute the portion of the invariant increase due to fees
uint256 supplyGrowthRatio = postJoinExitSupply.divDown(preJoinExitSupply);
uint256 feelessInvariant = preJoinExitInvariant.mulDown(supplyGrowthRatio);

// The postJoinExitInvariant should always be greater than the feelessInvariant (since the invariant and total
// supply move proportionally outside of fees, which the postJoinInvariant includes and the feelessInvariant
// does not). However, in the unexpected case in which due to rounding errors this is not true, we simply skip
// further computation of protocol fees.
if (postJoinExitInvariant > feelessInvariant) {
uint256 invariantDeltaFromFees = postJoinExitInvariant - feelessInvariant;

// To convert to a percentage of pool ownership, multiply by the rate,
// then normalize against the final invariant
uint256 protocolOwnershipPercentage = Math.divDown(
Math.mul(invariantDeltaFromFees, getProtocolFeePercentageCache(ProtocolFeeType.SWAP)),
postJoinExitInvariant
);

if (protocolFeeAmount > 0) {
_payProtocolFees(protocolFeeAmount);
if (protocolOwnershipPercentage > 0) {
uint256 protocolFeeAmount = ProtocolFees.bptForPoolOwnershipPercentage(
postJoinExitSupply,
protocolOwnershipPercentage
);

_payProtocolFees(protocolFeeAmount);
}
}

_updatePostJoinExit(currentAmp, postJoinExitInvariant);
Expand Down

0 comments on commit a5f3958

Please sign in to comment.