Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A malicious user can block remove_token function in Omnipool by holding a tiny amount of shares #144

Open
c4-bot-5 opened this issue Feb 29, 2024 · 3 comments
Labels
bug Something isn't working downgraded by judge Judge downgraded the risk level of this issue duplicate-180 grade-a QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax 🤖_26_group AI based duplicate group recommendation

Comments

@c4-bot-5
Copy link
Contributor

Lines of code

https://github.com/code-423n4/2024-02-hydradx/blob/main/HydraDX-node/pallets/omnipool/src/lib.rs#L1545-L1550

Vulnerability details

Impact

A malicious user can easily block the remove_token() function.

Proof of Concept

In Omnipool we have remove_token() function which is used by the admin to remove a token:

	    #[pallet::call_index(12)]
        #[pallet::weight(<T as Config>::WeightInfo::remove_token())]
        #[transactional]
        pub fn remove_token(origin: OriginFor<T>, asset_id: T::AssetId, beneficiary: T::AccountId) -> DispatchResult {
            T::AuthorityOrigin::ensure_origin(origin)?;
            let asset_state = Self::load_asset_state(asset_id)?;

            // Allow only if no shares owned by LPs and asset is frozen.
            ensure!(asset_state.tradable == Tradability::FROZEN, Error::<T>::AssetNotFrozen);
            ensure!(
                asset_state.shares == asset_state.protocol_shares, 
                Error::<T>::SharesRemaining                        
            );
            // Imbalance update
            let imbalance = <HubAssetImbalance<T>>::get();
            let hub_asset_liquidity = Self::get_hub_asset_balance_of_protocol_account();
            let delta_imbalance = hydra_dx_math::omnipool::calculate_delta_imbalance(
                asset_state.hub_reserve,
                I129 {
                    value: imbalance.value,
                    negative: imbalance.negative,
                },
                hub_asset_liquidity,
            )
            .ok_or(ArithmeticError::Overflow)?;
            Self::update_imbalance(BalanceUpdate::Increase(delta_imbalance))?;

            T::Currency::withdraw(T::HubAssetId::get(), &Self::protocol_account(), asset_state.hub_reserve)?;
            T::Currency::transfer(asset_id, &Self::protocol_account(), &beneficiary, asset_state.reserve)?;
            <Assets<T>>::remove(asset_id);
            Self::deposit_event(Event::TokenRemoved {
                asset_id,
                amount: asset_state.reserve,
                hub_withdrawn: asset_state.hub_reserve,
            }); 
            Ok(())
        }
    }

The asset or token to be removed must have its tradability status set to FROZEN and all remaining shares of the asset must belong to the protocol:

            ensure!(
                asset_state.shares == asset_state.protocol_shares, 
                Error::<T>::SharesRemaining                       
            );

This function can be potentially blocked if a malicious user holds a very small unit value of the shares. Since the function checks for exact equality between asset_state.shares and asset_state.protocol_shares, even a minuscule amount of shares held outside the protocol can prevent the asset's removal. This situation could be exploited by malicious user.

Tools Used

Visual Studio Code

Recommended Mitigation Steps

Allow a small tolerance in the shares comparison or introduce a mechanism to buy out or forcibly redeem the remaining shares under specific, strictly governed conditions.

Assessed type

Other

@c4-bot-5 c4-bot-5 added 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working labels Feb 29, 2024
c4-bot-5 added a commit that referenced this issue Feb 29, 2024
@c4-bot-13 c4-bot-13 added the 🤖_26_group AI based duplicate group recommendation label Mar 1, 2024
@c4-pre-sort
Copy link

0xRobocop marked the issue as duplicate of #180

@c4-judge
Copy link

c4-judge commented Mar 8, 2024

OpenCoreCH changed the severity to QA (Quality Assurance)

@c4-judge c4-judge added downgraded by judge Judge downgraded the risk level of this issue QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax grade-a and removed 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value labels Mar 8, 2024
@c4-judge
Copy link

c4-judge commented Mar 9, 2024

OpenCoreCH marked the issue as grade-a

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working downgraded by judge Judge downgraded the risk level of this issue duplicate-180 grade-a QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax 🤖_26_group AI based duplicate group recommendation
Projects
None yet
Development

No branches or pull requests

5 participants