CoinFabrik/scout-substrate huggingface dataset:
Audit finding: Vulnerable and Unmaintained Dependencies
Project: Pendulum
Auditor: Hacken
Location: pallets/orml-currencies-allowance-extension/Cargo.toml
Vulnerability class (audit): Dependency Management
Vulnerability class (Scout): Dependency
Status: Acknowledged

Vulnerable and Unmaintained Dependencies
The orml-currencies-allowance-extension pallet has dependencies that include one vulnerable crate plus three unmaintained crates.
ID: PDM-004
Scope: Dependencies
Status: Acknowledged

Description:
The orml-currencies-allowance-extension pallet has several dependencies that raise concerns regarding their security and maintenance. The following table provides details about these dependencies:

Dependency  | Version | Id            | Type            | Remediation
------------|---------|---------------|-----------------|--------------------------------------------------
time        | 0.1.45  | RUSTSEC-2020-0071 | Vulnerability   | Upgrade to >=0.2.23
ansi_term   | 0.12.1  | RUSTSEC-2021-0139 | Unmaintained   | Use alternative crates: anstyle, console, nu-ansi-term, owo-colors, stylish, yansi
mach        | 0.3.2   | RUSTSEC-2020-0168 | Unmaintained   | Switch to mach2
parity-wasm | 0.45.0  | RUSTSEC-2022-0061 | Unmaintained   | Switch to wasm-tools

Although these dependencies may not have an immediate impact on the security aspect and are part of the Substrate project, it is essential to regularly review dependencies and monitor for updates to ensure the overall security and maintenance of the project.

Recommendation:
To address these concerns and maintain a secure codebase, it is recommended to take the following actions:

1. Use cargo audit to check for any new vulnerabilities or outdated packages in your project's dependencies. Regularly perform these checks to stay updated on potential security issues.
2. Monitor for new releases of Substrate and update your project accordingly. Keeping your project up to date with the latest Substrate releases ensures that you benefit from bug fixes, security patches, and improvements.

Additionally, it is worth noting that the latest available Substrate release at the time of writing is v0.9.43. Stay informed about new releases and evaluate the feasibility of updating your project to benefit from the latest features and improvements.

Summary: Dependency includes one vulnerable and three unmaintained crates requiring updates or replacements.
Audit finding: TCR voting design should be improved
Project: Nodle
Auditor: Halborn
Impact: 3
Likelihood: 3
Vulnerability class (Scout): Business Logic
Status: NOT APPLICABLE: The issue is marked as not applicable by the Nodle team as the tcr and root of trust pallets will be removed.

3.1 (HAL-01) HAL-01 TCR VOTING DESIGN SHOULD BE IMPROVED - MEDIUM 
 Description:
It was observed that it is possible to:
• Vote with 0 amount
• Challenge yourself
• Counter yourself
• Vote for yourself
By combining these properties, some scenarios might be possible:
• A whale can influence any challenge/counter decision by voting for itself.
A whale can also farm additional tokens upon success by countering any application and then voting to itself.
By countering your application and voting with 0 amount, it is possible to fill up the storage since the values are pushed into vector
To remove yourself from members in the root of trust.

Risk Level:
Likelihood - 3
Impact - 4

Recommendation:
Consider improving the design by not letting the same account to:
• Vote to itself
• Counter itself
• Challenge itself
• Vote with 0 deposit

Remediation Plan:
NOT APPLICABLE: The issue is marked as not applicable by the Nodle team as the TCR and root of trust pallets will be removed.

Summary: TCR voting design allows self-voting, zero-amount votes, and potential manipulation by large token holders.
Audit finding: Denomination logic should be improved
Project: Nodle
Auditor: Halborn
Location: pallets/staking/src/lib.rs
Impact: 2
Likelihood: 4
Vulnerability class (Scout): Business Logic
Status: SOLVED

3.2 (HAL-02) HAL-02 DENOMINATION LOGIC SHOULD BE IMPROVED - MEDIUM
 Description:
It was observed that if a nominator has a single validator, it is not possible to remove a validator through nominator_denominate since it has a check for <StakingMinNominatorTotalBond<T>>. In that case, nominator_denominate_all has to be used, which bypasses that check, which is not intentional.

