CoinFabrik/scout-substrate huggingface dataset:
Audit finding: Inefficient active markets search
Project: Bifrost
Auditor: Oak Security
Location: pallets/lend-market/src/lib.rs:1801-1806
Impact: Informational
Vulnerability class (Scout): Code Quality
Status: Resolved

11. Inefficient active markets search
Severity: Informational
The ensure_active_market function, defined in pallets/lend-market/src/lib.rs:1801-1806, searches for a market by comparing identifiers one by one in a loop through all markets with an asymptotic complexity of O(n). However, the same operation could be performed in constant time by using the market method, defined in pallets/lend-market/src/lib.rs:1946. Consequently, this would cause the execution to incur higher costs due to unnecessary iteration.
Recommendation
We recommend replacing the iteration with a call to the market function.
Status: Resolved

Summary: Active market search is inefficient due to O(n) iteration; can be optimized with constant time method.
Audit finding: Inefficient market data aggregation
Project: Bifrost
Auditor: Oak Security
Location: pallets/lend-market/src/lib.rs:1145-1151,1407
Impact: Informational
Vulnerability class (Scout): Code Quality
Status: Acknowledged

12. Inefficient market data aggregation
Severity: Informational
The get_lf_base_position function, defined in pallets/lend-market/src/lib.rs:1145-1151 iterates through all active markets, aggregating collateral for underlying assets. However, the markets queried are not retained, despite being re-queried later by the current_collateral_balance function in line 1407. Consequently, this would cause the execution to incur higher costs due to unnecessary calculations.
Recommendation
We recommend either passing the query results down to the called functions without alteration, or redesigning the storage layout to only retrieve the necessary data at the point of call.
Status: Acknowledged

Summary: Inefficient market data aggregation leads to unnecessary re-queries and higher execution costs.
Audit finding: Redundant storage queries
Project: Bifrost
Auditor: Oak Security
Location: pallets/lend-market/src/lib.rs:315,945-946,1280-1283,1312-1315,2105-2106,1146
Impact: Informational
Vulnerability class (Scout): Code Quality
Status: Acknowledged

13. Redundant storage queries
Severity: Informational
The pallets/lend-market/src/lib.rs file exhibits redundant uses of on-chain storage. For instance, the AccountDeposits storage, introduced at line 315, undergoes redundant queries in lines 945-946, 1280-1283, 1312-1315, and 2105-2106. In each case, the storage is first checked for the key's presence, followed by a separate query to fetch the key's value. Another example of redundant queries can be seen in line 1146, where the storage query Self::liquidation_free_collaterals is called on every iteration of the loop despite having the same value on each iteration. Minimizing the number of storage queries would enhance both performance and code clarity.
Recommendation
We recommend employing the OptionQuery type for business logic that needs to check for the existence of a key. Additionally, duplicated queries in the same scope should be avoided.
Status: Acknowledged

Summary: Redundant storage queries impact performance and code clarity.
Audit finding: Code duplication
Project: Bifrost
Auditor: Oak Security
Location: pallets/lend-market/src/lib.rs:1144-1152,1158-1166,1280-1293,1312-1325
Impact: Informational
Vulnerability class (Scout): Code Quality
Status: Acknowledged

14. Code duplication
Severity: Informational
The pallets/lend-market/src/lib.rs file contains multiple code duplicates:
1. The code fragments in lines 1144-1152 and 1158-1166 are nearly identical, with the only distinction being the function called on the iterated values: collateral_asset_value (line 1149) in one instance and liquidation_threshold_asset_value (line 1163) in the other.
2. The code fragments in lines 1312-1325 and 1280-1293 are nearly identical, with the only distinction being the type parameter: BalanceOf in one instance and FixedU128 in the other.
Code duplication undermines maintainability, thereby expanding the potential for security vulnerabilities.
Recommendation
We recommend refactoring the codebase to avoid duplications. Generic type parameters and function-type parameters could be used to streamline the data flow.
Status: Acknowledged

Summary: Code duplication impacts maintainability and increases potential for security issues.
Audit finding: The get_special_asset_price function consistently returns None
Project: Bifrost
Auditor: Oak Security
Location: pallets/prices/src/lib.rs:188
Impact: Informational
Vulnerability class (Scout): Code Quality
Status: Resolved

