Omniscia DappRadar Audit

RadarStakingLogic Static Analysis Findings

RadarStakingLogic Static Analysis Findings

RSL-01S: Illegible Numeric Value Representation

TypeSeverityLocation
Code StyleRadarStakingLogic.sol:L168

Description:

The linked representation of a numeric literal is sub-optimally represented decreasing the legibility of the codebase.

Example:

contracts/RadarStakingLogic.sol
168uint256 accruedReward = totalStaked * currentApr.apr/10_000 * secondsWithCurrentApr/(365 days);

Recommendation:

To properly illustrate the value's purpose, we advise the following guidelines to be followed. For values meant to depict fractions with a base of 1e18, we advise fractions to be utilized directly (i.e. 1e17 becomes 0.1e18) as they are supported. For values meant to represent a percentage base, we advise each value to utilize the underscore (_) separator to discern the percentage decimal (i.e. 10000 becomes 100_00, 300 becomes 3_00 and so on). Finally, for large numeric values we simply advise the underscore character to be utilized again to represent them (i.e. 1000000 becomes 1_000_000).

Alleviation (8614454f02ec2934ccfdc3f17974be01ca6c1709):

The DappRadar team has not provided any remediation for this exhibit instead opting to acknowledge it.

RSL-02S: Unutilized Contract Modifier

TypeSeverityLocation
Gas OptimizationRadarStakingLogic.sol:L38-L43

Description:

The RadarStakingLogic::requireVariablesSet modifier remains unused within the codebase.

Example:

contracts/RadarStakingLogic.sol
38modifier requireVariablesSet() {
39 require(address(rewardAddress) != address(0), "RadarStakingLogic: Reward Address not set");
40 require(address(radarTokenContract) != address(0), "RadarStakingLogic: Token contract not set");
41 require(address(radarStakeContract) != address(0), "RadarStakingLogic: Staking contract not set");
42 _;
43}

Recommendation:

We advise it to be safely removed, reducing the bytecode size of the contract.

Alleviation (8614454f02ec2934ccfdc3f17974be01ca6c1709):

The unutilized modifier has been safely omitted from the codebase.

RSL-03S: Incorrect Conditional Evaluations

TypeSeverityLocation
Language SpecificRadarStakingLogic.sol:L48, L98, L100, L109, L141, L154, L191, L197

Description:

The referenced conditional evaluations of unsigned integers (i.e. uint256 a) are performing comparisons that either represent tautologies (a >= 0) or impossible states (a <= 0).

Impact:

Presently, the conditionals do not sufficiently sanitize the arguments they are meant to permitting unintentional execution of certain functions such as RadarStakingLogic::stake with a zero-value amount.

Example:

contracts/RadarStakingLogic.sol
47function stake(uint256 amount) external nonReentrant {
48 require(amount >= 0, "RadarStakingLogic: Amount must be above 0");

Recommendation:

We advise the conditionals to be corrected, converting greater-than-or-equal (>=) comparisons with zero to strictly greater-than (>) and less-than-or-equal (<=) comparisons with zero to equality ones.

Alleviation (8614454f02ec2934ccfdc3f17974be01ca6c1709):

Some instances have been alleviated whereas others (mostly LTE comparisons with zero) remain in the codebase. We advise all instances to be adequately updated.

RSL-04S: Inexistent Sanitization of Input Addresses

TypeSeverityLocation
Input SanitizationRadarStakingLogic.sol:L13-L17

Description:

The linked function(s) accept address arguments yet do not properly sanitize them.

Impact:

The presence of zero-value addresses, especially in constructor implementations, can cause the contract to be permanently inoperable. These checks are advised as zero-value inputs are a common side-effect of off-chain software related bugs.

Example:

contracts/RadarStakingLogic.sol
13constructor(address rewardAddr, address radarTokenContractAddr, address radarStakeContractAddr) {
14 rewardAddress = rewardAddr;
15 radarTokenContract = iRadarToken(radarTokenContractAddr);
16 radarStakeContract = iRadarStake(radarStakeContractAddr);
17}

Recommendation:

We advise some basic sanitization to be put in place by ensuring that each address specified is non-zero.

Alleviation (8614454f02ec2934ccfdc3f17974be01ca6c1709):

All input addresses of the RadarStakingLogic::constructor are adequately sanitized as advised, preventing the contract from being accidentally misconfigured during its deployment.

RSL-05S: Improper Invocations of EIP-20 transferFrom

TypeSeverityLocation
Standard ConformityRadarStakingLogic.sol:L59, L66, L89, L125, L128

Description:

The linked statements do not properly validate the returned bool of the EIP-20 standard transferFrom function. As the standard dictates, callers must not assume that false is never returned.

Impact:

If the code mandates that the returned bool is true, this will cause incompatibility with tokens such as USDT / Tether as no such bool is returned to be evaluated causing the check to fail at all times. On the other hand, if the token utilized can return a false value under certain conditions but the code does not validate it, the contract itself can be compromised as having received / sent funds that it never did.

Example:

contracts/RadarStakingLogic.sol
59radarTokenContract.transferFrom(_msgSender(), address(radarStakeContract), amount);

Recommendation:

Since not all standardized tokens are EIP-20 compliant (such as Tether / USDT), we advise a safe wrapper library to be utilized instead such as SafeERC20 by OpenZeppelin to opportunistically validate the returned bool only if it exists in each instance.

Alleviation (9193d77dde992ca090fe8895a88804e096173564):

The DappRadar team has stated that the token they are interacting with is a known implementation that is conformant to the EIP-20 standard and as such the usage of a safe wrapper library is not needed. Given that the referenced invocation interacts solely with the project-affiliated Radar token, we consider this exhibit nullified as the current code is optimal and safe.