Code Location:
Listing 1: pallets/staking/src/lib.rs
1 if !do_force {
   ensure!(
      remaining >= <StakingMinNominatorTotalBond<T>>::get(),
      <Error<T>>::NominatorBondBelowMin
   );
}

Risk Level:
Likelihood - 4
Impact - 2

Recommendation:
Consider having a conditional statement in nominator_denominate that allows the forced removal of a validator if the nominator has only one validator.

Remediation Plan:
SOLVED: The issue was solved by the Nodle team.
• Fix Commit

Summary: Denomination logic bypasses minimum bond check when only one validator is nominated.
Audit finding: Emergency shutdown not used in critical functions
Project: Nodle
Auditor: Halborn
Location: pallets
Impact: 4
Likelihood: 3
Vulnerability class (Scout): Denial of Service (DoS) and Spamming
Status: PENDING: In a future release, the Nodle team will modify the emergency shutdown pallet to better generalize.

3.3 (HAL-03) HAL-03 EMERGENCY SHUTDOWN NOT USED IN MANY CRITICAL FUNCTIONS - MEDIUM
 Description:
It was observed that the emergency shutdown pallet is used only in the allocate function in the allocations pallet. However, there are more public functions across different pallets that might be problematic if, at any point in time, there is a bug (security/non-security) discovered within them. There should be a functionality to shut them down before new fixes are pushed.

Code Location:
These functions should have a shutdown functionality:

Grants pallet
• add_vesting_schedule

Staking pallet
• validator_join_pool
• validator_exit_pool
• validator_bond_more
• validator_bond_less
• nominator_nominate
• nominator_denominate
• nominator_bond_more
• nominator_bond_less
• nominator_move_nomination
• unbond_frozen
• withdraw_unbonded
• withdraw_staking_rewards

Risk Level:
Likelihood - 3
Impact - 4

Recommendation:
Consider enabling shutdown functionality in critical public functions.

Example Code:
Listing 2
1 ensure!(
   !pallet_emergency_shutdown :: Pallet::<T>::shutdown(),
   Error::<T>::UnderShutdown
);

Remediation Plan:
PENDING: In a future release, the Nodle team will modify the emergency shutdown pallet to better generalize.

Summary: Emergency shutdown functionality is missing in multiple critical public functions across different pallets.
Audit finding: Missing sanity checks
Project: Nodle
Auditor: Halborn
Location: pallets/staking/src/lib.rs:201-208
Impact: 2
Likelihood: 3
Vulnerability class (Scout): Error Handling and Validation
Status: SOLVED

3.4 (HAL-04) HAL-04 MISSING SANITY CHECKS - LOW
 Description:
It was observed that the set_staking_limits privileged function is missing sanity checks on provided values. Even though it is a protected function, it is still advised to have some sanity checks to avoid any human error.

