Omniscia DappRadar Audit
RadarStakingLogic Static Analysis Findings
RadarStakingLogic Static Analysis Findings
RSL-01S: Illegible Numeric Value Representation
Type | Severity | Location |
---|---|---|
Code Style | RadarStakingLogic.sol:L168 |
Description:
The linked representation of a numeric literal is sub-optimally represented decreasing the legibility of the codebase.
Example:
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
Type | Severity | Location |
---|---|---|
Gas Optimization | RadarStakingLogic.sol:L38-L43 |
Description:
The RadarStakingLogic::requireVariablesSet
modifier remains unused within the codebase.
Example:
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
Type | Severity | Location |
---|---|---|
Language Specific | RadarStakingLogic.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:
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
Type | Severity | Location |
---|---|---|
Input Sanitization | RadarStakingLogic.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:
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
Type | Severity | Location |
---|---|---|
Standard Conformity | RadarStakingLogic.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:
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.