Omniscia Steadefi Audit
TraderJoeYieldFarmReader Manual Review Findings
TraderJoeYieldFarmReader Manual Review Findings
TJF-01M: Inexplicable Delta Return
Type | Severity | Location |
---|---|---|
Logical Fault | TraderJoeYieldFarmReader.sol:L140 |
Description:
The TraderJoeYieldFarmReader::delta
function returns an arbitrary delta evaluation that does not appear to be base 1e18
as the zero-value conditional within it yields 1
instead of 1e18
.
Impact:
While the code is incorrect as it yields 1
when the _tokenAAmt
and _tokenADebtAmt
values are 0
, its impact cannot be assessed as it is not in use within the codebase.
Example:
132/**133 * Current delta: token A equity value / vault's equityValue; possible to be negative value134 * @return delta Current delta in 1e18135*/136function delta() public view returns (int) {137 (uint256 _tokenAAmt,) = manager.assetInfo();138 (uint256 _tokenADebtAmt,) = manager.debtInfo();139
140 if (_tokenAAmt == 0 && _tokenADebtAmt == 0) return 1;141
142 return (int(_tokenAAmt) - int(_tokenADebtAmt))143 * int(to18ConversionFactor(tokenA()))144 * int(priceOracle.consult(tokenA()))145 / int(equityValue());146}
Recommendation:
We advise more documentation to be introduced for the TraderJoeYieldFarmReader::delta
function, such as its expected usage as well as why only TraderJoeYieldFarmReader::tokenA
is considered in its calculations. Additionally, we advise the return
statement to yield either 0
or 1e8
instead of 1
as a "delta" of 1
is incorrect.
Alleviation (4325253d6de0ea91c1e9fb9e01d2e7e98f3d83a9):
The function correctly yields 0
when the token A debt and asset amounts are zero in the latest implementation, addressing the exhibit's highlighted ambiguity.
TJF-02M: Potentially Incorrect Default Values
Type | Severity | Location |
---|---|---|
Logical Fault | TraderJoeYieldFarmReader.sol:L128, L154 |
Description:
The default values yielded whenever either of the variables utilized in the respective divisions is zero appears to be incorrect as it is always zero even when the denominator of the division is zero.
Impact:
The impact of this exhibit cannot be assessed as it depends on how the relevant data points are utilized.
Example:
148/**149 * Debt ratio: token A and token B debt value / total asset value150 * @return debtRatio Current debt ratio % in 1e18151*/152function debtRatio() public view returns (uint256) {153 (uint256 tokenADebtValue, uint256 tokenBDebtValue) = debtValue();154 if (assetValue() == 0) return 0;155 return (tokenADebtValue + tokenBDebtValue) * SAFE_MULTIPLIER / assetValue();156}
Recommendation:
We advise the return
statements to yield "infinity" (type(uint256).max
) when the denominator is zero, representing that the system is in a significantly abnormal state (i.e. a non-zero TraderJoeYieldFarmReader::debtValue
and a zero TraderJoeYieldFarmReader::assetValue
).
Alleviation (4325253d6de0ea91c1e9fb9e01d2e7e98f3d83a9):
The Steadefi team evaluated this exhibit and outlined that the likelihood of a non-zero debt when the TraderJoeYieldFarmReader::assetValue
evaluates to 0
is highly improbable, rendering the exhibit's rationale incorrect. As such, we consider this exhibit nullified.
TJF-03M: Unsafe Casting Operations
Type | Severity | Location |
---|---|---|
Mathematical Operations | TraderJoeYieldFarmReader.sol:L142, L145 |
Description:
The referenced statements perform a casting operation from the uint256
data type to the int256
data type which is unsafe.
Impact:
Unsafe casting operations can result in normally positive variables to become negative, significantly affecting all relevant arithmetic operations.
Example:
132/**133 * Current delta: token A equity value / vault's equityValue; possible to be negative value134 * @return delta Current delta in 1e18135*/136function delta() public view returns (int) {137 (uint256 _tokenAAmt,) = manager.assetInfo();138 (uint256 _tokenADebtAmt,) = manager.debtInfo();139
140 if (_tokenAAmt == 0 && _tokenADebtAmt == 0) return 1;141
142 return (int(_tokenAAmt) - int(_tokenADebtAmt))143 * int(to18ConversionFactor(tokenA()))144 * int(priceOracle.consult(tokenA()))145 / int(equityValue());146}
Recommendation:
We advise the code to perform the casting operations safely, preferably via the usage of a library such as SafeCast
by OpenZeppelin. To note, the usage of a 0.8.X
compiler with built-in safe arithmetics does not cover casting operations which still need to be manually validated**.
If the usage of a library is undesirable, we advise the casting statements to be accompanied by require
checks that ensure the casted values are less-than-or-equal to the maximum an int256
variable can hold (type(int256).max
).
Alleviation (4325253d6de0ea91c1e9fb9e01d2e7e98f3d83a9):
The calculations were significantly simplified, performing a single casting operation at the end of the calculation chain optimally and securely.