-
Notifications
You must be signed in to change notification settings - Fork 0
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
NoyaValueOracle.getValue
returns an incorrect price when a multi-token route is used
#1430
Labels
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Something isn't working
H-03
primary issue
Highest quality submission among a set of duplicates
🤖_22_group
AI based duplicate group recommendation
satisfactory
satisfies C4 submission criteria; eligible for awards
selected for report
This submission will be included/highlighted in the audit report
sponsor confirmed
Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
sufficient quality report
This report is of sufficient quality
Comments
DadeKuma marked the issue as primary issue |
This was referenced May 18, 2024
Closed
Closed
DadeKuma marked the issue as sufficient quality report |
true, needs to be fixed |
gzeon-c4 marked the issue as satisfactory |
gzeon-c4 marked the issue as selected for report |
fix in 66d4104e83cc1b68ab117c78c4a92eafac86341c |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Something isn't working
H-03
primary issue
Highest quality submission among a set of duplicates
🤖_22_group
AI based duplicate group recommendation
satisfactory
satisfies C4 submission criteria; eligible for awards
selected for report
This submission will be included/highlighted in the audit report
sponsor confirmed
Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
sufficient quality report
This report is of sufficient quality
Lines of code
https://github.com/code-423n4/2024-04-noya/blob/9c79b332eff82011dcfa1e8fd51bad805159d758/contracts/helpers/valueOracle/NoyaValueOracle.sol#L89
Vulnerability details
The NoyaValueOracle.getValue is used to convert the price of an
asset
tobaseToken
, using token routing when necessary.If there is no oracle for two tokens, a route needs to be set up between them. This route can then be used to get a value using NoyaValueOracle.getValue.
However, there's a mistake in the NoyaValueOracle.getValue function that makes it give the wrong price.
Impact
The NoyaValueOracle.getValue will return incorrect prices for tokens when the configured priceRoutes[asset][baseToken].length is more than 1.
Proof of Concept
To set a price path for a token pair, the maintainer should use NoyaValueOracle.updatePriceRoute.
For instance, for the
SOL
toUNI
conversion. 1SOL
is roughly equal to 21UNI
, but there's no direct oracle. So, the maintainer sets a routeSOL
→BNB
→ETH
→UNI
.When _getValue tries to convert 100
SOL
intoUNI
, it should first convertSOL
→BNB
, thenBNB
→ETH
, and lastlyETH
→UNI
. But, what _getValue really does is to convertSOL
→BNB
,SOL
→ETH
, andSOL
→UNI
.You can see this error in the _getValue function, where
asset
is used each time instead ofquotingToken
.function _getValue(address asset, address baseToken, uint256 amount, address[] memory sources) internal view returns (uint256 value) { uint256 initialValue = amount; address quotingToken = asset; for (uint256 i = 0; i < sources.length; i++) { > initialValue = _getValue(asset, sources[i], initialValue); quotingToken = sources[i]; } return _getValue(quotingToken, baseToken, initialValue); }
The first problem comes up if the
SOL
→BNB
,SOL
→ETH
, andSOL
→UNI
oracles are not set up. This will cause a revert of _getValue.function _getValue(address quotingToken, address baseToken, uint256 amount) internal view returns (uint256) { INoyaValueOracle oracle = priceSource[quotingToken][baseToken]; if (address(oracle) == address(0)) { oracle = priceSource[baseToken][quotingToken]; } if (address(oracle) == address(0)) { oracle = defaultPriceSource[baseToken]; } if (address(oracle) == address(0)) { oracle = defaultPriceSource[quotingToken]; } if (address(oracle) == address(0)) { > revert NoyaOracle_PriceOracleUnavailable(quotingToken, baseToken); } return oracle.getValue(quotingToken, baseToken, amount); }
Even if we configure these oracles, the calculated value will still be incorrect.
Consider this example - the _getValue is called with the following parameters:
This will convert 100
SOL
toUNI
, usingBNB
andETH
as the route.The result is calculated using
quotingToken
= ETH,baseToken
= UNI, and theinitialValue
= 1.25, which returns 526.However, the expected result should be 2094.
Tools Used
Manual Review
Recommended Mitigation Steps
Replace
asset
withquotingToken:
Assessed type
Oracle
The text was updated successfully, but these errors were encountered: