Consider using OpenZeppelin’s SafeCast library to prevent unexpected overflows when casting from various type int/uint values
Summary
Type casting in Solidity without proper checks can lead to overflows or underflows, resulting in unexpected behavior. To prevent these issues, it's advised to use the SafeCast library provided by OpenZeppelin, which offers functions to safely cast between different integer sizes.
Vulnerability Detail
When casting from a larger integer type to a smaller one (e.g., uint256 to uint128), if the value exceeds the range of the target type, it can cause an overflow. Similarly, when casting from signed to unsigned types without checks, it can result in an underflow. These can introduce bugs and vulnerabilities into the smart contract.
Impact
The likelihood and impact of this issue are considered low because it would require a very specific set of circumstances to exploit an overflow or underflow resulting from an unchecked cast. However, it still represents a potential risk that should be mitigated.
Manual Review - Used my own static analyzer (still in development)
Recommendation
Incorporate OpenZeppelin's SafeCast library to perform type casting. This library provides functions like toUint256(), toUint128(), and toInt256() which include overflow and underflow checks.
kaancaglan
medium
Consider using OpenZeppelin’s
SafeCast
library to prevent unexpected overflows when casting from various type int/uint valuesSummary
Type casting in Solidity without proper checks can lead to overflows or underflows, resulting in unexpected behavior. To prevent these issues, it's advised to use the SafeCast library provided by OpenZeppelin, which offers functions to safely cast between different integer sizes.
Vulnerability Detail
When casting from a larger integer type to a smaller one (e.g., uint256 to uint128), if the value exceeds the range of the target type, it can cause an overflow. Similarly, when casting from signed to unsigned types without checks, it can result in an underflow. These can introduce bugs and vulnerabilities into the smart contract.
Impact
The likelihood and impact of this issue are considered low because it would require a very specific set of circumstances to exploit an overflow or underflow resulting from an unchecked cast. However, it still represents a potential risk that should be mitigated.
Code Snippet
Click to show findings
```solidity Path: ./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol 110: UFixed6.wrap(uint256( slot0 << (256 - 24)) >> (256 - 24)), // @audit-issue 111: UFixed6.wrap(uint256( slot0 << (256 - 24 - 24)) >> (256 - 24)), // @audit-issue 112: UFixed6.wrap(uint256( slot0 << (256 - 24 - 24 - 24)) >> (256 - 24)), // @audit-issue 113: UFixed6.wrap(uint256( slot0 << (256 - 24 - 24 - 24 - 24)) >> (256 - 24)), // @audit-issue 114: UFixed6.wrap(uint256( slot0 << (256 - 24 - 24 - 24 - 24 - 24)) >> (256 - 24)), // @audit-issue 115: UFixed6.wrap(uint256( slot0 << (256 - 24 - 24 - 24 - 24 - 24 - 24)) >> (256 - 24)), // @audit-issue 116: UFixed6.wrap(uint256( slot0 << (256 - 24 - 24 - 24 - 24 - 24 - 24 - 24)) >> (256 - 24)), // @audit-issue 117: UFixed6.wrap(uint256( slot0 << (256 - 24 - 24 - 24 - 24 - 24 - 24 - 24 - 64)) >> (256 - 64)), // @audit-issue 118: UFixed6.wrap(uint256( slot0 << (256 - 24 - 24 - 24 - 24 - 24 - 24 - 24 - 64 - 24)) >> (256 - 24)), // @audit-issue 120: UFixed6.wrap(uint256( slot1 << (256 - 24)) >> (256 - 24)), // @audit-issue 121: UFixed6.wrap(uint256( slot1 << (256 - 24 - 48)) >> (256 - 48)), // @audit-issue 122: UFixed6.wrap(uint256( slot2 << (256 - 48 - 32 - 48 - 48 - 48)) >> (256 - 48)), // @audit-issue 124: UFixed6.wrap(uint256( slot1 << (256 - 24 - 48 - 64 - 32)) >> (256 - 32)), // @audit-issue 125: UFixed6.wrap(uint256( slot1 << (256 - 24 - 48 - 64 - 32 - 32)) >> (256 - 32)), // @audit-issue 126: UFixed6.wrap(uint256( slot1 << (256 - 24 - 48 - 64 - 32 - 32 - 32)) >> (256 - 32)), // @audit-issue 127: UFixed6.wrap(uint256( slot1 << (256 - 24 - 48 - 64 - 32 - 32 - 32 - 24)) >> (256 - 24)) // @audit-issue 131: UFixed6.wrap(uint256( slot2 << (256 - 48)) >> (256 - 48)), // @audit-issue 132: UFixed6.wrap(uint256( slot2 << (256 - 48 - 32)) >> (256 - 32)) // @audit-issue 134: UFixed6.wrap(uint256( slot2 << (256 - 48 - 32 - 48)) >> (256 - 48)), // @audit-issue 135: UFixed6.wrap(uint256( slot2 << (256 - 48 - 32 - 48 - 48)) >> (256 - 48)), // @audit-issue 136: UFixed6.wrap(uint256( slot1 << (256 - 24 - 48 - 64)) >> (256 - 64)), // @audit-issue 137: uint256( slot2 << (256 - 48 - 32 - 48 - 48 - 48 - 24)) >> (256 - 24), // @audit-issue 138: 0 != (uint256( slot2 << (256 - 48 - 32 - 48 - 48 - 48 - 24 - 8)) >> (256 - 8)) // @audit-issue 185: if (newValue.staleAfter > uint256(type(uint24).max)) revert RiskParameterStorageInvalidError(); // @audit-issue 188: uint256(UFixed6.unwrap(newValue.margin) << (256 - 24)) >> (256 - 24) | // @audit-issue 189: uint256(UFixed6.unwrap(newValue.maintenance) << (256 - 24)) >> (256 - 24 - 24) | // @audit-issue 190: uint256(UFixed6.unwrap(newValue.takerFee) << (256 - 24)) >> (256 - 24 - 24 - 24) | // @audit-issue 191: uint256(UFixed6.unwrap(newValue.takerSkewFee) << (256 - 24)) >> (256 - 24 - 24 - 24 - 24) | // @audit-issue 192: uint256(UFixed6.unwrap(newValue.takerImpactFee) << (256 - 24)) >> (256 - 24 - 24 - 24 - 24 - 24) | // @audit-issue 193: uint256(UFixed6.unwrap(newValue.makerFee) << (256 - 24)) >> (256 - 24 - 24 - 24 - 24 - 24 - 24) | // @audit-issue 194: uint256(UFixed6.unwrap(newValue.makerImpactFee) << (256 - 24)) >> (256 - 24 - 24 - 24 - 24 - 24 - 24 - 24) | // @audit-issue 195: uint256(UFixed6.unwrap(newValue.makerLimit) << (256 - 64)) >> (256 - 24 - 24 - 24 - 24 - 24 - 24 - 24 - 64) | // @audit-issue 196: uint256(UFixed6.unwrap(newValue.efficiencyLimit) << (256 - 24)) >> (256 - 24 - 24 - 24 - 24 - 24 - 24 - 24 - 64 - 24); // @audit-issue 199: uint256(UFixed6.unwrap(newValue.liquidationFee) << (256 - 24)) >> (256 - 24) | // @audit-issue 200: uint256(UFixed6.unwrap(newValue.minLiquidationFee) << (256 - 48)) >> (256 - 24 - 48) | // @audit-issue 201: uint256(UFixed6.unwrap(newValue.skewScale) << (256 - 64)) >> (256 - 24 - 48 - 64) | // @audit-issue 202: uint256(UFixed6.unwrap(newValue.utilizationCurve.minRate) << (256 - 32)) >> (256 - 24 - 48 - 64 - 32) | // @audit-issue 203: uint256(UFixed6.unwrap(newValue.utilizationCurve.maxRate) << (256 - 32)) >> (256 - 24 - 48 - 64 - 32 - 32) | // @audit-issue 204: uint256(UFixed6.unwrap(newValue.utilizationCurve.targetRate) << (256 - 32)) >> (256 - 24 - 48 - 64 - 32 - 32 - 32) | // @audit-issue 205: uint256(UFixed6.unwrap(newValue.utilizationCurve.targetUtilization) << (256 - 24)) >> (256 - 24 - 48 - 64 - 32 - 32 - 32 - 24); // @audit-issue 208: uint256(UFixed6.unwrap(newValue.pController.k) << (256 - 48)) >> (256 - 48) | // @audit-issue 209: uint256(UFixed6.unwrap(newValue.pController.max) << (256 - 32)) >> (256 - 48 - 32) | // @audit-issue 210: uint256(UFixed6.unwrap(newValue.minMargin) << (256 - 48)) >> (256 - 48 - 32 - 48) | // @audit-issue 211: uint256(UFixed6.unwrap(newValue.minMaintenance) << (256 - 48)) >> (256 - 48 - 32 - 48 - 48) | // @audit-issue 212: uint256(UFixed6.unwrap(newValue.maxLiquidationFee) << (256 - 48)) >> (256 - 48 - 32 - 48 - 48 - 48) | // @audit-issue 213: uint256(newValue.staleAfter << (256 - 24)) >> (256 - 48 - 32 - 48 - 48 - 48 - 24) | // @audit-issue 214: uint256((newValue.makerReceiveOnly ? uint256(1) : uint256(0)) << (256 - 8)) >> (256 - 48 - 32 - 48 - 48 - 48 - 24 - 8); // @audit-issue ``` *GitHub*: [110](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L110-L110), [111](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L111-L111), [112](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L112-L112), [113](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L113-L113), [114](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L114-L114), [115](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L115-L115), [116](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L116-L116), [117](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L117-L117), [118](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L118-L118), [120](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L120-L120), [121](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L121-L121), [122](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L122-L122), [124](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L124-L124), [125](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L125-L125), [126](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L126-L126), [127](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L127-L127), [131](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L131-L131), [132](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L132-L132), [134](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L134-L134), [135](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L135-L135), [136](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L136-L136), [137](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L137-L137), [138](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L138-L138), [185](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L185-L185), [188](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L188-L188), [189](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L189-L189), [190](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L190-L190), [191](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L191-L191), [192](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L192-L192), [193](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L193-L193), [194](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L194-L194), [195](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L195-L195), [196](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L196-L196), [199](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L199-L199), [200](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L200-L200), [201](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L201-L201), [202](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L202-L202), [203](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L203-L203), [204](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L204-L204), [205](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L205-L205), [208](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L208-L208), [209](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L209-L209), [210](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L210-L210), [211](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L211-L211), [212](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L212-L212), [213](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L213-L213), [214](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/RiskParameter.sol#L214-L214) ```solidity Path: ./perennial-v2/packages/perennial/contracts/types/Version.sol 352: (uint256(slot0 << (256 - 8)) >> (256 - 8)) != 0, // @audit-issue 353: Accumulator6(Fixed6.wrap(int256(slot0 << (256 - 8 - 64)) >> (256 - 64))), // @audit-issue 354: Accumulator6(Fixed6.wrap(int256(slot0 << (256 - 8 - 64 - 64)) >> (256 - 64))), // @audit-issue 355: Accumulator6(Fixed6.wrap(int256(slot0 << (256 - 8 - 64 - 64 - 64)) >> (256 - 64))), // @audit-issue 356: UAccumulator6(UFixed6.wrap(uint256(slot1 << (256 - 64)) >> (256 - 64))), // @audit-issue 357: UAccumulator6(UFixed6.wrap(uint256(slot1 << (256 - 64 - 64)) >> (256 - 64))), // @audit-issue 358: UAccumulator6(UFixed6.wrap(uint256(slot1 << (256 - 64 - 64 - 64)) >> (256 - 64))) // @audit-issue 374: uint256((newValue.valid ? uint256(1) : uint256(0)) << (256 - 8)) >> (256 - 8) | // @audit-issue 375: uint256(Fixed6.unwrap(newValue.makerValue._value) << (256 - 64)) >> (256 - 8 - 64) | // @audit-issue 376: uint256(Fixed6.unwrap(newValue.longValue._value) << (256 - 64)) >> (256 - 8 - 64 - 64) | // @audit-issue 377: uint256(Fixed6.unwrap(newValue.shortValue._value) << (256 - 64)) >> (256 - 8 - 64 - 64 - 64); // @audit-issue 379: uint256(UFixed6.unwrap(newValue.makerReward._value) << (256 - 64)) >> (256 - 64) | // @audit-issue 380: uint256(UFixed6.unwrap(newValue.longReward._value) << (256 - 64)) >> (256 - 64 - 64) | // @audit-issue 381: uint256(UFixed6.unwrap(newValue.shortReward._value) << (256 - 64)) >> (256 - 64 - 64 - 64); // @audit-issue ``` *GitHub*: [352](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Version.sol#L352-L352), [353](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Version.sol#L353-L353), [354](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Version.sol#L354-L354), [355](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Version.sol#L355-L355), [356](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Version.sol#L356-L356), [357](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Version.sol#L357-L357), [358](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Version.sol#L358-L358), [374](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Version.sol#L374-L374), [375](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Version.sol#L375-L375), [376](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Version.sol#L376-L376), [377](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Version.sol#L377-L377), [379](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Version.sol#L379-L379), [380](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Version.sol#L380-L380), [381](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Version.sol#L381-L381) ```solidity Path: ./perennial-v2/packages/perennial/contracts/types/Local.sol 119: uint256(slot0 << (256 - 32)) >> (256 - 32), // @audit-issue 120: uint256(slot0 << (256 - 32 - 32)) >> (256 - 32), // @audit-issue 121: Fixed6.wrap(int256(slot0 << (256 - 32 - 32 - 64)) >> (256 - 64)), // @audit-issue 122: UFixed6.wrap(uint256(slot0 << (256 - 32 - 32 - 64 - 64)) >> (256 - 64)), // @audit-issue 123: (uint256(slot0) << (256 - 32 - 32 - 64 - 64 - 32)) >> (256 - 32) // @audit-issue 128: if (newValue.currentId > uint256(type(uint32).max)) revert LocalStorageInvalidError(); // @audit-issue 129: if (newValue.latestId > uint256(type(uint32).max)) revert LocalStorageInvalidError(); // @audit-issue 133: if (newValue.protection > uint256(type(uint32).max)) revert LocalStorageInvalidError(); // @audit-issue 136: uint256(newValue.currentId << (256 - 32)) >> (256 - 32) | // @audit-issue 137: uint256(newValue.latestId << (256 - 32)) >> (256 - 32 - 32) | // @audit-issue 138: uint256(Fixed6.unwrap(newValue.collateral) << (256 - 64)) >> (256 - 32 - 32 - 64) | // @audit-issue 139: uint256(UFixed6.unwrap(newValue.reward) << (256 - 64)) >> (256 - 32 - 32 - 64 - 64) | // @audit-issue 140: uint256(newValue.protection << (256 - 32)) >> (256 - 32 - 32 - 64 - 64 - 32); // @audit-issue ``` *GitHub*: [119](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Local.sol#L119-L119), [120](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Local.sol#L120-L120), [121](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Local.sol#L121-L121), [122](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Local.sol#L122-L122), [123](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Local.sol#L123-L123), [128](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Local.sol#L128-L128), [129](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Local.sol#L129-L129), [133](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Local.sol#L133-L133), [136](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Local.sol#L136-L136), [137](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Local.sol#L137-L137), [138](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Local.sol#L138-L138), [139](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Local.sol#L139-L139), [140](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Local.sol#L140-L140) ```solidity Path: ./perennial-v2/packages/perennial/contracts/types/Position.sol 445: uint256(slot0 << (256 - 32)) >> (256 - 32), // @audit-issue 446: UFixed6.wrap(uint256(slot1 << (256 - 64)) >> (256 - 64)), // @audit-issue 447: UFixed6.wrap(uint256(slot0 << (256 - 32 - 48 - 48 - 64)) >> (256 - 64)), // @audit-issue 448: UFixed6.wrap(uint256(slot0 << (256 - 32 - 48 - 48 - 64 - 64)) >> (256 - 64)), // @audit-issue 449: Fixed6.wrap(int256(slot0 << (256 - 32 - 48)) >> (256 - 48)), // @audit-issue 450: UFixed6.wrap(uint256(slot0 << (256 - 32 - 48 - 48)) >> (256 - 48)), // @audit-issue 454: Fixed6.wrap(int256(slot1 << (256 - 64 - 64)) >> (256 - 64)), // @audit-issue 455: Fixed6.wrap(int256(slot1 << (256 - 64 - 64 - 64)) >> (256 - 64)), // @audit-issue 456: Fixed6.wrap(int256(slot1 << (256 - 64 - 64 - 64 - 64)) >> (256 - 64)) // @audit-issue 469: uint256(newValue.timestamp << (256 - 32)) >> (256 - 32) | // @audit-issue 470: uint256(Fixed6.unwrap(newValue.fee) << (256 - 48)) >> (256 - 32 - 48) | // @audit-issue 471: uint256(UFixed6.unwrap(newValue.keeper) << (256 - 48)) >> (256 - 32 - 48 - 48) | // @audit-issue 472: uint256(UFixed6.unwrap(newValue.long) << (256 - 64)) >> (256 - 32 - 48 - 48 - 64) | // @audit-issue 473: uint256(UFixed6.unwrap(newValue.short) << (256 - 64)) >> (256 - 32 - 48 - 48 - 64 - 64); // @audit-issue 475: uint256(UFixed6.unwrap(newValue.maker) << (256 - 64)) >> (256 - 64) | // @audit-issue 476: uint256(Fixed6.unwrap(newValue.invalidation.maker) << (256 - 64)) >> (256 - 64 - 64) | // @audit-issue 477: uint256(Fixed6.unwrap(newValue.invalidation.long) << (256 - 64)) >> (256 - 64 - 64 - 64) | // @audit-issue 478: uint256(Fixed6.unwrap(newValue.invalidation.short) << (256 - 64)) >> (256 - 64 - 64 - 64 - 64); // @audit-issue 510: uint256 direction = uint256(slot1 << (256 - 2)) >> (256 - 2); // @audit-issue 511: UFixed6 magnitude = UFixed6.wrap(uint256(slot1 << (256 - 2 - 62)) >> (256 - 62)); // @audit-issue 514: uint256(slot0 << (256 - 32)) >> (256 - 32), // @audit-issue 518: Fixed6.wrap(int256(slot0 << (256 - 32 - 48)) >> (256 - 48)), // @audit-issue 519: UFixed6.wrap(uint256(slot0 << (256 - 32 - 48 - 48)) >> (256 - 48)), // @audit-issue 520: Fixed6.wrap(int256(slot0 << (256 - 32 - 48 - 48 - 64)) >> (256 - 64)), // @audit-issue 521: Fixed6.wrap(int256(slot0 << (256 - 32 - 48 - 48 - 64 - 64)) >> (256 - 64)), // @audit-issue 523: Fixed6.wrap(int256(slot1 << (256 - 2 - 62 - 64)) >> (256 - 64)), // @audit-issue 524: Fixed6.wrap(int256(slot1 << (256 - 2 - 62 - 64 - 64)) >> (256 - 64)), // @audit-issue 525: Fixed6.wrap(int256(slot1 << (256 - 2 - 62 - 64 - 64 - 64)) >> (256 - 64)) // @audit-issue 540: uint256(newValue.timestamp << (256 - 32)) >> (256 - 32) | // @audit-issue 541: uint256(Fixed6.unwrap(newValue.fee) << (256 - 48)) >> (256 - 32 - 48) | // @audit-issue 542: uint256(UFixed6.unwrap(newValue.keeper) << (256 - 48)) >> (256 - 32 - 48 - 48) | // @audit-issue 543: uint256(Fixed6.unwrap(newValue.collateral) << (256 - 64)) >> (256 - 32 - 48 - 48 - 64) | // @audit-issue 544: uint256(Fixed6.unwrap(newValue.delta) << (256 - 64)) >> (256 - 32 - 48 - 48 - 64 - 64); // @audit-issue 546: uint256(direction << (256 - 2)) >> (256 - 2) | // @audit-issue 547: uint256(UFixed6.unwrap(newValue.magnitude()) << (256 - 62)) >> (256 - 2 - 62) | // @audit-issue 548: uint256(Fixed6.unwrap(newValue.invalidation.maker) << (256 - 64)) >> (256 - 2 - 62 - 64) | // @audit-issue 549: uint256(Fixed6.unwrap(newValue.invalidation.long) << (256 - 64)) >> (256 - 2 - 62 - 64 - 64) | // @audit-issue 550: uint256(Fixed6.unwrap(newValue.invalidation.short) << (256 - 64)) >> (256 - 2 - 62 - 64 - 64 - 64); // @audit-issue ``` *GitHub*: [445](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L445-L445), [446](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L446-L446), [447](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L447-L447), [448](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L448-L448), [449](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L449-L449), [450](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L450-L450), [454](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L454-L454), [455](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L455-L455), [456](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L456-L456), [469](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L469-L469), [470](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L470-L470), [471](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L471-L471), [472](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L472-L472), [473](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L473-L473), [475](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L475-L475), [476](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L476-L476), [477](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L477-L477), [478](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L478-L478), [510](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L510-L510), [511](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L511-L511), [514](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L514-L514), [518](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L518-L518), [519](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L519-L519), [520](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L520-L520), [521](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L521-L521), [523](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L523-L523), [524](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L524-L524), [525](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L525-L525), [540](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L540-L540), [541](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L541-L541), [542](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L542-L542), [543](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L543-L543), [544](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L544-L544), [546](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L546-L546), [547](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L547-L547), [548](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L548-L548), [549](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L549-L549), [550](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial/contracts/types/Position.sol#L550-L550) ```solidity Path: ./perennial-v2/packages/perennial-oracle/contracts/Oracle.sol 45: oracles[global.current].timestamp = uint96(currentTimestamp); // @audit-issue 74: if (timestamp > uint256(oracles[i].timestamp)) break; // @audit-issue 90: oracles[global.current].timestamp = uint96(latestVersion.timestamp); // @audit-issue 94: oracles[++global.current] = Epoch(newProvider, uint96(newProvider.current())); // @audit-issue 117: uint256(isLatestStale ? oracles[global.current].timestamp : oracles[global.latest].timestamp); // @audit-issue 129: if (uint256(oracles[global.latest].timestamp) > oracles[global.latest].provider.latest().timestamp) return false; // @audit-issue 130: if (uint256(oracles[global.latest].timestamp) >= currentOracleLatestVersion.timestamp) return false; // @audit-issue ``` *GitHub*: [45](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial-oracle/contracts/Oracle.sol#L45-L45), [74](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial-oracle/contracts/Oracle.sol#L74-L74), [90](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial-oracle/contracts/Oracle.sol#L90-L90), [94](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial-oracle/contracts/Oracle.sol#L94-L94), [117](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial-oracle/contracts/Oracle.sol#L117-L117), [129](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial-oracle/contracts/Oracle.sol#L129-L129), [130](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial-oracle/contracts/Oracle.sol#L130-L130) ```solidity Path: ./perennial-v2/packages/perennial-oracle/contracts/keeper/KeeperFactory.sol 147: uint256 effectiveGranularity = block.timestamp <= uint256(_granularity.effectiveAfter) ? // @audit-issue 148: uint256(_granularity.latestGranularity) : // @audit-issue 149: uint256(_granularity.currentGranularity); // @audit-issue 243: if (_current <= uint256(_granularity.effectiveAfter)) revert KeeperFactoryInvalidGranularityError(); // @audit-issue 248: uint64(newGranularity), // @audit-issue 249: uint128(_current) // @audit-issue ``` *GitHub*: [147](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial-oracle/contracts/keeper/KeeperFactory.sol#L147-L147), [148](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial-oracle/contracts/keeper/KeeperFactory.sol#L148-L148), [149](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial-oracle/contracts/keeper/KeeperFactory.sol#L149-L149), [243](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial-oracle/contracts/keeper/KeeperFactory.sol#L243-L243), [248](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial-oracle/contracts/keeper/KeeperFactory.sol#L248-L248), [249](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial-oracle/contracts/keeper/KeeperFactory.sol#L249-L249) ```solidity Path: ./perennial-v2/packages/perennial-oracle/contracts/keeper/KeeperOracle.sol 121: _global.latestVersion = uint64(version.timestamp); // @audit-issue ``` *GitHub*: [121](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial-oracle/contracts/keeper/KeeperOracle.sol#L121-L121) ```solidity Path: ./perennial-v2/packages/perennial-oracle/contracts/pyth/PythFactory.sol 66: Fixed6 base = Fixed6Lib.from(int256(10 ** SignedMath.abs(exponent))); // @audit-issue ``` *GitHub*: [66](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial-oracle/contracts/pyth/PythFactory.sol#L66-L66) ```solidity Path: ./perennial-v2/packages/perennial-extensions/contracts/types/TriggerOrder.sol 76: uint8(storedValue.side), // @audit-issue 77: int8(storedValue.comparison), // @audit-issue 78: UFixed6.wrap(uint256(storedValue.fee)), // @audit-issue 79: Fixed6.wrap(int256(storedValue.price)), // @audit-issue 80: Fixed6.wrap(int256(storedValue.delta)), // @audit-issue 82: UFixed6.wrap(uint256(storedValue.interfaceFeeAmount)), // @audit-issue 101: uint8(newValue.side), // @audit-issue 102: int8(newValue.comparison), // @audit-issue 103: uint64(UFixed6.unwrap(newValue.fee)), // @audit-issue 104: int64(Fixed6.unwrap(newValue.price)), // @audit-issue 105: int64(Fixed6.unwrap(newValue.delta)), // @audit-issue 106: uint40(UFixed6.unwrap(newValue.interfaceFee.amount)), // @audit-issue ``` *GitHub*: [76](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial-extensions/contracts/types/TriggerOrder.sol#L76-L76), [77](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial-extensions/contracts/types/TriggerOrder.sol#L77-L77), [78](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial-extensions/contracts/types/TriggerOrder.sol#L78-L78), [79](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial-extensions/contracts/types/TriggerOrder.sol#L79-L79), [80](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial-extensions/contracts/types/TriggerOrder.sol#L80-L80), [82](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial-extensions/contracts/types/TriggerOrder.sol#L82-L82), [101](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial-extensions/contracts/types/TriggerOrder.sol#L101-L101), [102](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial-extensions/contracts/types/TriggerOrder.sol#L102-L102), [103](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial-extensions/contracts/types/TriggerOrder.sol#L103-L103), [104](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial-extensions/contracts/types/TriggerOrder.sol#L104-L104), [105](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial-extensions/contracts/types/TriggerOrder.sol#L105-L105), [106](https://github.com/sherlock-audit/2023-10-perennial/blob/main/./perennial-v2/packages/perennial-extensions/contracts/types/TriggerOrder.sol#L106-L106)Tool used
Manual Review - Used my own static analyzer (still in development)
Recommendation
Incorporate OpenZeppelin's SafeCast library to perform type casting. This library provides functions like toUint256(), toUint128(), and toInt256() which include overflow and underflow checks.