The Auction contract calculates the cost of purchasing ZENO tokens by multiplying the current auction price (obtained via getPrice()
) by the desired token amount. However, the buy
function does not enforce any slippage protection, such as a minimum acceptable token output or a maximum cost parameter. As a result, users are exposed to adverse price movements during transaction confirmation, which can lead to unexpectedly high costs for token purchases.
Absence of Slippage Protection:
In the buy
function, the cost is calculated as follows:
The function then processes the transfer using:
There is no mechanism to verify that the cost remains within a user-specified acceptable range, leaving users vulnerable if the price fluctuates between transaction initiation and confirmation.
Lack of User-Defined Price Boundaries:
Users are not provided with an option to set a minimum acceptable token output or a maximum acceptable cost.
Without such parameters, the auction process does not safeguard bidders against unfavorable price movements that can occur during the transaction confirmation period.
Potential for Unintended Overpayment:
The absence of slippage checks means that if the auction price increases unexpectedly, users may end up paying significantly more USDC than anticipated for the same amount of ZENO tokens.
This not only harms the user experience but also undermines trust in the auction process.
Adverse Price Execution:
Users may be forced to purchase ZENO tokens at a higher cost than expected if the auction price shifts unfavorably during the transaction window.
User Financial Loss:
Bidders could incur unexpected extra costs, leading to potential financial loss when the final executed cost exceeds their planned expenditure.
Assume:
A bidder intends to purchase 100 ZENO tokens.
At the time of transaction initiation, getPrice()
returns a price P
, resulting in an expected cost of 100 * P
USDC.
However, due to rapid auction dynamics or network delays, the auction price increases to P'
by the time the transaction is confirmed.
Since there is no slippage protection, the final cost becomes 100 * P'
USDC, which could be significantly higher than anticipated.
Steps:
The bidder calls buy(100)
when the auction is active.
The function retrieves the price P
and calculates the cost as 100 * P
.
Before the transaction is confirmed, the auction price changes to P'
.
The transaction is confirmed, and the contract recalculates or effectively uses the updated price, resulting in a cost of 100 * P'
.
Result:
The bidder ends up overpaying due to the price increase, as there was no mechanism to enforce a slippage limit or minimum acceptable output.
Manual review
Implement Slippage Protection:
Add a parameter to the buy
function (e.g., maxCost
or minAmountOut
) to allow users to specify acceptable limits for price fluctuations.
Update the function logic to enforce that the computed cost does not exceed the user's specified threshold:
Alternatively, provide a minAmountOut
parameter to ensure users receive a minimum amount of tokens for their USDC.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.