15. The get_special_asset_price function consistently returns None
Severity: Informational
In pallets/prices/src/lib.rs:188, the get_special_asset_price function is designed to return a TimeStampedPrice value, but it consistently returns None instead. As a consequence, this behavior is misleading and renders the function ineffective.
Recommendation
We recommend eliminating the function get_special_asset_price if it’s not being utilized.
Status: Resolved

Summary: The get_special_asset_price function consistently returns None, making it ineffective.
Audit finding: Inefficient reduce_reserves extrinsic execution in case of reduce_reserves parameter equal to zero
Project: Bifrost
Auditor: Oak Security
Location: pallets/lend-market/src/lib.rs:1045
Impact: Informational
Vulnerability class (Scout): Code Quality
Status: Resolved

16. Inefficient reduce_reserves extrinsic execution in case of reduce_reserves parameter equal to zero
Severity: Informational
In pallets/lend-market/src/lib.rs:1045, the reduce_reserves extrinsic takes reduce_amount as a parameter. However, if this amount is zero, the function will perform all operations unnecessarily, which is inefficient and may be misleading to the function caller.
Recommendation
We recommend verifying whether reduce_amount is greater than zero and, if not, returning an error that terminates the transaction.
Status: Resolved

Summary: Inefficient execution occurs if reduce_reserves parameter is zero, performing unnecessary operations.
Audit finding: Use of magic numbers decreases maintainability
Project: Bifrost
Auditor: Oak Security
Location: pallets/lend-market/src/farming.rs:28
pallets/lend-market/src/rate_model.rs:173
Impact: Informational
Vulnerability class (Scout): Code Quality
Status: Acknowledged

17. Use of magic numbers decreases maintainability
Severity: Informational
Throughout the codebase, hard-coded number literals without context or a description are used. Using such 'magic numbers' goes against best practices as they reduce code readability and maintenance as developers are unable to easily understand their use and may make inconsistent changes across the codebase.
Instances of magic numbers are listed below:
- pallets/lend-market/src/farming.rs:28
- pallets/lend-market/src/rate_model.rs:173
Recommendation
We recommend defining magic numbers as constants with descriptive variable names and comments, where necessary.
Status: Acknowledged

Summary: Use of magic numbers decreases code readability and maintainability.
Audit finding: State change events are emitted even if no change has occurred
Project: Bifrost
Auditor: Oak Security
Location: pallets/lend-market/src/lib.rs:678,778
Impact: Informational
Vulnerability class (Scout): Business Logic
Status: Acknowledged

18. State change events are emitted even if no change has occurred
Severity: Informational
In pallets/lend-market/src/lib.rs:778 and pallets/lend-market/src/lib.rs:678, when updating market parameters, the event about success is emitted regardless of whether anything has been changed. If none of the optional values are specified, then the function will end without changing the state, but the MarketRewardSpeedUpdated or UpdatedMarket event will be emitted, which is inconsistent with the function's logic.
Recommendation
We recommend emitting an event only in case the state has been updated.
Status: Acknowledged

Summary: State change events are emitted even when no actual change has occurred.
Audit finding: Miscellaneous comments
Project: Bifrost
Auditor: Oak Security
Location: pallets/lend-market/src/lib.rs:959,1894
pallets/leverage-staking/src/lib.rs:129
pallets/lend-market/src/interest.rs:141
Impact: Informational
Vulnerability class (Scout): Code Quality
Status: Resolved

19. Miscellaneous comments
Severity: Informational
Miscellaneous recommendations can be found below:
- In pallets/lend-market/src/lib.rs:1894 there should be an Overflow error, not an Underflow one, causing exchange_rate to be between (0.02, 1) range, so the division of amount value and exchange_rate could cause overflow only.
- In pallets/lend-market/src/lib.rs:959, it should be used asset, instead of assert.
- In pallets/leverage-staking/src/lib.rs:129, NotSupportTokenType should be reworded to NotSupportedTokenType.
- In pallets/lend-market/src/interest.rs:141, the inequality should be greater than or equal to 0.02, not only greater, based on code implementation.
Recommendation
We suggest following the aforementioned suggestions.
Status: Resolved

