Submitted by J4X, also found by tsvetanovv
The HydraDx protocol includes an oracle. This oracle generates prices, based upon the information it receives from its sources (of which Omnipool is one). The Omnipool provides information to the oracle through the on_liquidity_changed and on_trade hooks. Whenever a trade happens or the liquidity in one of the pools changes the corresponding hooks need to be called with the updated values.
The Omnipool contract also includes the remove_token() function. This function can only be called by the authority and can be only called on an asset which is FROZEN and where all the liquidity shares are owned by the protocol.
When the function gets called it transfers all remaining liquidity to the beneficiary and removes the token. This is a change in liquidity in the Omnipool. The functionality in terms of liquidity change is similar to the withdraw_protocol_liquidity() where the protocol also withdraws liquidity in the form of protocol_shares from the pool. When looking at the withdraw_protocol_liquidity() function, one can see that it calls the on_liquidity_changed hook at the end, so that the oracle receives the information about the liquidity change.
Unfortunately, the  remove_token() function does not call this hook, keeping the oracle in an outdated state. As the token is removed later on, the oracle will calculate based on liquidity that does not exist anymore in the Omnipool.
The issue results in the oracle receiving incorrect information and calculating new prices, based on an outdated state of the Omnipool.
The issue can be viewed when looking at the code of remove_token() where one can see that no call to the hook happens:
The issue can be mitigated by forwarding the updated asset state to the oracle by calling the on_liquidity_changed hook.
Oracle
enthusiastmartin (HydraDX) disputed and commented via duplicate issue #141:
J4X (warden) commented:
Lambda (judge) commented:
