Incorrect operator in _tweakPrice
Description
The _tweakPrice
function adjusts the priceOracle
, lastPrices
and priceScale
variables, used in the calculation of the prices within the pool. This function is an essential component of the pool, and is called whenever there is an inbalance during any of the liquidity operations, such as swap, mint or burn.
The Vyper code (in tweak_price
in the Curve twoCrypto V2 pool) has the following code:
# If A and gamma are not undergoing ramps (t < block.timestamp),
# ensure new virtual_price is not less than old virtual_price,
# else the pool suffers a loss.
if self.future_A_gamma_time < block.timestamp:
assert virtual_price > old_virtual_price, "Loss"
The inverse of >
in the assertion is <=
. However, the Solidity code (in _tweakPrice
in SyncSwapCryptoPool) ports the above code as follows, using the <
operator:
if (_futureTime < block.timestamp) {
if (it.virtualPrice < it.oldVirtualPrice) {
revert Loss();
}
}
Impact
The above code may not revert in all cases intended by the original Vyper code, and it is not logically equivalent.
Recommendations
Use the <=
operator instead of <
.
if (_futureTime < block.timestamp) {
- if (it.virtualPrice < it.oldVirtualPrice) {
+ if (it.virtualPrice <= it.oldVirtualPrice) {
revert Loss();
}
}
Remediation
This issue has been acknowledged by SyncSwap Labs, and a fix was implemented in commit ff28d01a↗.