Summary: Various code recommendations to fix minor errors and improve clarity.
Audit finding: Potential spamming attack via unsigned dispatch_permit extrinsic
Project: HydraDX
Auditor: Security Research Labs
Location: pallets/transaction-multi-payment/src/lib.rs
Impact: Medium
Vulnerability class (Scout): Denial of Service (DoS) and Spamming
Status: Open

4.1 Potential spamming attack via unsigned dispatch_permit extrinsic
Attack scenario
An attacker spams the network with unsigned transactions.

Location
pallet-transaction-multi-payment

Attack impact
Slowing down the chain.

Severity
Medium

Status
Open

The dispatch_permit extrinsic in the HydraDX node allows for unsigned transactions that perform heavy computational validation (e.g.: validate_permit, decode_all_with_depth_limit). This extrinsic is part of the transaction-multi-payment pallet and utilizes the validate_unsigned function to ensure the transaction's validity. The computationally intensive nature of this validation process can be exploited by submitting numerous unsigned extrinsics, potentially leading to a denial-of-service (DoS) attack on the network.

Moreover, the validate_unsigned logic duplicates the same code as the actual extrinsic, dispatch_permit, which adds even more computation time and resources for the entire call.

As the dispatch_permit is an unsigned extrinsic, there are no fees to be paid, increasing the attack surface.

The following risks can be attributed to this vulnerability:
1. Spam vector: An attacker can use a node to submit a large number of unsigned extrinsics, which will be gossiped across the network. This can lead to:
   - High computational load on collators/validators
   - Potential denial-of-service (DoS) attack, delaying or dropping legitimate transactions
   - Network congestion and performance degradation

2. Resource consumption: The heavy computation required for validating unsigned extrinsics can consume significant node resources, impacting overall network stability and performance.

Changing this extrinsic to be an ensure_signed extrinsic will remove the spamming vector by ensuring the payment of the computation from the caller's account.

Summary: Unsigned dispatch_permit extrinsic can be exploited for network spam and DoS attacks due to lack of payment requirement.
Audit finding: The mapping between Ethereum and Substrate addresses could create unwanted behavior
Project: HydraDX
Auditor: Security Research Labs
Location: pallets/evm-accounts/src/lib.rs
Impact: Info
Vulnerability class (Scout): Business Logic
Status: Open

4.2 The mapping between Ethereum and Substrate addresses could create unwanted behavior

Attack scenario
Legitimate user transfers tokens to an EVM address without a bound Substrate account.

Location
pallet-evm-accounts

Attack impact
The user could lose their funds as the destination address cannot be claimed by a Substrate account.

Severity
Info

Status
Open

HydraDX defines three types of addresses:
1. Truncated address: A substrate address created from an EVM address by prefixing it with "ETH\0" and appending with eight 0 bytes
2. Full Substrate address: Original 32 bytes long native address (not a truncated address)
3. EVM address: First 20 bytes of a Substrate address

This method of mapping EVM addresses to Substrate addresses raises a number of concerns:
- Taking the raw bytes of an address is against best practices (i.e.: the first 20 bytes of a Substrate address are being used to represent an EVM address)
- The entropy of truncated addresses is reduced by 12 bytes as the address always begins with "ETH\0" and ends with eight zero bytes
- Transferring funds to an EVM address which was not bound to a Substrate address results in the funds being transferred to a truncated address, which cannot be claimed by any user

Legitimate users might lose funds by submitting a transfer to an EVM address that is not bound to a Substrate address. This could decrease the trust of the users in the HydraDX network. By reducing the addresses' entropy, the chances of collision attacks increase significantly.

Our mitigation suggestion is to deprecate the usage of truncated addresses and make sure that every EVM address is bound to a Substrate address.

Summary: Mapping Ethereum to Substrate addresses can lead to unclaimable funds and reduced address entropy, increasing collision risks.
Audit finding: Unrestricted URI
Project: LAOS
Auditor: CoinFabrik
Location: pallets/laos-evolution
Impact: High
Vulnerability class (audit): CWE-1269: Product Released in Non-Release Configuration
Vulnerability class (Scout): Error Handling and Validation
CWE: CWE-1269
Status: Acknowledged

