code-423n4 / 2024-03-acala-findings

0 stars 0 forks source link

Unnecessary iteration increases gas costs and decreases performance efficiency. #65

Closed c4-bot-8 closed 5 months ago

c4-bot-8 commented 5 months ago

Lines of code

https://github.com/code-423n4/2024-03-acala/blob/9c71c05cf2d9f0a2603984c50f76fc8a315d4d65/src/orml/rewards/src/lib.rs#L191-L251

Vulnerability details

There is a potential performance inefficiency when updating withdrawn rewards for reward currencies in which the user has no balance.

Impact

Issue Description

It is expected to update the user's share balance, the pool's total shares, and the user's withdrawn rewards correctly based on the removed share amount.

The remove_share() function behaves as expected, updating the share balances and withdrawn rewards correctly. However, it iterates through all reward currencies, even for currencies in which the user has no balance, leading to unnecessary computation. That's my point.

Proof of Concept

https://github.com/code-423n4/2024-03-acala/blob/9c71c05cf2d9f0a2603984c50f76fc8a315d4d65/src/orml/rewards/src/lib.rs#L191-L251

fn remove_share(who: &T::AccountId, pool: &T::PoolId, remove_amount: T::Share) {
    // ... (existing code)

    // Update withdrawn rewards for each reward currency
    withdrawn_rewards
        .iter_mut()
        .for_each(|(reward_currency, withdrawn_reward)| {
            // ... (existing code)
        });

    // ... (existing code)
}

Tools Used

Manual Audit

Recommended Mitigation Steps

Consider modifying the iteration over reward currencies to only update withdrawn rewards for currencies in which the user has a non-zero balance.

     fn remove_share(who: &T::AccountId, pool: &T::PoolId, remove_amount: T::Share) {
         // ... (existing code)

         // Update withdrawn rewards only for currencies with non-zero user balance
         for (reward_currency, withdrawn_reward) in user_reward_currencies(who) {
             if let Some((total_reward, total_withdrawn_reward)) = pool_info.rewards.get_mut(reward_currency) {
                 // ... (existing code)
             }
         }

         // ... (existing code)
     }

Assessed type

Loop

c4-pre-sort commented 5 months ago

DadeKuma marked the issue as insufficient quality report

DadeKuma commented 5 months ago

Spam

c4-judge commented 5 months ago

OpenCoreCH marked the issue as unsatisfactory: Insufficient quality