Closed c4-bot-9 closed 7 months ago
0xRobocop marked the issue as primary issue
0xRobocop marked the issue as sufficient quality report
No issue at all. That's how substrate works with public functions.
Why would you bother with this - if you can call Balances::transfer, which is also public function.
enthusiastmartin (sponsor) disputed
This is not valid report.
Public functions in substarte are designed to work with other pallets if needed to be.
Attacker cannot call this function as it is not possible deploy custom code/contract which would call this.
This is how substrate works.
If you could deploy custom code and call public functions- you can easily just call transfer functions and transfers any amounts you want, as this functionality is also public.
As mentioned by the sponsor, there seems to be a misunderstanding by the warden about how Substrate works. These functions cannot be called directly within a transaction because they are not marked for that, the public
is irrelevant here.
OpenCoreCH marked the issue as unsatisfactory: Invalid
Lines of code
https://github.com/code-423n4/2024-02-hydradx/blob/main/HydraDX-node/pallets/omnipool/src/lib.rs#L1975-L1981
Vulnerability details
Impact
In the
omnipool/src/lib.rs
, theupdate_asset_state()
function is a public function defined in a Pallet implementation. Since this function is clearly marked public, it can be called outside the pallet. Hence any user or smart contract within the runtime can make a call toupdate_asset_state()
and update the asset reserve state rather than through other functions that update the asset state e.g add_liquidity(), sell(), buy(), remove_liquidity().The function loads the state of an asset and updates it with given delta changes. Any user within the same runtime can make a dispatch call to this non-entristic function and update the state of the asset.
With a combination of other vulnerable functions, a malicious user can manipulate the state to their advantage for favourable liquidations
Proof of Concept
https://github.com/code-423n4/2024-02-hydradx/blob/main/HydraDX-node/pallets/omnipool/src/lib.rs#L1975-L1981
In the PoC below, for a normal transaction, LP1 is expected to have a balance of 4840 tokens of the registered asset, and 203.921568627449 amount of LRNA
but when the LP1 calls Omnipool::set_position() function with the arbritary position data, the balance of the registered token for LP1 user will be 4840 amount of tokens and 274.050464807436 amount of LRNA token
In the above PoC, the liquidity provider was able to gain more LRNA tokens after manipulating the asset reserve state.
Tools Used
Manual review
Recommended Mitigation Steps
Add an access control check to ensure the function can only be called by authorized origin. If function is not necessary, remove it.
Assessed type
Access Control