High Severity Issues
HI-01 Unrestricted URI
Found on commit: 16bd9e56d20c206cf927d961c8ec58f299308473
Location:
- pallets/laos-evolution
Classification:
- CWE-1269: Product Released in Non-Release Configuration
If a collection created via the EvolutionCollectionFactory precompile is set to allow public minting, any user of the LAOS blockchain may create new collection items corresponding to any slot not being used, pointing to any malicious URI, including URIs pointing to:
1. Browser exploits
2. Client-side attacks
3. Illegal images
4. Gross images
5. URIs that would only appear in the item after an evolution.
These may appear in the NFT related to the collection, and shown in the websites where NFTs are traded.
The severity of this issue was lowered given that public minting is not enabled by default.
Recommendation
Either whitelist the URIs (and owners) of the minted items when the minting is not made by the owner or disallow minting by a non-owner account.
If the second option is implemented an intermediate contract may be set as the owner and handle both the access and the allowed URIs to mint and or evolve items.
Status
Acknowledged. The development team informed us that they are aware of this issue but do not want to remove it yet, as it allows them to test bridgeless minting.

Summary: Public minting allows any user to create collection items with potentially malicious URIs.
Audit finding: Lack of URI Validation
Project: LAOS
Auditor: CoinFabrik
Location: pallets/asset-metadata-extender
pallets/laos-evolution
Impact: Medium
Vulnerability class (audit): CWE-1286: Improper Validation of Syntactic Correctness of Input
Vulnerability class (Scout): Error Handling and Validation
CWE: CWE-1286
Status: Unresolved

ME-01 Lack of URI Validation
Found on commit: 16bd9e56d20c206cf927d961c8ec58f299308473
Location:
- pallets/asset-metadata-extender
- pallets/laos-evolution
Classification:
- CWE-1286: Improper Validation of Syntactic Correctness of Input
The URIs received in the functions of the AssetMetadataExtender precompile and the EvolutionCollection precompile are not being validated nor canonized. These URIs are then stored and can be consulted from the state of the blockchain by other systems.
This may lead to exploiting these other systems with malformed URIs.
This issue makes the HI-01 Unrestricted URI issue more dangerous, as any account may write malformed URIs to be read by other systems.
Recommendation
In order to solve this issue, we recommend the string parameter receiving the URI parameter to be parsed to check that it conforms to the URI format.
In order to mitigate this issue, you may choose to document in the .sol files that document the interfaces of the precompiles that the format of the URI is not being validated on-chain.
Status
Unresolved.

Summary: URIs are not validated or canonized, allowing malformed URIs to be stored and potentially exploited by other systems.
Audit finding: No Logging on Minting Error
Project: LAOS
Auditor: CoinFabrik
Location: pallets/parachain-staking/src/rewards/mint_rewards.rs:50-55
Impact: Minor
Vulnerability class (audit): CWE-778: Insufficient Logging
Vulnerability class (Scout): Error Handling and Validation
CWE: CWE-778
Status: Unresolved

Minor Severity Issues
MI-01 No Logging on Minting Error
Found on commit: 16bd9e56d20c206cf927d961c8ec58f299308473
Location:
- pallets/parachain-staking/src/rewards/mint_rewards.rs: 50-55
Classification:
- CWE-778: Insufficient Logging
If funds are not deposited for the collator when making a new block, the error is not registered anywhere.
This can be seen in the following code, where there is no else clause
if let Ok(amount_transferred) = T::Currency::deposit_into_existing(&collator_id, amt) {
Self::deposit_event(Event::Rewarded {
account: collator_id.clone(),
rewards: amount_transferred.peek(),
});
}
Recommendation
Either generate an event showing the error or at least log the error.
Status
Unresolved.

