Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ambitious Cedar Monkey - ETH <=> NUMA conversion is subject to price manipulation #246

Open
sherlock-admin4 opened this issue Dec 31, 2024 · 0 comments

Comments

@sherlock-admin4
Copy link

Ambitious Cedar Monkey

High

ETH <=> NUMA conversion is subject to price manipulation

Summary

Per the audit README, the protocol will be deployed on ETH (hence it is safe to assume frontrunning by MEV bots is possible)

https://github.com/sherlock-audit/2024-12-numa-audit/blob/main/Numa/contracts/NumaProtocol/NumaOracle.sol#L270

https://github.com/sherlock-audit/2024-12-numa-audit/blob/main/Numa/contracts/NumaProtocol/NumaOracle.sol#L168

https://github.com/sherlock-audit/2024-12-numa-audit/blob/main/Numa/contracts/NumaProtocol/NumaOracle.sol#L341-L342

The sqrtPriceX96 is pulled from Uniswap.slot0, which is the most recent data point and can be manipulated easily via MEV bots and Flashloans with sandwich attacks, which can cause the loss of funds as it is used in the protocol to evaluate getV3SqrtLowestPrice() and getV3SqrtHighestPrice

Root Cause

File: NumaOracle.sol
164:     function getV3SpotPrice(
165:         address _numaPool,
166:         uint _numaAmount
167:     ) external view returns (uint256) {
168:  @>     (uint160 sqrtPriceX96, , , , , , ) = IUniswapV3Pool(_numaPool).slot0();


257:     function getV3SqrtLowestPrice(
258:         address _uniswapV3Pool,
259:         uint32 _intervalShort,
260:         uint32 _intervalLong
261:     ) public view returns (uint160) {
262:         require(
263:             _intervalLong > _intervalShort,
264:             "intervalLong must be longer than intervalShort"
265:         );
266: 
267:         uint160 sqrtPriceX96;
268: 
269:         //Spot price of the token
270:    @>   (uint160 sqrtPriceX96Spot, , , , , , ) = IUniswapV3Pool(_uniswapV3Pool)
271:             .slot0();


329:     function getV3SqrtHighestPrice(
330:         address _uniswapV3Pool,
331:         uint32 _intervalShort,
332:         uint32 _intervalLong
333:     ) public view returns (uint160) {
334:         require(
335:             _intervalLong > _intervalShort,
336:             "intervalLong must be longer than intervalShort"
337:         );
338: 
339:         uint160 sqrtPriceX96;
340:         //Spot price of the token
341:   @>    (uint160 sqrtPriceX96Spot, , , , , , ) = IUniswapV3Pool(_uniswapV3Pool)
342:             .slot0();

Internal pre-conditions

No response

External pre-conditions

No response

Attack Path

No response

Impact

Price evaluation when EH<->NUMA convertions can be manipulated

PoC

No response

Mitigation

Consider using TWAP pricing instead of slot0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant