[high]
Within L1Sender.sol
, there are multiple instance of ETH being sent to an arbitrary address. For instance:
- To the
ILayerZeroEndpoint
variable. - To the
config
variable.
Consider using a whitelist of addresses to send ETH to, or ensure you send ETH to the desired address.
[note]
-
0.8.20:
-
0.8.21:
-
0.8.22:
Please ensure that the codebase is not impacted by any of the enumerated Solidity bugs.
[ethtrust]
Multiple Possible Violations of 'No Conflicting Inheritance' EEA Ethtrust Security Level [S] Requirement
Throughout the codebase there are multiple possible violations. For instance:
- The function
supportsInterface
within the contractL2TokenReceiver
inL2TokenReceiver.sol
file. - The function
supportsInterface
within the contractMOR
inMOR.sol
file. - The function
cap
within the contractMOR
inMOR.sol
file. - The function
burn
within the contractMOR
inMOR.sol
file. - The function
_mint
within the contractMOR
inMOR.sol
file.
Consider solving conflicting inheritance issues.
[note]
In L2TokenReceiver.sol
there are constants not using UPPER_CASE
format. For instance:
According to the Solidity Style Guide, constants should be named with all capital letters with underscores separating words. For better readability, consider following this convention.
[note]
Within Distribution.sol
, some variables are being initialized to their default values. For instance:
To avoid wasting gas uselessly, consider not initializing the variables to the same value that they have by default when they are being declared.
[low]
Throughout the codebase there are multiple floating pragma directives. For instance:
- The file
Distribution.sol
has thesolidity ^0.8.20
floating pragma directive. - The file
L1Sender.sol
has thesolidity ^0.8.20
floating pragma directive. - The file
L2MessageReceiver.sol
has thesolidity ^0.8.20
floating pragma directive. - The file
L2TokenReceiver.sol
has thesolidity ^0.8.20
floating pragma directive. - The file
LinearDistributionIntervalDecrease.sol
has thesolidity ^0.8.20
floating pragma directive. - The file
MOR.sol
has thesolidity ^0.8.20
floating pragma directive.
Use fixed pragma version.
[note]
Throughout the codebase, instances of functions with unnecessarily permissive visibility were found. For instance:
- The
_validatePool
function inDistribution.sol
withINTERNAL
visibility could be limited toPRIVATE
. - The
_stake
function inDistribution.sol
withINTERNAL
visibility could be limited toPRIVATE
. - The
_withdraw
function inDistribution.sol
withINTERNAL
visibility could be limited toPRIVATE
. - The
_getCurrentUserReward
function inDistribution.sol
withINTERNAL
visibility could be limited toPRIVATE
. - The
_getCurrentPoolRate
function inDistribution.sol
withINTERNAL
visibility could be limited toPRIVATE
. - The
_poolExists
function inDistribution.sol
withINTERNAL
visibility could be limited toPRIVATE
. - The
_authorizeUpgrade
function inDistribution.sol
withINTERNAL
visibility could be limited toPRIVATE
. - The
supportsInterface
function inL2TokenReceiver.sol
withPUBLIC
visibility could be limited toEXTERNAL
. - The
editParams
function inL2TokenReceiver.sol
withPUBLIC
visibility could be limited toEXTERNAL
. - The
_editParams
function inL2TokenReceiver.sol
withINTERNAL
visibility could be limited toPRIVATE
. - The
getPeriodReward
function inLinearDistributionIntervalDecrease.sol
withPUBLIC
visibility could be limited toEXTERNAL
. - The
supportsInterface
function inMOR.sol
withPUBLIC
visibility could be limited toEXTERNAL
. - The
cap
function inMOR.sol
withPUBLIC
visibility could be limited toEXTERNAL
. - The
burn
function inMOR.sol
withPUBLIC
visibility could be limited toEXTERNAL
. - The
_mint
function inMOR.sol
withINTERNAL
visibility could be limited toPRIVATE
.
To better convey the intended use of functions and to potentially realize some additional gas savings, consider changing a function's visibility to be only as permissive as required.
[note]
Contract L2TokenReceiver
contract has inconsistent usage of named returns in its functions.
Consider naming all returns of all functions.
[high]
Throughout the codebase, multiple contracts do not implement some interfaces well. For instance:
The L2TokenReceiver
contract in L2TokenReceiver.sol
does not implement the IERC165
Interface well. Check the conformity checker output:
Conformity Checker IERC165:
Functions:
[❌] supportsInterface(bytes4) is implemented incorrectly.
[✅] supportsInterface(bytes4) signature is correct.
[❌] PUBLIC visibility is incorrect, should be EXTERNAL.
[✅] VIEW mutability is correct.
[✅] [bool] return type is correct.
The MOR
contract in MOR.sol
does not implement the IERC165
Interface well. Check the conformity checker output:
Conformity Checker IERC165:
Functions:
[❌] supportsInterface(bytes4) is implemented incorrectly.
[✅] supportsInterface(bytes4) signature is correct.
[❌] PUBLIC visibility is incorrect, should be EXTERNAL.
[✅] VIEW mutability is correct.
[✅] [bool] return type is correct.
To avoid unexpected behavior, ensure that all contracts correctly implement their public interfaces.
[note]
In Distribution.sol
this optimization could be applied. For instance:
Consider using the prefix increment operator ++i
instead of the post-increment operator i++
in order to save gas. This optimization skips storing the value before the incremental operation, as the return value of the expression is ignored.
[note]
Throughout the codebase, there are contracts that do not have a security contact. For instance:
- The
Distribution
contract. - The
L1Sender
contract. - The
L2MessageReceiver
contract. - The
L2TokenReceiver
contract. - The
LinearDistributionIntervalDecrease
library. - The
MOR
contract.
Consider adding a NatSpec comment containing a security contact on top of the contracts definition. Using the @custom:security-contact
convention is recommended as it has been adopted by the OpenZeppelin Wizard and the ethereum-lists.
[low]
Throughout the codebase there are several parts that do not have docstrings. For instance:
- Line 15 in
Distribution.sol
- Line 18 in
Distribution.sol
- Line 20 in
Distribution.sol
- Line 21 in
Distribution.sol
- Line 24 in
Distribution.sol
- Line 25 in
Distribution.sol
- Line 28 in
Distribution.sol
- Line 31 in
Distribution.sol
- Line 49 in
Distribution.sol
- Line 68 in
Distribution.sol
- Line 75 in
Distribution.sol
- Line 89 in
Distribution.sol
- Line 116 in
Distribution.sol
- Line 143 in
Distribution.sol
- Line 147 in
Distribution.sol
- Line 170 in
Distribution.sol
- Line 174 in
Distribution.sol
- Line 299 in
Distribution.sol
- Line 308 in
Distribution.sol
- Line 325 in
Distribution.sol
- Line 17 in
L1Sender.sol
- Line 18 in
L1Sender.sol
- Line 20 in
L1Sender.sol
- Line 21 in
L1Sender.sol
- Line 23 in
L1Sender.sol
- Line 27 in
L1Sender.sol
- Line 74 in
L1Sender.sol
- Line 99 in
L1Sender.sol
- Line 13 in
L2MessageReceiver.sol
- Line 14 in
L2MessageReceiver.sol
- Line 15 in
L2MessageReceiver.sol
- Line 17 in
L2MessageReceiver.sol
- Line 19 in
L2MessageReceiver.sol
- Line 24 in
L2MessageReceiver.sol
- Line 13 in
L2TokenReceiver.sol
- Line 14 in
L2TokenReceiver.sol
- Line 15 in
L2TokenReceiver.sol
- Line 17 in
L2TokenReceiver.sol
- Line 26 in
L2TokenReceiver.sol
- Line 30 in
L2TokenReceiver.sol
- Line 43 in
L2TokenReceiver.sol
- Line 60 in
L2TokenReceiver.sol
- Line 8 in
LinearDistributionIntervalDecrease.sol
- Line 11 in
MOR.sol
- Line 14 in
MOR.sol
- Line 21 in
MOR.sol
- Line 25 in
MOR.sol
- Line 29 in
MOR.sol
Consider thoroughly documenting all functions (and their parameters) that are part of any contract's public API. Functions implementing sensitive functionality, even if not public, should be clearly documented as well. When writing docstrings, consider following the Ethereum Natural Specification Format (NatSpec).
[note]
In LinearDistributionIntervalDecrease.sol
, there are multiple multiplications that can lead to precision loss. For instance:
- The multiplication
*
. - The multiplication
*
. - The multiplication
*
. - The multiplication
*
. - The multiplication
*
. - The multiplication
*
. - The multiplication
*
.
Performing multiplication before division is generally better to avoid loss of precision, consider ordering multiplication before division.
[low]
Within Distribution.sol
the require( amount_ > 0 && (newDeposited_ >= pool.minimalStake || newDeposited_ == 0), "DS: invalid withdraw amount" )
requires multiple conditions to be satisfied.
To simplify the codebase and raise the most helpful error messages for failing require
statements, consider having a single require statement per condition.
[low]
Throughout the codebase, there are multiple variables with similar names. For instance:
- The
poolData
name within theDistribution.sol
is similar topoolsData
. - The
pool
name within theDistribution.sol
is similar topools
. - The
users_
name within theDistribution.sol
is similar touser_
. - The
amounts_
name within theDistribution.sol
is similar toamount_
. - The
user_
name within theDistribution.sol
is similar tousers_
. - The
amount_
name within theDistribution.sol
is similar toamounts_
. - The
pool
name within theDistribution.sol
is similar topools
. - The
poolData
name within theDistribution.sol
is similar topoolsData
. - The
userData
name within theDistribution.sol
is similar tousersData
. - The
userData
name within theDistribution.sol
is similar tousersData
. - The
pool
name within theDistribution.sol
is similar topools
. - The
poolData
name within theDistribution.sol
is similar topoolsData
. - The
userData
name within theDistribution.sol
is similar tousersData
. - The
pool
name within theDistribution.sol
is similar topools
. - The
poolData
name within theDistribution.sol
is similar topoolsData
. - The
userData
name within theDistribution.sol
is similar tousersData
. - The
userData_
name within theDistribution.sol
is similar tousersData
. - The
poolData
name within theDistribution.sol
is similar topoolsData
. - The
amount0_
name within theL2TokenReceiver.sol
is similar toamount1_
. - The
amount1_
name within theL2TokenReceiver.sol
is similar toamount0_
. - The
amountAdd0_
name within theL2TokenReceiver.sol
is similar toamountAdd1_
. - The
amountAdd1_
name within theL2TokenReceiver.sol
is similar toamountAdd0_
.
Consider to rename the variables using clear and descriptive variable names and adhering to a naming convention.
[note]
Throughout the codebase, instances of functions that are updating the state without an event emission were found: For instance:
- The
Distribution_init
function inDistribution.sol
. - The
Distribution_init
function inDistribution.sol
. - The
createPool
function inDistribution.sol
. - The
editPool
function inDistribution.sol
. - The
editPool
function inDistribution.sol
. - The
manageUsersInPrivatePool
function inDistribution.sol
. - The
manageUsersInPrivatePool
function inDistribution.sol
. - The
claim
function inDistribution.sol
. - The
claim
function inDistribution.sol
. - The
claim
function inDistribution.sol
. - The
_stake
function inDistribution.sol
. - The
_stake
function inDistribution.sol
. - The
_stake
function inDistribution.sol
. - The
_stake
function inDistribution.sol
. - The
_withdraw
function inDistribution.sol
. - The
_withdraw
function inDistribution.sol
. - The
_withdraw
function inDistribution.sol
. - The
_withdraw
function inDistribution.sol
. - The
removeUpgradeability
function inDistribution.sol
. - The
setRewardTokenConfig
function inL1Sender.sol
. - The
setDepositTokenConfig
function inL1Sender.sol
. - The
_replaceDepositToken
function inL1Sender.sol
. - The
setParams
function inL2MessageReceiver.sol
. - The
setParams
function inL2MessageReceiver.sol
. - The
lzReceive
function inL2MessageReceiver.sol
. - The
constructor
function inL2TokenReceiver.sol
. - The
constructor
function inL2TokenReceiver.sol
. - The
_editParams
function inL2TokenReceiver.sol
.
Consider emitting events whenever there are state changes to make the codebase less error prone and improve its readability.
[High]
The use of ERC20's transferFrom
on line 195 in Distribution.sol
does not pass msg.sender
as a from
parameter.
Consider using msg.sender
as from
parameter in ERC20's transferFrom
calls.
[ethtrust]
The call ILayerZeroEndpoint(config.gateway).send{value: msg.value}( config.receiverChainId, // communicator LayerZero chainId receiverAndSenderAddresses_, // send to this address to the communicator payload_, // bytes payload payable(refundTo_), // refund address address(0x0), // future parameter bytes("") // adapterParams (see "Advanced Features") )
within the contract L1Sender
in L1Sender.sol
has missing failure check.
undefined
[note]
Throughout the codebase, some local variables are not initialized. For instance:
- The
newDeposited_
local variable ofDistribution.sol
. - The
sender_
local variable ofL2MessageReceiver.sol
. - The
amountAdd0_
local variable ofL2TokenReceiver.sol
. - The
amountAdd1_
local variable ofL2TokenReceiver.sol
. - The
intervalPart_
local variable ofLinearDistributionIntervalDecrease.sol
.
To improve the overall clarity, intent, and readability of the codebase, consider initializing all local variables.
[note]
Within the Distribution
contract, the None
argument for the _authorizeUpgrade
function is unused.
To improve the overall clarity, intentionality, and readability of the codebase, consider removing any unused function parameters.
[note]
In Distribution.sol
the _authorizeUpgrade
function is unused.
To improve the overall clarity, intentionality, and readability of the codebase, consider using or removing any currently unused functions.
[note]
Within the Distribution
contract, the isNotUpgradeable
state variable is unused.
To improve the overall clarity, intentionality, and readability of the codebase, consider removing any unused state variables.
[Low]
The constructor of contract MOR
calls void constructor of ERC20("MOR", "MOR")
.
Remove the constructor call.
[high]
Throughout the codebase there are contracts containing code that does not protect against reentrancy. For instance:
- The
claim(uint256,address)
function inDistribution.sol
👍 👎 💬 - The
sendDepositToken(uint256,uint256,uint256)
function inL1Sender.sol
👍 👎 💬 - The
getPeriodReward(uint256,uint256,uint128,uint128,uint128,uint128)
function inLinearDistributionIntervalDecrease.sol
👍 👎 💬
Consider following the checks-effects-interactions pattern whenever possible, or otherwise protecting code from potential reentrancy.
[note]
- On line 107 of
Distribution.sol
- On line 19 of
LinearDistributionIntervalDecrease.sol
- On line 87 of
LinearDistributionIntervalDecrease.sol
- On line 102 of
LinearDistributionIntervalDecrease.sol
- On line 131 of
LinearDistributionIntervalDecrease.sol
undefined
[note]
Throughout the codebase, instances of revert and/or require messages were found. For instance:
- In the
Distribution.sol
contract, therequire
statement with the message "DS: pool doesn't exist". - In the
Distribution.sol
contract, therequire
statement with the message "DS: pool isn't public". - In the
Distribution.sol
contract, therequire
statement with the message "DS: invalid payout start value". - In the
Distribution.sol
contract, therequire
statement with the message "DS: invalid pool type". - In the
Distribution.sol
contract, therequire
statement with the message "DS: invalid reward decrease". - In the
Distribution.sol
contract, therequire
statement with the message "DS: pool is public". - In the
Distribution.sol
contract, therequire
statement with the message "DS: invalid length". - In the
Distribution.sol
contract, therequire
statement with the message "DS: pool claim is locked". - In the
Distribution.sol
contract, therequire
statement with the message "DS: nothing to claim". - In the
Distribution.sol
contract, therequire
statement with the message "DS: nothing to stake". - In the
Distribution.sol
contract, therequire
statement with the message "DS: amount too low". - In the
Distribution.sol
contract, therequire
statement with the message "DS: user isn't staked". - In the
Distribution.sol
contract, therequire
statement with the message "DS: pool withdraw is locked". - In the
Distribution.sol
contract, therequire
statement with the message "DS: invalid withdraw amount". - In the
Distribution.sol
contract, therequire
statement with the message "DS: overplus is zero". - In the
Distribution.sol
contract, therequire
statement with the message "DS: upgrade isn't available". - In the
L1Sender.sol
contract, therequire
statement with the message "L1S: invalid receiver". - In the
L2MessageReceiver.sol
contract, therequire
statement with the message "L2MR: invalid nonce". - In the
L2MessageReceiver.sol
contract, therequire
statement with the message "L2MR: invalid gateway". - In the
L2MessageReceiver.sol
contract, therequire
statement with the message "L2MR: invalid sender chain ID". - In the
L2MessageReceiver.sol
contract, therequire
statement with the message "L2MR: invalid sender address". - In the
L2TokenReceiver.sol
contract, therequire
statement with the message "L2TR: invalid tokenIn". - In the
L2TokenReceiver.sol
contract, therequire
statement with the message "L2TR: invalid tokenOut".
For conciseness and gas savings, consider replacing require and revert messages with custom errors.
[note]
The lzReceive
function in L2MessageReceiver.sol
might have an incorrect ABI decoding.
Consider carefully checking the abi decodings to prevent decoding in unexpected ways.
[note]
- On line 57 of
Distribution.sol
- On line 126 of
Distribution.sol
Consider wrapping the incremental update into an unchecked
block to save the gas required to check against overflows.
[note]
undefined