Summary: Minting errors are not logged, leaving issues untraceable.
Audit finding: Lack of Universal Location Validation
Project: LAOS
Auditor: CoinFabrik
Location: pallets/asset-metadata-extender
Impact: Minor
Vulnerability class (audit): CWE-1286: Improper Validation of Syntactic Correctness of Input
Vulnerability class (Scout): Error Handling and Validation
CWE: CWE-1286
Status: Unresolved

MI-02 Lack of Universal Location Validation
Found on commit: 16bd9e56d20c206cf927d961c8ec58f299308473
Location:
- pallets/asset-metadata-extender
Classification:
- CWE-1286: Improper Validation of Syntactic Correctness of Input
When extending or updating an universal location with an URI using the extendULWithExternalURI or updateExtendedULWithExternalURI functions, the string where the universal location is received is not validated. This string is then reflected in the emitted events that can be processed by other systems. This may lead to exploiting these other systems with malformed universal locations.
This issue has less severity than the ME-01 Lack of URI Validation issue given that the universal location is reflected only in events.
Recommendation
In order to solve this issue, we recommend the string parameter receiving the universal location parameter to be parsed to check that it conforms to the URI format.
In order to mitigate this issue, you may choose to document in the .sol files that document the interfaces of the precompiles that the format of the universal location is not being validated on-chain.
Status
Unresolved.

Summary: Universal location strings are not validated, risking exploitation through malformed inputs in emitted events.
Audit finding: Claiming rewards while the deduction rate is != 0 , allows for repeated withdrawal of redistributed rewards
Project: Acala
Auditor: Code4Arena
Location: src/modules/incentives/src/lib.rs:451-457
Impact: Medium
Vulnerability class (Scout): Business Logic
Status: This is intended behaviour and non issue.

[M-01] Claiming rewards while the deduction rate is != 0 allows for repeated withdrawal of redistributed rewards
Submitted by n4nika, also found by ABAIKUNANBAEV and djxploit
If a participant in a pool claims rewards while the deduction rate is not equal to 0, the deducted rewards are redistributed between all participants.

fn payout_reward_and_reaccumulate_reward(
  pool_id: PoolId,
  who: &T::AccountId,
  reward_currency_id: CurrencyId,
  payout_amount: Balance,
  reaccumulate_amount: Balance,
) -> DispatchResult {
  if !reaccumulate_amount.is_zero() {
    <orml_rewards::Pallet<T>>::accumulate_reward
  }
  T::Currency::transfer(reward_currency_id, &Self::
  Ok(())
}

Since the deduction is redistributed between all participants (including the one claiming the reward), they can repeatedly claim rewards and receive more from the rewards pool than intended.

Proof of Concept:

#[test]
fn repeated_claiming() {
  ExtBuilder::default().build().execute_with(|| {
    assert_ok!(TokensModule::deposit(BTC, &VAULT::get()));
    assert_ok!(IncentivesModule::update_claim_reward_deduction(RuntimeOrigin::signed(ROOT::get()), vec![(PoolId::Dex(BTC_AUSD_LP), Rate::new(400)]));
    
    // 40% deduction rate
    assert_ok!(IncentivesModule::update_claim_reward_deduction(RuntimeOrigin::signed(ROOT::get()), vec![(PoolId::Dex(BTC_AUSD_LP), Rate::new(400)]));

    // Add participants with equal shares
    TokensModule::deposit(BTC_AUSD_LP, &ALICE::get());
    TokensModule::deposit(BTC_AUSD_LP, &BOB::get());
    IncentivesModule::update_incentive_rewards();

    // ALICE claims her reward and should receive the full deduction-adjusted amount
    assert_ok!(IncentivesModule::claim_rewards(&ALICE));
    let btc_before = TokensModule::total_balance();

    // ALICE claims again after redistribution
    assert_ok!(IncentivesModule::claim_rewards(&ALICE));
    let btc_after = TokensModule::total_balance();

    assert_eq!(btc_before, btc_after);
  });
}

Recommended Mitigation Steps:
Add the claiming user to accumulate_rewards and implement reaccumulating rewards excluding the calling user.

xlc (Acala) disputed and commented: This is intended behavior and not an issue.

Summary: Participants can repeatedly claim redistributed rewards when the deduction rate is not zero, allowing them to gain more rewards than intended.