Assessment reports>Synthereum>Discussion>Documentation

Documentation

The formulas for calculating the interest shares and fee shares are incorrect in the accompanying documentation and do not reflect the implementation in the code. These errors in documentaiton could result in end-user and developer confusion. However, the in-line code documentation is accurate and informative, and we applaud Jarvis for their committment to quality in-line developer documentation.

Interest shares

We advise that the formula for calculating interest shares in the documentation should be changed from

final_share = (minting_capacity_ratio + utilization)/2

to the following:

final_share = (minting_capacity_share + utilization_share)/2

Utilization shares

Where minting_capacity_share corresponds with the definition of minting_capacity_ratio in the current documentation and utilization_share is given by

utilization[i] / total_utilization

Here, utilization_i corresponds with the utilization of the i'th liquidity provider:

utilization[i] = (tokensCollateralized[i] * price * overCollateralization[i]) / collateralDeposited[i].

This is consistent with the implementation in the multiple liquidity pool shown below:

SynthereumMultiLpLiquidityPool...
  function _calculateInterest(
    uint256 _totalInterests,
    uint256 _price,
    uint8 _collateralDecimals,
    PositionCache[] memory _positionsCache
  ) internal view returns (uint256 prevTotalLPsCollateral) {
  ...
      tempInterstArguments.utilizationShare = tempInterstArguments
        .isTotUtilizationNotZero
        ? utilizationShares[j].div(tempInterstArguments.totalUtilization)
        : 0;
  ...

The economic implications of the implementation of the formula responsible for calculating utilization shares is such that, if the entry/exit of LPs was not restricted by whitelist/registration, then an ecomonic attack becomes feasible where an attacker adds many LPs to a pool and collateralizes one token, resulting in 0% capacity shares but a 100% utilization rate. Due to the calculation of utilization shares, which relies on a fraction of the entire utilization, an attacker could steal/earn ~50% of a pool's interest due to their enormous stake into the utilization shares as a result of the many LP providers they control with a 100% utilization rate.

While this is not currently an issue due to the whitelist placed on MultiLpPools, if in the future a change was introduced to allow LPs to join freely, such an attack could take place.

Fee splitting

The formula for calculating the fees allocated to each liquidity provider is given by

redeemFeePaid * ratio[i]

Here, redeemFeePaid corresponds with the total fee paid by the synthetic token minter:

ratio = (share[i] / totalNumberOfTokens )

// and

share[i] = (tokensCollateralized[i] / totalNumberOfTokens)

The formula for fees paid to each liquidity provider should be changed to the following:

redeemFeePaid * share[i]

This is consistent with the implementation in the multiple liquidity pool shown below.

// SynthereumMultiLpLiquidityPool.sol
  // ...
  function _calculateRedeemTokensAndFee(
    uint256 _totalNumTokens,
    uint256 _redeemNumTokens,
    uint256 _feeAmount,
    WithdrawDust memory _withdrawDust,
    PositionCache[] memory _positionsCache
  ) internal pure {
  ...
    redeemSplit.fees = _feeAmount.mul(
    redeemSplit.lpPosition.tokensCollateralized.div(_totalNumTokens)
    );
  ...
Zellic © 2024Back to top ↑