DevABDee - `XOracle.putPrice()` Can Fall Victim to Front-running Attacks: Attackers Can Make Quick Profits, while Users Can Avoid Loss and even Turn the Potential Loss into Profits. #105
XOracle.putPrice() Can Fall Victim to Front-running Attacks: Attackers Can Make Quick Profits, while Users Can Avoid Loss and even Turn the Potential Loss into Profits.
Summary
XOracle.putPrice() (& updatePrices()), which sets and updates the price of the supported tokens, especially EMC tokens. However, this functionality can be vulnerable to exploitation by attackers and malicious users.
Vulnerability Detail
Proof-of-concept
Attackers Can Make Quick Profits:
Suppose, 1 USD = 82 INR. (1 USD1 = 82 USD91)
INR appriciates and the USD/INR price goes to 80. (1 USD1 = 80 USD91)
The PriceFeeder calls the putPrice function to update the price of the USD91 to its new value.
The Attacker monitors the mempool and observes the PriceFeeder's transaction to update the USD91 price.
Sensing an opportunity, the Attacker front runs the PriceFeeder's transaction by submitting their own transaction with a higher gas fee.
The Attacker calls the Unitas.swap() function to purchase 5 Million USD91 tokens with paying High Gas Fee.
Due to the higher gas fee, the Attacker's transaction gets executed before the PriceFeeder's transaction, granting the Attacker ownership of the 5 Million USD91 tokens at the previous price of 82
After the PriceFeeder's transaction is eventually executed and the price is updated to 80, the Attacker decides to sell all the USD91 he acquired.
Capitalizing on the price increase, the Attacker successfully sells the 5M USD91 tokens at the new price of 80.
Attacker makes a quick $1500+ profit.
An attacker can create a very large profit using Flahloans.
Furthermore, Malicious users can prevent losses and even turn the potential loss into profits:
Suppose Bob holds 10 Million USD91 tokens
USD91 price depreciates from 82 to 85
PriceFeeder calls the putPrice function to update the price of the USD91 to its new value.
Bob sees that TRX is in mempool and front runs it.
Bob sells all his 10 Million USD91 tokens @ 82 and gets 121951.22 USD
After the price updates successfully to 85
Bob buyback USD91 with 121951.22 USD, and now he got 10365853 USD91
Bob successfully not only avoids price depreciation loss but also turn it into 365853 USD91 profit
Impact
Frontrun Attacks
Market Manipulation
Attackers have the ability to make quick profits, while users can prevent losses and even turn the potential loss into profits
To ensure the security of price updates, it is advised to implement the following measures:
Pause Swapping:
Since the function Unitas.swap() is already designed to be pausable, it is advisable to pause swapping before the Feeder updates the price. This will prevent any inconsistencies or undesired effects during the price update process.
Implement an Oracle:
It is highly recommended to use Oracle for pricing. Relying on manual price updates can make the system susceptible to attacks and vulnerabilities. An Oracle provides a secure and reliable source of real-time price data, reducing the risk of manipulation or inaccuracies.
Delay Mechanism:
Consider implementing a delay mechanism specifically for the Unitas.swap() function. This delay mechanism can introduce a time delay between the initiation of the swap and its execution. The purpose of this delay is to allow sufficient time for any potential price updates or changes to be processed and validated by Oracle, ensuring that the swap occurs at the most accurate and up-to-date price.
Additional Note:
Regarding the putPrice(), the protocol wrote this in the contest page's already known issues section:
When users are performing a swap, if they encounter an Oracle price update within the same block, they may exchange at a different price than originally expected. Our Oracle price feeder does not have a fixed update time, but the chances of encountering this situation are very low. We plan to implement checks in phase 2 to address this.
Risk: very low.
I believe the protocol may have overlooked the potential attack vector associated with the issue from an attacker's perspective. This vulnerability can be exploited by malicious users and attackers, resulting in substantial profits. Bots, in particular, can take advantage of this loophole and ruthlessly capitalize on the situation. Therefore, it is essential to prioritize the mitigation of this issue during the current phase of development. Thanks
DevABDee
high
XOracle.putPrice()
Can Fall Victim to Front-running Attacks: Attackers Can Make Quick Profits, while Users Can Avoid Loss and even Turn the Potential Loss into Profits.Summary
XOracle.putPrice()
(&updatePrices()
), which sets and updates the price of the supported tokens, especially EMC tokens. However, this functionality can be vulnerable to exploitation by attackers and malicious users.Vulnerability Detail
Proof-of-concept
Attackers Can Make Quick Profits:
putPrice
function to update the price of the USD91 to its new value.Unitas.swap()
function to purchase 5 Million USD91 tokens with paying High Gas Fee.An attacker can create a very large profit using Flahloans.
Furthermore, Malicious users can prevent losses and even turn the potential loss into profits:
putPrice
function to update the price of the USD91 to its new value.Impact
Attackers have the ability to make quick profits, while users can prevent losses and even turn the potential loss into profits
Code Snippet
https://github.com/sherlock-audit/2023-04-unitasprotocol/blob/d5328421bea80e3b0fd4595e4eb6b732a40e421e/Unitas-Protocol/src/XOracle.sol#L26
https://github.com/sherlock-audit/2023-04-unitasprotocol/blob/d5328421bea80e3b0fd4595e4eb6b732a40e421e/Unitas-Protocol/src/XOracle.sol#L34
https://github.com/sherlock-audit/2023-04-unitasprotocol/blob/d5328421bea80e3b0fd4595e4eb6b732a40e421e/Unitas-Protocol/src/Unitas.sol#L208
Tool used
Shaheen's Vision
Recommendation
To ensure the security of price updates, it is advised to implement the following measures:
Pause Swapping: Since the function
Unitas.swap()
is already designed to be pausable, it is advisable to pause swapping before the Feeder updates the price. This will prevent any inconsistencies or undesired effects during the price update process.Implement an Oracle: It is highly recommended to use Oracle for pricing. Relying on manual price updates can make the system susceptible to attacks and vulnerabilities. An Oracle provides a secure and reliable source of real-time price data, reducing the risk of manipulation or inaccuracies.
Delay Mechanism: Consider implementing a delay mechanism specifically for the
Unitas.swap()
function. This delay mechanism can introduce a time delay between the initiation of the swap and its execution. The purpose of this delay is to allow sufficient time for any potential price updates or changes to be processed and validated by Oracle, ensuring that the swap occurs at the most accurate and up-to-date price.Additional Note:
Regarding the
putPrice()
, the protocol wrote this in the contest page's already known issues section:I believe the protocol may have overlooked the potential attack vector associated with the issue from an attacker's perspective. This vulnerability can be exploited by malicious users and attackers, resulting in substantial profits. Bots, in particular, can take advantage of this loophole and ruthlessly capitalize on the situation. Therefore, it is essential to prioritize the mitigation of this issue during the current phase of development. Thanks
Duplicate of #67