Omniscia Faculty Group Audit
LiquidityMining Manual Review Findings
LiquidityMining Manual Review Findings
LMG-01M: Incorrect Decimal Assumption
| Type | Severity | Location |
|---|---|---|
| Logical Fault | Medium | LiquidityMining.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:
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
| Type | Severity | Location |
|---|---|---|
| Standard Conformity | Minor | LiquidityMining.sol:L174-L177, L180, L306 |
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:
301uint256 pending =302 user.amount.mul(pool.accTokenPerShare).div(UNITS).sub(303 user.rewardDebt304 );305306uint256 tokenAvailable = token.balanceOf(tokenRewardsAddress);307308if (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.