Omniscia Faculty Group Audit

LiquidityMining Manual Review Findings

LiquidityMining Manual Review Findings

LMG-01M: Incorrect Decimal Assumption

TypeSeverityLocation
Logical FaultMediumLiquidityMining.sol:L15, L16

Description:

The current implementation assumes that the tokens introduced to the system will always have 18 decimals, however, this is not the case for many currencies including BTC-pegged ones.

Example:

contracts/LiquidityMining.sol
15uint256 private constant DECIMALS = 18;
16uint256 private constant UNITS = 10**DECIMALS;

Recommendation:

We advise the UNITS variable to instead be dynamically evaluated per pool by accessing the token's actual decimals via its getter function and forming the unit there. The current system will contain notice-able deviations in the rewards if a token with other than 18 decimals is introduced. At certain points, a different offset should be used depending on the precision desired by the system so the dynamic evaluation of UNITS should be done so wherever the token's total supply is used as a multiplier or divisor.The development team has acknowledged this exhibit but decided to not apply its remediation in the current version of the codebase citing time constraints.

LMG-02M: Inconsistent Paradigm

Description:

The getPoolReward function accommodates for the fact that the allowance between the contract and the tokenRewardsAddress may be smaller than the actual balance of it, however, the _harvest function does not do so which can lead into failed calls if the system does not have sufficient allowance available.

Example:

contracts/LiquidityMining.sol
301uint256 pending =
302 user.amount.mul(pool.accTokenPerShare).div(UNITS).sub(
303 user.rewardDebt
304 );
305
306uint256 tokenAvailable = token.balanceOf(tokenRewardsAddress);
307
308if (pending > tokenAvailable) {
309 pending = tokenAvailable;
310}

Recommendation:

We advise the same paradigm to be applied to ensure that no such issue can arise.

Alleviation:

The same logic path as getPoolReward was added to the _harvest function ensuring it properly takes into account the available allowance of the user.