Code Location:
Listing 3: pallets/staking/src/lib.rs
201 pub fn set_staking_limits (
   origin: OriginFor<T>,
   max_stake_validators: u32,
   min_stake_session_selection: BalanceOf<T>,
   min_validator_bond: BalanceOf<T>,
   min_nominator_total_bond: BalanceOf<T>,
   min_nominator_chill_threshold: BalanceOf<T>
) -> DispatchResultWithPostInfo {

Risk Level:
Likelihood - 3
Impact - 2

Recommendation:
It is recommended to add sanity checks to ensure:
• max_stake_validators != 0
• min_stake_session_selection != 0
• min_validator_bond != 0
• min_nominator_total_bond != 0

Remediation Plan:
SOLVED: The issue was solved by the Nodle team.
• Fix Commit

Summary: Missing sanity checks in set_staking_limits function may allow invalid parameter values.
Audit finding: Vesting to yourself is allowed
Project: Nodle
Auditor: Halborn
Location: pallets/grants/src/lib.rs:157-168
Impact: 2
Likelihood: 3
Vulnerability class (Scout): Business Logic
Status: SOLVED

3.5 (HAL-05) HAL-05 VESTING TO YOURSELF IS ALLOWED - LOW
 Description:
It was observed that you can create a vesting schedule to yourself.

Code Location:
Listing 4: pallets/grants/src/lib.rs
157 pub fn add_vesting_schedule (
   origin: OriginFor<T>,
   dest: <T::Lookup as StaticLookup>::Source,
   schedule: VestingScheduleOf<T>
) -> DispatchResultWithPostInfo {
   let from = ensure_signed(origin)?;
   let to = T::Lookup::lookup(dest)?;
   Self::do_add_vesting_schedule(&from, &to, schedule.clone())?;
   Self::deposit_event(Event::VestingScheduleAdded(from, to, schedule));
   Ok(().into())
}

Risk Level:
Likelihood - 3
Impact - 2

Recommendation:
Please add a check that ensures that from != to in fn add_vesting_schedule.

Remediation Plan:
SOLVED: The issue was solved by the Nodle team.
• Fix Commit

Summary: Vesting schedule allows setting up a vesting to oneself without restrictions.
Audit finding: Missing zero value check
Project: Nodle
Auditor: Halborn
Location: pallets/grants/src/lib.rs:88
Impact: 2
Likelihood: 2
Vulnerability class (Scout): Error Handling and Validation
Status: SOLVED

3.6 (HAL-06) HAL-06 MISSING ZERO VALUE CHECK - LOW
 Description:
It was observed that the allocate function should have a zero value check on the amount argument.

Code Location:
Listing 5: pallets/grants/src/lib.rs (Line 88)
85 pub fn allocate (
   origin: OriginFor<T>,
   to: T::AccountId,
   amount: BalanceOf<T>,
   proof: Vec<u8>
) -> DispatchResultWithPostInfo {
   Self::ensure_oracle(origin)?;
   ...

Risk Level:
Likelihood - 2
Impact - 2

Recommendation:
Consider adding zero value checks to these functions to avoid performing redundant operations if a zero value is received.

Remediation Plan:
SOLVED: The issue was solved by the Nodle team.
• Fix Commit

Summary: Allocate function lacks a zero-value check for the amount argument.
Audit finding: Vesting schedules less than a current block can be created
Project: Nodle
Auditor: Halborn
Impact: 1
Likelihood: 1
Vulnerability class (Scout): Business Logic
Status: NOT APPLICABLE: The issue was marked as not applicable by the Nodle team saying: This can be useful to keep it as it is. In fact, we may have to create retroactive awards that may have been partially vested.

3.7 (HAL-07) HAL-07 VESTING SCHEDULES LESS THAN A CURRENT BLOCK CAN BE CREATED - INFORMATIONAL
 Description:
It was observed that the pallet allows the creation of vesting schedules that are less than the current block number. Those vesting schedules are not more than the regular transfers with extra steps. Therefore, those are redundant.

Example:
Listing 6
1 Current Block: 100

3 Vesting Schedule Start: 1st Block
5 Period: 10 Blocks
7 Period_count: 2
9 Per Period: 1 knodl

13 Vesting Duration: 10 * 2 + 1 = 21 Blocks
14 Initial Transfer sent: 2 knodl
16 Next Claims: 0 since Vesting Duration < Current Block

Risk Level:
Likelihood - 1
Impact - 1

Recommendation:
Consider adding a check that ensures that:
(period * period_count) + start > current_block_number

Remediation Plan:
NOT APPLICABLE: The issue was marked as not applicable by the Nodle team, stating:
This can be useful to keep as it is. In fact, we may have to create retroactive awards that may have been partially vested.

Summary: Vesting schedules can be created with start blocks earlier than the current block, making them redundant.
Audit finding: Redundant check
Project: Nodle
Auditor: Halborn
Location: pallets/grants/src/lib.rs:253
Impact: 1
Likelihood: 1
Vulnerability class (Scout): Code Quality
Status: SOLVED

3.8 (HAL-08) HAL-08 REDUNDANT CHECK - INFORMATIONAL
 Description:
It was observed that the grants pallet contains a redundant check.

Code Location:
There is no need for a second new_lock.is_zero() since it was already checked prior. Removing of the vestingSchedule can be performed within the first check.

Listing 7: pallets/grants/src/lib.rs (Line 253)
247 if new_lock . is_zero () {
248 T :: Currency :: remove_lock ( VESTING_LOCK_ID , & target );
249 }
250 else {
251 T :: Currency :: set_lock ( VESTING_LOCK_ID , & target , new_lock , WithdrawReasons :: all () );
252 }
253 if new_lock . is_zero () {
254 // No more claimable , clear
255 VestingSchedules :: <T >:: remove ( target . clone () );
256 }
257 else {
258 T :: Currency :: set_lock ( VESTING_LOCK_ID , & target , new_lock , WithdrawReasons :: all () );
}

Risk Level:
Likelihood - 1
Impact - 1

Recommendation:
Please remove the second new_lock.is_zero() check and remove the vestingSchedule within the first check.

Listing 8: pallets/grants/src/lib.rs
247 if new_lock . is_zero () {
248 T :: Currency :: remove_lock ( VESTING_LOCK_ID , & target );
249 VestingSchedules :: <T >:: remove ( target . clone () );
250 }
251 else {
252 T :: Currency :: set_lock ( VESTING_LOCK_ID , & target , new_lock , WithdrawReasons :: all () );

Remediation Plan:
SOLVED: The issue was solved by the Nodle team.
• Fix Commit

Summary: Redundant check of new_lock.is_zero() found in grants pallet.
Audit finding: Redundant variable
Project: Nodle
Auditor: Halborn
Location: pallets/tcr/src/lib.rs:138-152,478
Impact: 1
Likelihood: 1
Vulnerability class (Scout): Code Quality
Status: SOLVED

3.9 (HAL-09) HAL-09 REDUNDANT VARIABLE - INFORMATIONAL
 Description:
It was observed that the old1 variable in on_finalize function in tcr pallet is redundant. Tuple returned from commit_applications is Ok(( new_members, Vec::new())). Therefore, old1 is always going to be an empty vector. Hence, extending it with old2 does not make any difference. In this scenario, we only care about new_1.

Code Location:
Listing 9: pallets/tcr/src/lib.rs
138 fn on_finalize ( block : T :: BlockNumber ) {
139 let ( mut new_1 , mut old_1 ) =
140 Self :: commit_applications ( block ) . unwrap_or (( Vec :: new () , Vec :: new () ) );
141 let ( new_2 , old_2 ) =
142 Self :: resolve_challenges ( block ). unwrap_or (( Vec :: new () , Vec :: new () ) );
143 // Should never be the same , so should not need some uniq checks
145 new_1 . extend ( new_2 ) ;
146 old_1 . extend ( old_2 ) ;
148 new_1 . sort () ;
149 old_1 . sort () ;
151 Self :: notify_members_change ( new_1 , old_1 ) ;

Listing 10: pallets/tcr/src/lib.rs (Line 478)
460 fn commit_applications ( block : T :: BlockNumber ) -> FinalizeHelperResultFrom <T > {
461 let new_members = < Applications <T , I > >:: iter ()
462 . filter (|( _account_id , application )| {
463 block
464 . checked_sub (& application . clone () . created_block )
465 . expect ( " created_block should always be smaller than block ; qed ")
466 >= T :: FinalizeApplicationPeriod :: get ()
})
468 . map (|( account_id , application ) | {
469 < Applications <T , I > >:: remove ( account_id . clone () );
470 < Members <T , I > >:: insert ( account_id . clone () , application . clone () ) ;
471 Self :: unreserve_for ( account_id . clone () , application . candidate_deposit );
472 Self :: deposit_event ( Event :: ApplicationPassed ( account_id . clone () ) ) ;
474 account_id
475 })
476 . collect :: < Vec <T :: AccountId > >() ;
478 Ok (( new_members , Vec :: new () ) ) // === HERE ===
}

Risk Level:
Likelihood - 1
Impact - 1

Recommendation:
Consider omitting old1 and remove all actions performed on it.

Listing 11: pallets/tcr/src/lib.rs
247 fn on_finalize ( block : T :: BlockNumber ) {
248 let ( mut new_1 , _ ) =
249 Self :: commit_applications ( block ) . unwrap_or (( Vec :: new () , Vec :: new () ) );
250 let ( new_2 , mut old ) =
251 Self :: resolve_challenges ( block ). unwrap_or (( Vec :: new () , Vec :: new () ) );
253 // Should never be the same , so should not need some uniq checks
254 new_1 . extend ( new_2 ) ;
257 new_1 . sort () ;
258 old . sort () ;
260 Self :: notify_members_change ( new_1 , old ) ;

Remediation Plan:
SOLVED: The issue was solved by the Nodle team.
• Fix Commit

Summary: Redundant variable old1 in on_finalize function.
Audit finding: Usage of vulnerable crates
Project: Nodle
Auditor: Halborn
Impact: 1
Likelihood: 2
Vulnerability class (Scout): Dependency
Status: ACKNOWLEDGED

3.10 (HAL-10) HAL-10 USAGE OF VULNERABLE CRATES - INFORMATIONAL
 Description:
It was observed that the project uses crates with known vulnerabilities.

Code Location:
ID
RUSTSEC-2020-0159
RUSTSEC-2020-0071
RUSTSEC-2021-0130
RUSTSEC-2021-0067
RUSTSEC-2021-009
RUSTSEC-2021-0079
RUSTSEC-2021-0078
RUSTSEC-2021-0076
RUSTSEC-2021-0070
RUSTSEC-2021-0073
RUSTSEC-2021-0013
RUSTSEC-2021-0089
RUSTSEC-2021-0124
RUSTSEC-2021-0110
RUSTSEC-2021-0115

FINDINGS & TECH DETAILS
package: chrono
Short Description: Potential segfault in 'localtime_r' invocations
package: time
Short Description: Potential segfault in the time crate
package: lru
Short Description: Use after free in lru crate
package: cranelift-codegen
Short Description: Memory access due to code generation flaw in Cranelift module
package: crossbeam-deque
Short Description: Data race in crossbeam-deque
package: hyper
Short Description: Integer overflow in hyper's parsing of the Transfer-Encoding header leads to data loss
package: hyper
Short Description: Lenient hyper header parsing of Content-Length could allow request smuggling
package: libsecp256k1
Short Description: libsecp256k1 allows overflowing signatures
package: nalgebra
Short Description: VecStorage Deserialize Allows Violation of Length Invariant
package: prost-types
Short Description: Conversion from prost_types::Timestamp to SystemTime can cause an overflow and panic
package: raw-cpuid
Short Description: Soundness issues in raw-cpuid
package: raw-cpuid
Short Description: Optional Deserialize implementations lacking validation
package: tokio
Short Description: Data race when sending and receiving after closing a oneshot channel
package: wasmtime
Short Description: Multiple Vulnerabilities in Wasmtime
package: zeroize-derive
Short Description: #[zeroize(drop)] doesn’t implement Drop for enums

Risk Level:
Likelihood - 2
Impact - 1

Recommendation:
Even if those vulnerable crates cannot impact the underlying application, it is advised to be aware of them and attempt to update them to non-vulnerable versions. Furthermore, it is necessary to set up dependency monitoring to always be alerted when a new vulnerability is disclosed in one of the project’s crates.

Remediation Plan:
ACKNOWLEDGED: The issue was acknowledged by the Nodle team and will be fixed later.

Summary: Usage of crates with known vulnerabilities identified.
Audit finding: Outdated Rust edition
Project: Nodle
Auditor: Halborn
Location: Cargo.toml
Impact: 1
Likelihood: 1
Vulnerability class (Scout): Code Quality
Status: SOLVED

3.11 (HAL-11) HAL-11 OUTDATED RUST EDITION - INFORMATIONAL
 Description:
It was observed that the project is using outdated rust edition (2018). Recently, 2021 rust edition came out, which includes a lot of stability improvements and new features that might make the code more readable.

Code Location:
• Cargo.toml

Risk Level:
Likelihood - 1
Impact - 1

Recommendation:
Consider updating the Rust to the latest edition to use the latest features and stability improvements.

Reference:
Rust 2021 Edition Guide

Remediation Plan:
SOLVED: The issue was solved by the Nodle team.
• Fix Commit

Summary: Project is using an outdated Rust edition (2018).
Audit finding: Integer overflow
Project: ReefChain
Auditor: Halborn
Location: modules/evm-accounts/src/lib.rs:182,313,314
modules/evm-bridge/src/lib.rs:183,186,191
Impact: 3
Likelihood: 3
Vulnerability class (Scout): Arithmetic
Status: SOLVED

3.1 (HAL-01) INTEGER OVERFLOW - MEDIUM
Description:
An overflow happens when an arithmetic operation reaches the maximum size of a type. For instance, in the ethereum_signable_message() method, an if statement is summing up a few u32 values, which may end up overflowing the integer. In computer programming, an integer overflow occurs when an arithmetic operation attempts to create a numeric value that is outside of the range that can be represented with a given number of bits—either larger than the maximum or lower than the minimum representable value.

Code Location:
Listing 1: modules/evm-accounts/src/lib.rs (Lines 182)
180 pub fn ethereum_signable_message(what: &[u8], extra: &[u8]) -> Vec<u8> {
181 let prefix = b"reef evm:";
182 let mut l = prefix.len() + what.len() + extra.len();
183 let mut rev = Vec::new();

Listing 2: modules/evm-accounts/src/lib.rs (Lines 313,314)
312 pub fn to_ascii_hex(data: &[u8]) -> Vec<u8> {
313 let mut r = Vec::with_capacity(data.len() * 2);
314 let mut push_nibble = |n| r.push(if n < 10 { b'0' + n } else { b'a' - 10 + n });

Listing 3: modules/evm-bridge/src/lib.rs (Lines 183,186,191)
182 let offset = U256::from_big_endian(&output[0..32]);
183 let length = U256::from_big_endian(&output[offset.as_usize()..offset.as_usize() + 32]);
184 ensure!(
// output is 32-byte aligned. ensure total_length >= offset + string length + string data length.
186 output.len() >= offset.as_usize() + 32 + length.as_usize(),
187 Error::<T>::InvalidReturnValue
188 );
189 let mut data = Vec::new();
191 data.extend_from_slice(&output[offset.as_usize() + 32..offset.as_usize() + 32 + length.as_usize()]);

Risk Level:
Likelihood - 3
Impact - 3

Recommendations:
It is recommended to use vetted safe math libraries for arithmetic operations consistently throughout the smart contract system. Consider replacing the addition and multiplication operators with Rust’s checked_add and checked_mul methods.

Remediation:
SOLVED: Reef fixed the issue in commit 6e4153498a28d03b8600739709cb200065c88781.

Summary: Integer overflow vulnerability due to unchecked arithmetic operations in ethereum_signable_message and to_ascii_hex functions.
Audit finding: Total issuance not updated on mint
Project: ReefChain
Auditor: Halborn
Location: modules/currencies/src/lib.rs:168
Impact: 3
Likelihood: 3
Vulnerability class (Scout): Business Logic
Status: ACKNOWLEDGED: Reef states that the affected function is sudo only and will be deprecated in a future release.

3.2 (HAL-02) TOTAL ISSUANCE NOT UPDATED ON MINT - MEDIUM
Description:
The update_balance dispatchable defined in modules/currencies/src/lib.rs does not update the total issuance of the currency (identified by user-supplied ID) which is minted to the target address. This may lead to discrepancies in token data.

Code Location:
Listing 4: modules/currencies/src/lib.rs (Lines 168)
159 #[pallet::weight(T::WeightInfo::update_balance_non_native_currency())]
160 pub fn update_balance(
161 origin: OriginFor<T>,
162 who: <T::Lookup as StaticLookup>::Source,
163 currency_id: CurrencyIdOf<T>,
164 amount: AmountOf<T>,
165 ) -> DispatchResultWithPostInfo {
166 ensure_root(origin)?;
167 let dest = T::Lookup::lookup(who)?;
168 <Self as MultiCurrencyExtended<T::AccountId>>::update_balance(currency_id, &dest, amount)?;
169 Ok(().into())
170 }

Risk Level:
Likelihood - 3
Impact - 3

Recommendations:
Total issuance should be updated every time tokens are minted or burned.

Remediation Plan:
ACKNOWLEDGED: Reef states that the affected function is sudo only and will be deprecated in a future release.

Summary: Total issuance is not updated on mint, causing potential discrepancies in token data.