diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 16e171e4..6d34fa56 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -162,4 +162,4 @@ jobs: uses: Rubilmax/foundry-storage-check@v3.7 with: contract: src/IonPool.sol:IonPool - address: "0x00000000005a1de4c0eb34609e211ad8831707e0" # the address at which the contract check is deployed + address: "0xad71a9e73e235a61caeb10059b64459fab23b8c7" # the address at which the contract check is deployed diff --git a/.solhintignore b/.solhintignore index 6dc6ce42..496854d0 100644 --- a/.solhintignore +++ b/.solhintignore @@ -1,4 +1,3 @@ src/libraries/uniswap/ -src/interfaces/ProviderInterfaces.sol -src/interfaces/ISpotOracle.sol +src/interfaces/**.sol src/periphery/IonInvariants.sol diff --git a/certora/.DS_Store b/certora/.DS_Store deleted file mode 100644 index 58b8885c..00000000 Binary files a/certora/.DS_Store and /dev/null differ diff --git a/certora/README.md b/certora/README.md deleted file mode 100644 index c45d7e42..00000000 --- a/certora/README.md +++ /dev/null @@ -1,104 +0,0 @@ -# Formal Verification Details - -## Introduction - -The Formal Verification (FV) component of the contest is about using the Certora Prover to formally verify properties in the Solidity smart contracts in scope. Participants are incentivized to implement and verify high coverage properties. Submissions, incentives, and judging are different from the main contest so please read this document in its entirety. - -## Scope - -| Contract | SLOC | -| ------------------------------------------------------------------------------------------------- | ---- | -| [IonPool.sol](https://github.com/Ion-Protocol/ion-protocol/blob/master/src/IonPool.sol) | 578 | -| [Liquidation.sol](https://github.com/Ion-Protocol/ion-protocol/blob/master/src/Liquidation.sol) | 149 | -| [InterestRate.sol](https://github.com/Ion-Protocol/ion-protocol/blob/master/src/InterestRate.sol) | 212 | - -## Overview - -- 25% (10,000 USDC) of this contest will be allocated for FV. -- Conventional bug submission, issue judgment, and all reward distribution will be managed by Hats Finance. -- FV component is unique as participants are incentivized to implement and verify high coverage properties using the Certora Prover. -- The judging of FV is conducted by Certora, with different submissions, incentives, and judging processes compared to the standard contest. These processes are explained in this document. - -## Getting Started - -- **Get access to the Prover**: - - First time participants, [Register](https://www.certora.com/signup?plan=prover) to automatically receive an access key. -- **Update expired key**: - - Send a message in the [Certora Discord](https://discord.gg/usnJm6p4)'s `access-key-request` channel. -- **Tool Installation**: - - Follow [installation instructions](https://docs.certora.com/en/latest/docs/user-guide/getting-started/install.html) to download the `certora-cli` tool. Use the latest version of the tool available at the start of the contest, throughout the whole contest. -- **Learning Resources**: - - Complete the [tutorials](https://docs.certora.com/projects/tutorials/en/latest). - - Search the [docs](https://docs.certora.com/en/latest/index.html) for any additional information. - - Check out some of our [examples](https://www.github.com/certora/examples). -- **Contest Participation**: - - [Import](https://github.com/new/import) the public repository into a new private repository at the contest's commencement. - - Conduct verifications on the main branch. - - Grant access to `teryanarmen` and `pistiner` for judging. -- **Support Channels**: - - For tool-related issues, send a detailed message with a job link in `help-desk` channel in Discord. Remove the anonymousKey component from the link if you wish to limit viewing to Certora employees. - - For FV contest questions, use the relevant community verification channel in Discord. - -## Incentives - -- 25% (10k) of the total pool is allocated for FV. -- FV pool is split into three categories - - **Participation**: 10% of pool awarded for properties identifying public mutants. - - **Real Bugs**: 20% of pool awarded for properties uncovering actual bugs. - - **Coverage**: 70% of pool awarded for properties identifying private mutants. -- If no properties are accepted for real bugs, the pool will be rebalanced to 90% coverage and 10% participation. -- Mutants are mutated versions of the original code which create vulnerabilities. These mutants are used to gauge verified properties' coverage of the original code. - - Public mutants used for evaluating participation rewards can be found in `certora/mutations`. -- Participation and coverage reward can be calculated as follows - - Each mutant is worth $0.9^{n-1}$ points where $n$ is the number of participants that caught the mutant. - - If we let $P$ be the total FV pool and $T$ be the sum of all mutants' points, we can define each participant's reward as $ \frac{P}{T} \cdot \frac{0.9^{n-1}}{n} $ -- Real bug rewards will be awarded for properties that are violated because of the bug. Only the bug submitter can submit a spec for that bug. 25, 12, or 1 points will be allocated based on the severity of the bug (H/M/L). - -## Submission Guidelines - -- **Development Constraints**: - - Participants are allowed to create and modify configuration, harnesses, and specification files. - - Some conf files have commented out settings which can be used to help with running time. - - All coverage and participation submissions must pass on the unaltered original codebase. - - Source code modifications are prohibited. - - Evaluations are based on the original code; configurations reliant on code changes will be disregarded. - - Utilize the latest version of `certoraRun` available at contest start. - - Avoid updates during the contest, even if new versions are released. - - Only update if explicitly told to by Certora team. - - Submissions with tool errors, compilation errors, or timing-out rules will not be considered. - - Ensure configurations do not time out; retest to confirm consistency. -- **Configuration Naming**: - - For coverage and participation: Name configuration files as `ContractName_[identifier]_verified.conf`. The identifier is optional and should be used when multiple configurations are created for one contract. - - Example: `ERC20_summarized_verified.conf`. - - For real bugs: Replace `_verified` with `_violated` in the configuration file name. -- **Real bug submissions**: - - Real bug submissions must include a GitHub issue in your private fork, detailing the impact, specifics, violated rule, and a solution. - - Properties for real bugs will only be accepted if the underlying issue is accepted by the hosting platform judge. - - If possible, link to the original bug submission. - - Submission must explain the property that catches the bug. - - A link to the violated run must be included. - - A proposed solution must be included as a diff between the buggy and fixed code. - - A verified run of the property on the fixed version must be included. - -## Evaluation Process - -- **Preliminary Results**: Initial findings will be announced along with the mutations used for evaluation. A google sheet showing which mutants were caught by which participants will be shared. Participants will have a 72-hour period for review and submit corrections in case a certain mutant is marked as not caught but they actually caught it. -- **Correction Submissions**: Corrections must include a verified run on the source code and a violated run on the mutant. Any changes other than the mutation will result in exclusion of the correction. -- **Check your work**: Use `certoraMutate` to evaluate your work on public mutations and random mutations created by gambit. - - Gambit confs will be provided for all the in scope contracts. To run mutation testing, you can do `certoraMutate --prover_conf certora/confs/contract_verified.conf --mutation_conf certora/confs/gambit/contract.mconf` from root of the directory, same as `certoraRun`. - - You can change the number of bugs that are injected by adding manual mutations in the `mutations` folder in a similar fashion to the public mutations or by changing the value of automatic mutation in the contract's mutation conf. - - Use `--dump_csv file_path.csv` flag with `certoraMutate` to get a csv output of your results. During evaluation, the data from this output is aggregated for all participants used for coverage and participation evaluation. Make sure everthing looks right, specifically, all rules should have "SUCCESS" for the original run. - -## Report Compilation - -- **Public Disclosure**: The report, encompassing top submissions and mutation descriptions, will be made public post-analysis. - - Not all top properties focus on the quantity of mutations caught; high-level invariants are highly valued. - - Future mutations will be adjusted to properly value high quality properties. - - Guidelines for superior specifications: - - Avoid code duplication. - - Eschew simplistic unit tests. - - Limit excessive assertions. - - Focus on concise, high-level properties. - - Reduce overuse of `require` statements. - - Ensure clear documentation, proper naming, and formatting. -- **Participant Contributions**: The top participants' `certora` folders will be included in the public repository. diff --git a/certora/confs/InterestRate_verified.conf b/certora/confs/InterestRate_verified.conf deleted file mode 100644 index 50c72648..00000000 --- a/certora/confs/InterestRate_verified.conf +++ /dev/null @@ -1,21 +0,0 @@ -{ - "files": [ - "src/InterestRate.sol", - "src/YieldOracle.sol" - ], - "verify": "InterestRate:certora/specs/InterestRate.spec", - "loop_iter": "3", - "parametric_contracts": ["InterestRate"], - "packages": [ - "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts", - "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts" - ], - "link": [ - "InterestRate:YIELD_ORACLE=YieldOracle" - ], - "prover_args": [ - "-optimisticFallback true" - ], - "optimistic_loop": true, - "rule_sanity": "basic" -} \ No newline at end of file diff --git a/certora/confs/IonPool_verified.conf b/certora/confs/IonPool_verified.conf deleted file mode 100644 index 1c26b778..00000000 --- a/certora/confs/IonPool_verified.conf +++ /dev/null @@ -1,31 +0,0 @@ -{ - "files": [ - "src/IonPool.sol", - "src/InterestRate.sol", - "src/oracles/spot/WstEthSpotOracle.sol", - "src/oracles/reserve/WstEthReserveOracle.sol", - "src/Whitelist.sol", - "src/YieldOracle.sol", - "certora/helpers/ERC20A.sol", - "certora/helpers/ERC20B.sol" - ], - "verify": "IonPool:certora/specs/IonPool.spec", - "loop_iter": "3", - "parametric_contracts": ["IonPool"], - "packages": [ - "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts", - "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts" - ], - "link": [ - "InterestRate:YIELD_ORACLE=YieldOracle", - "WstEthSpotOracle:RESERVE_ORACLE=WstEthReserveOracle" - ], - "prover_args": [ - "-optimisticFallback true", - "-splitParallel true", // good for finding violations - // "-split false" helps with proving rules - ], - // "smt_timeout": "3600", helps with proving rules - "optimistic_loop": true, - "rule_sanity": "basic" -} \ No newline at end of file diff --git a/certora/confs/Liquidation_verified.conf b/certora/confs/Liquidation_verified.conf deleted file mode 100644 index 9bfb1bfe..00000000 --- a/certora/confs/Liquidation_verified.conf +++ /dev/null @@ -1,28 +0,0 @@ -{ - "files": [ - "src/Liquidation.sol", - "src/IonPool.sol", - "src/oracles/reserve/WstEthReserveOracle.sol", - "certora/helpers/ERC20A.sol", - "certora/helpers/ERC20B.sol", - "src/InterestRate.sol", - "src/YieldOracle.sol" - ], - "verify": "Liquidation:certora/specs/Liquidation.spec", - "loop_iter": "3", - "parametric_contracts": ["Liquidation"], - "packages": [ - "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts", - "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts", - ], - "assert_autofinder_success": true, - "prover_args": [ - "-splitParallel true", // good for finding violations - // "-split flase" helps with proving rules - ], - "link": [ - "Liquidation:POOL=IonPool", - ], - // "smt_timeout": "3600", helps with proving rules - "optimistic_loop": true, - "rule_sanity": "basic"} \ No newline at end of file diff --git a/certora/confs/mutation/InterestRate.mconf b/certora/confs/mutation/InterestRate.mconf deleted file mode 100644 index 69a638f5..00000000 --- a/certora/confs/mutation/InterestRate.mconf +++ /dev/null @@ -1,13 +0,0 @@ -{ - "gambit": { - "filename" : "../../../src/InterestRate.sol", - "num_mutants": 10, - "solc_remappings": [ - "@openzeppelin/contracts=../../../lib/openzeppelin-contracts/contracts", - "@openzeppelin/contracts-upgradeable=../../../lib/openzeppelin-contracts-upgradeable/contracts" - ] - }, - "manual_mutants": { - "../../../src/InterestRate.sol": "../../mutations/InterestRate" - } -} \ No newline at end of file diff --git a/certora/confs/mutation/IonPool.mconf b/certora/confs/mutation/IonPool.mconf deleted file mode 100644 index 2111e995..00000000 --- a/certora/confs/mutation/IonPool.mconf +++ /dev/null @@ -1,14 +0,0 @@ -{ - "gambit": { - "filename" : "../../../src/IonPool.sol", - "num_mutants": 10, - "solc_remappings": [ - "@openzeppelin/contracts=../../../lib/openzeppelin-contracts/contracts", - "@openzeppelin/contracts-upgradeable=../../../lib/openzeppelin-contracts-upgradeable/contracts" - ] - }, - "manual_mutants": { - "../../../src/IonPool.sol" : "../../mutations/IonPool", - "../../../src/InterestRate.sol": "../../mutations/InterestRate" - } -} \ No newline at end of file diff --git a/certora/confs/mutation/Liquidation.mconf b/certora/confs/mutation/Liquidation.mconf deleted file mode 100644 index d10a61b2..00000000 --- a/certora/confs/mutation/Liquidation.mconf +++ /dev/null @@ -1,14 +0,0 @@ -{ "gambit": { - "filename" : "../../../src/Liquidation.sol", - "num_mutants": 10, - "solc_remappings": [ - "@openzeppelin/contracts=../../../lib/openzeppelin-contracts/contracts", - "@openzeppelin/contracts-upgradeable=../../../lib/openzeppelin-contracts-upgradeable/contracts" - ] - }, - "manual_mutants": { - "../../../src/Liquidation.sol" : "../../mutations/Liquidation", - "../../../src/IonPool.sol": "../../mutations/IonPool", - "../../../src/InterestRate.sol": "../../mutations/InterestRate" - } -} \ No newline at end of file diff --git a/certora/helpers/ERC20A.sol b/certora/helpers/ERC20A.sol deleted file mode 100644 index 96060937..00000000 --- a/certora/helpers/ERC20A.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity =0.8.21; - -import "lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol"; - -contract ERC20A is ERC20 { - constructor(string memory name_, string memory symbol_) ERC20(name_, symbol_) {} -} \ No newline at end of file diff --git a/certora/helpers/ERC20B.sol b/certora/helpers/ERC20B.sol deleted file mode 100644 index f7e4b4fc..00000000 --- a/certora/helpers/ERC20B.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity =0.8.21; - -import "lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol"; - -contract ERC20B is ERC20 { - constructor(string memory name_, string memory symbol_) ERC20(name_, symbol_) {} -} \ No newline at end of file diff --git a/certora/mutations/InterestRate/InterestRate_P.sol b/certora/mutations/InterestRate/InterestRate_P.sol deleted file mode 100644 index 6fdfab3d..00000000 --- a/certora/mutations/InterestRate/InterestRate_P.sol +++ /dev/null @@ -1,326 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.21; - -import { IYieldOracle } from "src/interfaces/IYieldOracle.sol"; -import { WadRayMath } from "src/libraries/math/WadRayMath.sol"; - -// forgefmt: disable-start - -struct IlkData { - // Word 1 - uint96 adjustedProfitMargin; // 27 decimals - uint96 minimumKinkRate; // 27 decimals - - // Word 2 - uint16 reserveFactor; // 4 decimals - uint96 adjustedBaseRate; // 27 decimals - uint96 minimumBaseRate; // 27 decimals - uint16 optimalUtilizationRate; // 4 decimals - uint16 distributionFactor; // 4 decimals - - // Word 3 - uint96 adjustedAboveKinkSlope; // 27 decimals - uint96 minimumAboveKinkSlope; // 27 decimals -} - -// Word 1 -// -// 256 240 216 192 96 0 -// | | | | min_kink_rate | adj_profit_margin | -// -uint256 constant ADJUSTED_PROFIT_MARGIN_MASK = 0x0000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF; -uint256 constant MINIMUM_KINK_RATE_MASK = 0x0000000000000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000; - -// Word 2 -// -// 256 240 224 208 112 16 0 -// | __ | | | min_base_rate | adj_base_rate | | -// ^ ^ ^ -// ^ opt_util reserve_factor -// distribution_factor - -uint256 constant RESERVE_FACTOR_MASK = 0x000000000000000000000000000000000000000000000000000000000000FFFF; -uint256 constant ADJUSTED_BASE_RATE_MASK = 0x000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF0000; -uint256 constant MINIMUM_BASE_RATE_MASK = 0x000000000000FFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000; -uint256 constant OPTIMAL_UTILIZATION_MASK = 0x00000000FFFF0000000000000000000000000000000000000000000000000000; -uint256 constant DISTRIBUTION_FACTOR_MASK = 0x0000FFFF00000000000000000000000000000000000000000000000000000000; - -// Word 3 -// 256 240 216 192 96 0 -// | | | | min_above_kink_slope | adj_above_kink_slope | -// -uint256 constant ADJUSTED_ABOVE_KINK_SLOPE_MASK = 0x0000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF; -uint256 constant MINIMUM_ABOVE_KINK_SLOPE_MASK = 0x0000000000000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000; - -// forgefmt: disable-end - -// Word 1 -uint8 constant ADJUSTED_PROFIT_MARGIN_SHIFT = 0; -uint8 constant MINIMUM_KINK_RATE_SHIFT = 96; - -// Word 2 -uint8 constant RESERVE_FACTOR_SHIFT = 0; -uint8 constant ADJUSTED_BASE_RATE_SHIFT = 16; -uint8 constant MINIMUM_BASE_RATE_SHIFT = 16 + 96; -uint8 constant OPTIMAL_UTILIZATION_SHIFT = 16 + 96 + 96; -uint8 constant DISTRIBUTION_FACTOR_SHIFT = 16 + 96 + 96 + 16; - -// Word 3 -uint8 constant ADJUSTED_ABOVE_KINK_SLOPE_SHIFT = 0; -uint8 constant MINIMUM_ABOVE_KINK_SLOPE_SHIFT = 96; - -uint48 constant SECONDS_IN_A_YEAR = 31_536_000; - -contract InterestRate { - using WadRayMath for *; - - error CollateralIndexOutOfBounds(); - error DistributionFactorsDoNotSumToOne(uint256 sum); - error TotalDebtsLength(uint256 COLLATERAL_COUNT, uint256 totalIlkDebtsLength); - error InvalidYieldOracleAddress(); - - /** - * @dev Packed collateral configs - */ - uint256 internal immutable ILKCONFIG_0A; - uint256 internal immutable ILKCONFIG_0B; - uint256 internal immutable ILKCONFIG_0C; - uint256 internal immutable ILKCONFIG_1A; - uint256 internal immutable ILKCONFIG_1B; - uint256 internal immutable ILKCONFIG_1C; - uint256 internal immutable ILKCONFIG_2A; - uint256 internal immutable ILKCONFIG_2B; - uint256 internal immutable ILKCONFIG_2C; - uint256 internal immutable ILKCONFIG_3A; - uint256 internal immutable ILKCONFIG_3B; - uint256 internal immutable ILKCONFIG_3C; - uint256 internal immutable ILKCONFIG_4A; - uint256 internal immutable ILKCONFIG_4B; - uint256 internal immutable ILKCONFIG_4C; - uint256 internal immutable ILKCONFIG_5A; - uint256 internal immutable ILKCONFIG_5B; - uint256 internal immutable ILKCONFIG_5C; - uint256 internal immutable ILKCONFIG_6A; - uint256 internal immutable ILKCONFIG_6B; - uint256 internal immutable ILKCONFIG_6C; - uint256 internal immutable ILKCONFIG_7A; - uint256 internal immutable ILKCONFIG_7B; - uint256 internal immutable ILKCONFIG_7C; - - uint256 public immutable COLLATERAL_COUNT; - IYieldOracle public immutable YIELD_ORACLE; - - constructor(IlkData[] memory ilkDataList, IYieldOracle _yieldOracle) { - if (address(_yieldOracle) == address(0)) revert InvalidYieldOracleAddress(); - - COLLATERAL_COUNT = ilkDataList.length; - YIELD_ORACLE = _yieldOracle; - - uint256 distributionFactorSum = 0; - for (uint256 i = 0; i < COLLATERAL_COUNT;) { - distributionFactorSum += ilkDataList[i].distributionFactor; - - // forgefmt: disable-next-line - unchecked { ++i; } - } - - if (distributionFactorSum != 1e4) revert DistributionFactorsDoNotSumToOne(distributionFactorSum); - - (ILKCONFIG_0A, ILKCONFIG_0B, ILKCONFIG_0C) = _packCollateralConfig(ilkDataList, 0); - (ILKCONFIG_1A, ILKCONFIG_1B, ILKCONFIG_1C) = _packCollateralConfig(ilkDataList, 1); - (ILKCONFIG_2A, ILKCONFIG_2B, ILKCONFIG_2C) = _packCollateralConfig(ilkDataList, 2); - (ILKCONFIG_3A, ILKCONFIG_3B, ILKCONFIG_3C) = _packCollateralConfig(ilkDataList, 3); - (ILKCONFIG_4A, ILKCONFIG_4B, ILKCONFIG_4C) = _packCollateralConfig(ilkDataList, 4); - (ILKCONFIG_5A, ILKCONFIG_5B, ILKCONFIG_5C) = _packCollateralConfig(ilkDataList, 5); - (ILKCONFIG_6A, ILKCONFIG_6B, ILKCONFIG_6C) = _packCollateralConfig(ilkDataList, 6); - (ILKCONFIG_7A, ILKCONFIG_7B, ILKCONFIG_7C) = _packCollateralConfig(ilkDataList, 7); - } - - function _packCollateralConfig( - IlkData[] memory ilkDataList, - uint256 index - ) - internal - view - returns (uint256 packedConfig_a, uint256 packedConfig_b, uint256 packedConfig_c) - { - if (index >= COLLATERAL_COUNT) return (0, 0, 0); - - IlkData memory ilkData = ilkDataList[index]; - - packedConfig_a = ( - uint256(ilkData.adjustedProfitMargin) << ADJUSTED_PROFIT_MARGIN_SHIFT - | uint256(ilkData.minimumKinkRate) << MINIMUM_KINK_RATE_SHIFT - ); - - packedConfig_b = ( - uint256(ilkData.reserveFactor) << RESERVE_FACTOR_SHIFT - | uint256(ilkData.adjustedBaseRate) << ADJUSTED_BASE_RATE_SHIFT - | uint256(ilkData.minimumBaseRate) << MINIMUM_BASE_RATE_SHIFT - | uint256(ilkData.optimalUtilizationRate) << OPTIMAL_UTILIZATION_SHIFT - | uint256(ilkData.distributionFactor) << DISTRIBUTION_FACTOR_SHIFT - ); - - packedConfig_c = ( - uint256(ilkData.adjustedAboveKinkSlope) << ADJUSTED_ABOVE_KINK_SLOPE_SHIFT - | uint256(ilkData.minimumAboveKinkSlope) << MINIMUM_ABOVE_KINK_SLOPE_SHIFT - ); - } - - function _unpackCollateralConfig(uint256 index) internal view returns (IlkData memory ilkData) { - if (index > COLLATERAL_COUNT - 1) revert CollateralIndexOutOfBounds(); - - uint256 packedConfig_a; - uint256 packedConfig_b; - uint256 packedConfig_c; - - if (index == 0) { - packedConfig_a = ILKCONFIG_0A; - packedConfig_b = ILKCONFIG_0B; - packedConfig_c = ILKCONFIG_0C; - } else if (index == 1) { - packedConfig_a = ILKCONFIG_1A; - packedConfig_b = ILKCONFIG_1B; - packedConfig_c = ILKCONFIG_1C; - } else if (index == 2) { - packedConfig_a = ILKCONFIG_2A; - packedConfig_b = ILKCONFIG_2B; - packedConfig_c = ILKCONFIG_2C; - } else if (index == 3) { - packedConfig_a = ILKCONFIG_3A; - packedConfig_b = ILKCONFIG_3B; - packedConfig_c = ILKCONFIG_3C; - } else if (index == 4) { - packedConfig_a = ILKCONFIG_4A; - packedConfig_b = ILKCONFIG_4B; - packedConfig_c = ILKCONFIG_4C; - } else if (index == 5) { - packedConfig_a = ILKCONFIG_5A; - packedConfig_b = ILKCONFIG_5B; - packedConfig_c = ILKCONFIG_5C; - } else if (index == 6) { - packedConfig_a = ILKCONFIG_6A; - packedConfig_b = ILKCONFIG_6B; - packedConfig_c = ILKCONFIG_6C; - } else if (index == 7) { - packedConfig_a = ILKCONFIG_7A; - packedConfig_b = ILKCONFIG_7B; - packedConfig_c = ILKCONFIG_7C; - } - - uint96 adjustedProfitMargin = - uint96((packedConfig_a & ADJUSTED_PROFIT_MARGIN_MASK) >> ADJUSTED_PROFIT_MARGIN_SHIFT); - uint96 minimumKinkRate = uint96((packedConfig_a & MINIMUM_KINK_RATE_MASK) >> MINIMUM_KINK_RATE_SHIFT); - - uint16 reserveFactor = uint16((packedConfig_b & RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_SHIFT); - uint96 adjustedBaseRate = uint96((packedConfig_b & ADJUSTED_BASE_RATE_MASK) >> ADJUSTED_BASE_RATE_SHIFT); - uint96 minimumBaseRate = uint96((packedConfig_b & MINIMUM_BASE_RATE_MASK) >> MINIMUM_BASE_RATE_SHIFT); - uint16 optimalUtilizationRate = uint16((packedConfig_b & OPTIMAL_UTILIZATION_MASK) >> OPTIMAL_UTILIZATION_SHIFT); - uint16 distributionFactor = uint16((packedConfig_b & DISTRIBUTION_FACTOR_MASK) >> DISTRIBUTION_FACTOR_SHIFT); - - uint96 adjustedAboveKinkSlope = - uint96((packedConfig_c & ADJUSTED_ABOVE_KINK_SLOPE_MASK) >> ADJUSTED_ABOVE_KINK_SLOPE_SHIFT); - uint96 minimumAboveKinkSlope = - uint96((packedConfig_c & MINIMUM_ABOVE_KINK_SLOPE_MASK) >> MINIMUM_ABOVE_KINK_SLOPE_SHIFT); - - ilkData = IlkData({ - adjustedProfitMargin: adjustedProfitMargin, - minimumKinkRate: minimumKinkRate, - reserveFactor: reserveFactor, - adjustedBaseRate: adjustedBaseRate, - minimumBaseRate: minimumBaseRate, - optimalUtilizationRate: optimalUtilizationRate, - distributionFactor: distributionFactor, - adjustedAboveKinkSlope: adjustedAboveKinkSlope, - minimumAboveKinkSlope: minimumAboveKinkSlope - }); - } - - /** - * @param ilkIndex index of the collateral - * @param totalIlkDebt total debt of the collateral (45 decimals) - * @param totalEthSupply total eth supply of the system (18 decimals) - */ - function calculateInterestRate( - uint256 ilkIndex, - uint256 totalIlkDebt, // [RAD] - uint256 totalEthSupply - ) - external - view - returns (uint256, uint256) - { - IlkData memory ilkData = _unpackCollateralConfig(ilkIndex); - uint256 optimalUtilizationRateRay = ilkData.optimalUtilizationRate.scaleUpToRay(4); - uint256 collateralApyRayInSeconds = YIELD_ORACLE.apys(ilkIndex).scaleUpToRay(8) / SECONDS_IN_A_YEAR; - - uint256 distributionFactor = ilkData.distributionFactor; - // The only time the distribution factor will be set to 0 is when a - // market has been sunset. In this case, we want to prevent division by - // 0, but we also want to prevent the borrow rate from skyrocketing. So - // we will return a reasonable borrow rate of kink utilization on the - // minimum curve. - // mutation: `==` => `<=` - if (distributionFactor <= 0) { - return (ilkData.minimumKinkRate, ilkData.reserveFactor.scaleUpToRay(4)); - } - // [RAD] / [WAD] = [RAY] - uint256 utilizationRate = totalEthSupply == 0 ? 0 : totalIlkDebt / (totalEthSupply.wadMulDown(distributionFactor.scaleUpToWad(4))); - - // Avoid stack too deep - uint256 adjustedBelowKinkSlope; - { - uint256 slopeNumerator; - unchecked { - slopeNumerator = collateralApyRayInSeconds - ilkData.adjustedProfitMargin - ilkData.adjustedBaseRate; - } - - // Underflow occured - // If underflow occured, then the Apy was too low or the profitMargin was too high and - // we would want to switch to minimum borrow rate. Set slopeNumerator to zero such - // that adjusted borrow rate is below the minimum borrow rate. - if (slopeNumerator > collateralApyRayInSeconds) { - slopeNumerator = 0; - } - - adjustedBelowKinkSlope = slopeNumerator.rayDivDown(optimalUtilizationRateRay); - } - - uint256 minimumBelowKinkSlope = - (ilkData.minimumKinkRate - ilkData.minimumBaseRate).rayDivDown(optimalUtilizationRateRay); - - // Below kink - if (utilizationRate < optimalUtilizationRateRay) { - uint256 adjustedBorrowRate = adjustedBelowKinkSlope.rayMulDown(utilizationRate) + ilkData.adjustedBaseRate; - uint256 minimumBorrowRate = minimumBelowKinkSlope.rayMulDown(utilizationRate) + ilkData.minimumBaseRate; - - if (adjustedBorrowRate < minimumBorrowRate) { - return (minimumBorrowRate, ilkData.reserveFactor.scaleUpToRay(4)); - } else { - return (adjustedBorrowRate, ilkData.reserveFactor.scaleUpToRay(4)); - } - } - // Above kink - else { - // For the above kink calculation, we will use the below kink slope - // for all utilization up until the kink. From that point on we will - // use the above kink slope. - uint256 excessUtil = utilizationRate - optimalUtilizationRateRay; - - uint256 adjustedNormalRate = - adjustedBelowKinkSlope.rayMulDown(optimalUtilizationRateRay) + ilkData.adjustedBaseRate; - uint256 minimumNormalRate = - minimumBelowKinkSlope.rayMulDown(optimalUtilizationRateRay) + ilkData.minimumBaseRate; - - // [WAD] * [RAY] / [WAD] = [RAY] - uint256 adjustedBorrowRate = ilkData.adjustedAboveKinkSlope.rayMulDown(excessUtil) + adjustedNormalRate; - uint256 minimumBorrowRate = ilkData.minimumAboveKinkSlope.rayMulDown(excessUtil) + minimumNormalRate; - - if (adjustedBorrowRate < minimumBorrowRate) { - return (minimumBorrowRate, ilkData.reserveFactor.scaleUpToRay(4)); - } else { - return (adjustedBorrowRate, ilkData.reserveFactor.scaleUpToRay(4)); - } - } - } -} diff --git a/certora/mutations/IonPool/IonPool_P.sol b/certora/mutations/IonPool/IonPool_P.sol deleted file mode 100644 index a916d4f2..00000000 --- a/certora/mutations/IonPool/IonPool_P.sol +++ /dev/null @@ -1,1199 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.21; - -import { Whitelist } from "src/Whitelist.sol"; -import { SpotOracle } from "src/oracles/spot/SpotOracle.sol"; -import { RewardModule } from "src/reward/RewardModule.sol"; -import { InterestRate } from "src/InterestRate.sol"; -import { WadRayMath, RAY } from "src/libraries/math/WadRayMath.sol"; -import { IonPausableUpgradeable } from "src/admin/IonPausableUpgradeable.sol"; - -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; - -import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol"; -import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; -import { Math } from "@openzeppelin/contracts/utils/math/Math.sol"; - -contract IonPool is IonPausableUpgradeable, RewardModule { - using SafeERC20 for IERC20; - using SafeCast for *; - using WadRayMath for *; - using Math for uint256; - using EnumerableSet for EnumerableSet.AddressSet; - - // --- Errors --- - error CeilingExceeded(uint256 newDebt, uint256 debtCeiling); - error UnsafePositionChange(uint256 newTotalDebtInVault, uint256 collateral, uint256 spot); - error UnsafePositionChangeWithoutConsent(uint8 ilkIndex, address user, address unconsentedOperator); - error GemTransferWithoutConsent(uint8 ilkIndex, address user, address unconsentedOperator); - error UseOfCollateralWithoutConsent(uint8 ilkIndex, address depositor, address unconsentedOperator); - error TakingWethWithoutConsent(address payer, address unconsentedOperator); - error VaultCannotBeDusty(uint256 amountLeft, uint256 dust); - error ArithmeticError(); - error SpotUpdaterNotAuthorized(); - error IlkAlreadyAdded(address ilkAddress); - error IlkNotInitialized(uint256 ilkIndex); - error DepositSurpassesSupplyCap(uint256 depositAmount, uint256 supplyCap); - - error InvalidIlkAddress(); - error InvalidInterestRateModule(InterestRate invalidInterestRateModule); - error InvalidWhitelist(Whitelist invalidWhitelist); - - // --- Events --- - event IlkInitialized(uint8 indexed ilkIndex, address indexed ilkAddress); - event IlkSpotUpdated(address newSpot); - event IlkDebtCeilingUpdated(uint256 newDebtCeiling); - event IlkDustUpdated(uint256 newDust); - event SupplyCapUpdated(uint256 newSupplyCap); - event InterestRateModuleUpdated(address newModule); - event WhitelistUpdated(address newWhitelist); - - event AddOperator(address indexed from, address indexed to); - event RemoveOperator(address indexed from, address indexed to); - event MintAndBurnGem(uint8 indexed ilkIndex, address indexed usr, int256 wad); - event TransferGem(uint8 indexed ilkIndex, address indexed src, address indexed dst, uint256 wad); - - event Supply( - address indexed user, address indexed underlyingFrom, uint256 amount, uint256 supplyFactor, uint256 newDebt - ); - - event Withdraw(address indexed user, address indexed target, uint256 amount, uint256 supplyFactor, uint256 newDebt); - - event WithdrawCollateral(uint8 indexed ilkIndex, address indexed user, address indexed recipient, uint256 amount); - event DepositCollateral(uint8 indexed ilkIndex, address indexed user, address indexed depositor, uint256 amount); - event Borrow( - uint8 indexed ilkIndex, - address indexed user, - address indexed recipient, - uint256 amountOfNormalizedDebt, - uint256 ilkRate, - uint256 totalDebt - ); - event Repay( - uint8 indexed ilkIndex, - address indexed user, - address indexed payer, - uint256 amountOfNormalizedDebt, - uint256 ilkRate, - uint256 totalDebt - ); - - event RepayBadDebt(address indexed user, address indexed payer, uint256 rad); - event ConfiscateVault( - uint8 indexed ilkIndex, - address indexed u, - address v, - address indexed w, - int256 changeInCollateral, - int256 changeInNormalizedDebt - ); - - bytes32 public constant GEM_JOIN_ROLE = keccak256("GEM_JOIN_ROLE"); - bytes32 public constant LIQUIDATOR_ROLE = keccak256("LIQUIDATOR_ROLE"); - - address private immutable ADDRESS_THIS = address(this); - - // --- Modifiers --- - modifier onlyWhitelistedBorrowers(uint8 ilkIndex, bytes32[] memory proof) { - IonPoolStorage storage $ = _getIonPoolStorage(); - $.whitelist.isWhitelistedBorrower(ilkIndex, _msgSender(), proof); - _; - } - - modifier onlyWhitelistedLenders(bytes32[] memory proof) { - IonPoolStorage storage $ = _getIonPoolStorage(); - $.whitelist.isWhitelistedLender(_msgSender(), proof); - _; - } - - // --- Data --- - struct Ilk { - uint104 totalNormalizedDebt; // Total Normalised Debt [WAD] - uint104 rate; // Accumulated Rates [RAY] - uint48 lastRateUpdate; // block.timestamp of last update; overflows in 800_000 years - SpotOracle spot; // Oracle that provides price with safety margin - uint256 debtCeiling; // Debt Ceiling [RAD] - uint256 dust; // Vault Debt Floor [RAD] - } - - struct Vault { - uint256 collateral; // Locked Collateral [WAD] - uint256 normalizedDebt; // Normalised Debt [WAD] - } - - struct IonPoolStorage { - Ilk[] ilks; - // remove() should never be called, it will mess up the ordering - EnumerableSet.AddressSet ilkAddresses; - mapping(uint256 ilkIndex => mapping(address user => Vault)) vaults; - mapping(uint256 ilkIndex => mapping(address user => uint256)) gem; // [WAD] - mapping(address => uint256) unbackedDebt; // [RAD] - mapping(address => mapping(address => uint256)) isOperator; - uint256 debt; // Total Debt [RAD] - uint256 weth; // liquidity in pool [WAD] - uint256 wethSupplyCap; // [WAD] - uint256 totalUnbackedDebt; // Total Unbacked Dai [RAD] - InterestRate interestRateModule; - Whitelist whitelist; - } - - // keccak256(abi.encode(uint256(keccak256("ion.storage.IonPool")) - 1)) & ~bytes32(uint256(0xff)) - // solhint-disable-next-line - bytes32 private constant IonPoolStorageLocation = 0xceba3d526b4d5afd91d1b752bf1fd37917c20a6daf576bcb41dd1c57c1f67e00; - - function _getIonPoolStorage() internal pure returns (IonPoolStorage storage $) { - assembly { - $.slot := IonPoolStorageLocation - } - } - - constructor() { - _disableInitializers(); - } - - function initialize( - address _underlying, - address _treasury, - uint8 decimals_, - string memory name_, - string memory symbol_, - address initialDefaultAdmin, - InterestRate _interestRateModule, - Whitelist _whitelist - ) - external - initializer - { - __AccessControlDefaultAdminRules_init(0, initialDefaultAdmin); - RewardModule._initialize(_underlying, _treasury, decimals_, name_, symbol_); - - _grantRole(ION, initialDefaultAdmin); - - IonPoolStorage storage $ = _getIonPoolStorage(); - - $.interestRateModule = _interestRateModule; - $.whitelist = _whitelist; - - emit InterestRateModuleUpdated(address(_interestRateModule)); - emit WhitelistUpdated(address(_whitelist)); - } - - // --- Administration --- - - /** - * @notice Initializes a market with a new collateral type. - * @dev This function and the entire protocol as a whole operates under the - * assumption that there will never be more than 256 collaterals. - * @param ilkAddress address of the ERC-20 collateral. - */ - function initializeIlk(address ilkAddress) external onlyRole(ION) { - IonPoolStorage storage $ = _getIonPoolStorage(); - - if (ilkAddress == address(0)) revert InvalidIlkAddress(); - if (!$.ilkAddresses.add(ilkAddress)) revert IlkAlreadyAdded(ilkAddress); - - // Unsafe cast OK since we don't plan on having more than 256 - // collaterals - uint8 ilkIndex = uint8($.ilks.length); - Ilk memory newIlk; - $.ilks.push(newIlk); - Ilk storage ilk = $.ilks[ilkIndex]; - - ilk.rate = 10 ** 27; - // Unsafe cast OK - ilk.lastRateUpdate = uint48(block.timestamp); - - emit IlkInitialized(ilkIndex, ilkAddress); - } - - /** - * @dev Updates the spot oracle for a given collateral. - * @param ilkIndex index of the collateral. - * @param newSpot address of the new spot oracle. - */ - function updateIlkSpot(uint8 ilkIndex, SpotOracle newSpot) external onlyRole(ION) { - IonPoolStorage storage $ = _getIonPoolStorage(); - - $.ilks[ilkIndex].spot = newSpot; - - emit IlkSpotUpdated(address(newSpot)); - } - - /** - * @notice A market can be sunset by setting the debt ceiling to 0. It would - * still be possible to repay debt but creating new debt would not be - * possible. - * @dev Updates the debt ceiling for a given collateral. - * @param ilkIndex index of the collateral. - * @param newCeiling new debt ceiling. - */ - function updateIlkDebtCeiling(uint8 ilkIndex, uint256 newCeiling) external onlyRole(ION) { - IonPoolStorage storage $ = _getIonPoolStorage(); - - $.ilks[ilkIndex].debtCeiling = newCeiling; - - emit IlkDebtCeilingUpdated(newCeiling); - } - - /** - * @notice When increasing the `dust`, it is possible that some vaults will - * be dusty after the update. However, changes to the vault position from - * there will require that the vault be non-dusty (either by repaying all - * debt or increasing debt beyond the `dust`). - * @dev Updates the dust amount for a given collateral. - * @param ilkIndex index of the collateral. - * @param newDust new dust - */ - function updateIlkDust(uint8 ilkIndex, uint256 newDust) external onlyRole(ION) { - IonPoolStorage storage $ = _getIonPoolStorage(); - - $.ilks[ilkIndex].dust = newDust; - - emit IlkDustUpdated(newDust); - } - - /** - * @notice Reducing the supply cap will not affect existing deposits. - * However, if it is below the `totalSupply`, then no new deposits will be - * allowed until the `totalSupply` is below the new `supplyCap`. - * @dev Updates the supply cap. - * @param newSupplyCap new supply cap. - */ - function updateSupplyCap(uint256 newSupplyCap) external onlyRole(ION) { - IonPoolStorage storage $ = _getIonPoolStorage(); - - $.wethSupplyCap = newSupplyCap; - - emit SupplyCapUpdated(newSupplyCap); - } - - /** - * @dev Updates the interest rate module. There is a check to ensure that - * `collateralCount()` on the new interest rate module match the current - * number of collaterals in the pool. - * @param _interestRateModule new interest rate module. - */ - function updateInterestRateModule(InterestRate _interestRateModule) external onlyRole(ION) { - if (address(_interestRateModule) == address(0)) revert InvalidInterestRateModule(_interestRateModule); - - IonPoolStorage storage $ = _getIonPoolStorage(); - - // Sanity check - if (_interestRateModule.COLLATERAL_COUNT() != $.ilks.length) { - revert InvalidInterestRateModule(_interestRateModule); - } - $.interestRateModule = _interestRateModule; - - emit InterestRateModuleUpdated(address(_interestRateModule)); - } - - /** - * @dev Updates the whitelist. - * @param _whitelist new whitelist address. - */ - function updateWhitelist(Whitelist _whitelist) external onlyRole(ION) { - if (address(_whitelist) == address(0)) revert InvalidWhitelist(_whitelist); - - IonPoolStorage storage $ = _getIonPoolStorage(); - - $.whitelist = _whitelist; - - emit WhitelistUpdated(address(_whitelist)); - } - - /** - * @dev Pause actions that put the protocol into a further unsafe state. - * These are actions that take liquidity out of the system (e.g. borrowing, - * withdrawing base) - */ - function pauseUnsafeActions() external onlyRole(ION) { - _pause(Pauses.UNSAFE); - } - - /** - * @dev Unpause actions that put the protocol into a further unsafe state. - */ - function unpauseUnsafeActions() external onlyRole(ION) { - _unpause(Pauses.UNSAFE); - } - - /** - * @dev Pause actions that put the protocol into a further safe state. - * These are actions that put liquidity into the system (e.g. repaying, - * depositing base) - * - * Pausing accrual is also necessary with this since disabling repaying - * should not continue to accrue interest. - * - * Also accrues interest before the pause to update all debt at the time the - * pause takes place. - */ - function pauseSafeActions() external onlyRole(ION) { - _pause(Pauses.SAFE); - _accrueInterest(); - } - - /** - * @dev Unpause actions that put the protocol into a further safe state. - * - * Will also update the `lastRateUpdate` to the unpause transaction - * timestamp. This essentially allows for a pausing and unpausing of the - * accrual of interest. - */ - function unpauseSafeActions() external onlyRole(ION) { - _unpause(Pauses.SAFE); - IonPoolStorage storage $ = _getIonPoolStorage(); - - uint256 ilksLength = $.ilks.length; - for (uint256 i = 0; i < ilksLength;) { - // Unsafe cast OK - $.ilks[i].lastRateUpdate = uint48(block.timestamp); - - // forgefmt: disable-next-line - unchecked { ++i; } - } - } - - // --- Interest Calculations --- - - /** - * @dev Updates accumulators for all `ilk`s based on current interest rates. - * @return newTotalDebt the new total debt after interest accrual - */ - function accrueInterest() external whenNotPaused(Pauses.SAFE) returns (uint256 newTotalDebt) { - return _accrueInterest(); - } - - function _accrueInterest() internal returns (uint256 newTotalDebt) { - IonPoolStorage storage $ = _getIonPoolStorage(); - - // Safe actions should really only be paused in conjunction with unsafe - // actions. However, if for some reason only safe actions were paused, - // it would still be possible to accrue interest by withdrawing and/or - // borrowing... so we prevent this outcome; but without reverting the tx - // altogether. - if (paused(Pauses.SAFE)) return ($.debt); - uint256 totalEthSupply = totalSupply(); - - uint256 totalSupplyFactorIncrease; - uint256 totalTreasuryMintAmount; - uint256 totalDebtIncrease; - - uint256 ilksLength = $.ilks.length; - for (uint8 i = 0; i < ilksLength;) { - ( - uint256 supplyFactorIncrease, - uint256 treasuryMintAmount, - uint104 newRateIncrease, - uint256 newDebtIncrease, - uint48 timestampIncrease - ) = _calculateRewardAndDebtDistribution(i, totalEthSupply); - - if (timestampIncrease > 0) { - Ilk storage ilk = $.ilks[i]; - ilk.rate += newRateIncrease; - ilk.lastRateUpdate += timestampIncrease; - totalDebtIncrease += newDebtIncrease; - - totalSupplyFactorIncrease += supplyFactorIncrease; - totalTreasuryMintAmount += treasuryMintAmount; - } - - // forgefmt: disable-next-line - unchecked { ++i; } - } - - newTotalDebt = $.debt + totalDebtIncrease; - $.debt = newTotalDebt; - _setSupplyFactor(supplyFactor() + totalSupplyFactorIncrease); - _mintToTreasury(totalTreasuryMintAmount); - } - - function _accrueInterestForIlk(uint8 ilkIndex) internal { - ( - uint256 supplyFactorIncrease, - uint256 treasuryMintAmount, - uint104 newRateIncrease, - uint256 newDebtIncrease, - uint48 timestampIncrease - ) = _calculateRewardAndDebtDistribution(ilkIndex, totalSupply()); - - IonPoolStorage storage $ = _getIonPoolStorage(); - - if (timestampIncrease > 0) { - Ilk storage ilk = $.ilks[ilkIndex]; - ilk.rate += newRateIncrease; - ilk.lastRateUpdate += timestampIncrease; - $.debt += newDebtIncrease; - - _setSupplyFactor(supplyFactor() + supplyFactorIncrease); - _mintToTreasury(treasuryMintAmount); - } - } - - function _calculateRewardAndDebtDistribution( - uint8 ilkIndex, - uint256 totalEthSupply - ) - internal - view - returns ( - uint256 supplyFactorIncrease, - uint256 treasuryMintAmount, - uint104 newRateIncrease, - uint256 newDebtIncrease, - uint48 timestampIncrease - ) - { - IonPoolStorage storage $ = _getIonPoolStorage(); - Ilk storage ilk = $.ilks[ilkIndex]; - - uint256 _totalNormalizedDebt = ilk.totalNormalizedDebt; - // Unsafe cast OK - if (_totalNormalizedDebt == 0 || block.timestamp == ilk.lastRateUpdate) { - return (0, 0, 0, 0, 0); - } - uint256 totalDebt = _totalNormalizedDebt * ilk.rate; // [WAD] * [RAY] = [RAD] - - (uint256 borrowRate, uint256 reserveFactor) = - $.interestRateModule.calculateInterestRate(ilkIndex, totalDebt, totalEthSupply); - - if (borrowRate == 0) return (0, 0, 0, 0, 0); - - // Calculates borrowRate ^ (time) and returns the result with RAY precision - uint256 borrowRateExpT = _rpow(borrowRate + RAY, block.timestamp - ilk.lastRateUpdate, RAY); - - // Unsafe cast OK - timestampIncrease = uint48(block.timestamp) - ilk.lastRateUpdate; - - // Debt distribution - // This form of rate accrual is much safer than distributing the new - // debt increase to the total debt since low debt amounts won't cause - // rounding errors to sky rocket the rate. This form of accrual is still - // subject to rate inflation, however, it would only be from an - // extremely high borrow rate rather than being a function of the - // current total debt in the system. This is very relevant for - // sunsetting markets, where the goal will be to reduce the total debt - // to 0. - newRateIncrease = ilk.rate.rayMulUp(borrowRateExpT - RAY).toUint104(); // [RAY] - - newDebtIncrease = _totalNormalizedDebt * newRateIncrease; // [RAD] - - // Income distribution - uint256 _normalizedTotalSupply = normalizedTotalSupply(); // [WAD] - - // If there is no supply, then nothing is being lent out. - supplyFactorIncrease = _normalizedTotalSupply == 0 - ? 0 - : newDebtIncrease.mulDiv(RAY - reserveFactor, _normalizedTotalSupply.scaleUpToRad(18)); // [RAD] * [RAY] / [RAD] - // = [RAY] - - treasuryMintAmount = newDebtIncrease.mulDiv(reserveFactor, 1e54); // [RAD] * [RAY] / 1e54 = [WAD] - } - - // --- Lender Operations --- - - /** - * @dev Allows lenders to redeem their interest-bearing position for the - * underlying asset. It is possible that dust amounts more of the position - * are burned than the underlying received due to rounding. - * @param receiverOfUnderlying the address to which the redeemed underlying - * asset should be sent to. - * @param amount of underlying to reedeem for. - */ - function withdraw(address receiverOfUnderlying, uint256 amount) external whenNotPaused(Pauses.UNSAFE) { - uint256 newTotalDebt = _accrueInterest(); - IonPoolStorage storage $ = _getIonPoolStorage(); - - $.weth -= amount; - - uint256 _supplyFactor = - _burn({ user: _msgSender(), receiverOfUnderlying: receiverOfUnderlying, amount: amount }); - - emit Withdraw(_msgSender(), receiverOfUnderlying, amount, _supplyFactor, newTotalDebt); - } - - /** - * @dev Allows lenders to deposit their underlying asset into the pool and - * earn interest on it. - * @param user the address to receive credit for the position. - * @param amount of underlying asset to use to create the position. - * @param proof merkle proof that the user is whitelisted. - */ - function supply( - address user, - uint256 amount, - bytes32[] calldata proof - ) - external - whenNotPaused(Pauses.SAFE) - onlyWhitelistedLenders(proof) - { - uint256 newTotalDebt = _accrueInterest(); - IonPoolStorage storage $ = _getIonPoolStorage(); - - $.weth += amount; - - uint256 _supplyFactor = _mint({ user: user, senderOfUnderlying: _msgSender(), amount: amount }); - - uint256 _supplyCap = $.wethSupplyCap; - if (totalSupply() > _supplyCap) revert DepositSurpassesSupplyCap(amount, _supplyCap); - - emit Supply(user, _msgSender(), amount, _supplyFactor, newTotalDebt); - } - - // --- Borrower Operations --- - - /** - * @dev Allows a borrower to create debt in a position. - * @param ilkIndex index of the collateral. - * @param user to create the position for. - * @param recipient to receive the borrowed funds - * @param amountOfNormalizedDebt to create. - * @param proof merkle proof that the user is whitelist. - */ - function borrow( - uint8 ilkIndex, - address user, - address recipient, - uint256 amountOfNormalizedDebt, - bytes32[] calldata proof - ) - external - whenNotPaused(Pauses.UNSAFE) - onlyWhitelistedBorrowers(ilkIndex, proof) - { - _accrueInterestForIlk(ilkIndex); - (uint104 ilkRate, uint256 newDebt) = - _modifyPosition(ilkIndex, user, address(0), recipient, 0, amountOfNormalizedDebt.toInt256()); - - emit Borrow(ilkIndex, user, recipient, amountOfNormalizedDebt, ilkRate, newDebt); - } - - /** - * @dev Allows a borrower to repay debt in a position. - * @param ilkIndex index of the collateral. - * @param user to repay the debt for. - * @param payer to source the funds from. - * @param amountOfNormalizedDebt to repay. - */ - function repay( - uint8 ilkIndex, - address user, - address payer, - uint256 amountOfNormalizedDebt - ) - external - whenNotPaused(Pauses.SAFE) - { - _accrueInterestForIlk(ilkIndex); - (uint104 ilkRate, uint256 newDebt) = - _modifyPosition(ilkIndex, user, address(0), payer, 0, -(amountOfNormalizedDebt.toInt256())); - - emit Repay(ilkIndex, user, payer, amountOfNormalizedDebt, ilkRate, newDebt); - } - - /** - * @dev Moves collateral from internal `vault.collateral` balances to `gem` - * @param ilkIndex index of the collateral. - * @param user to withdraw the collateral for. - * @param recipient to receive the collateral. - * @param amount to withdraw. - */ - function withdrawCollateral( - uint8 ilkIndex, - address user, - address recipient, - uint256 amount - ) - external - whenNotPaused(Pauses.UNSAFE) - { - _modifyPosition(ilkIndex, user, recipient, address(0), -(amount.toInt256()), 0); - - emit WithdrawCollateral(ilkIndex, user, recipient, amount); - } - - /** - * @dev Moves collateral from `gem` balances to internal `vault.collateral` - * @param ilkIndex index of the collateral. - * @param user to deposit the collateral for. - * @param depositor to deposit the collateral from. - * @param amount to deposit. - * @param proof merkle proof that the user is whitelisted. - */ - function depositCollateral( - uint8 ilkIndex, - address user, - address depositor, - uint256 amount, - bytes32[] calldata proof - ) - external - whenNotPaused(Pauses.SAFE) - onlyWhitelistedBorrowers(ilkIndex, proof) - { - _modifyPosition(ilkIndex, user, depositor, address(0), amount.toInt256(), 0); - - emit DepositCollateral(ilkIndex, user, depositor, amount); - } - - // --- CDP Manipulation --- - - function _modifyPosition( - uint8 ilkIndex, - address u, - address v, - address w, - int256 changeInCollateral, - int256 changeInNormalizedDebt - ) - internal - returns (uint104 ilkRate, uint256 newTotalDebt) - { - IonPoolStorage storage $ = _getIonPoolStorage(); - - ilkRate = $.ilks[ilkIndex].rate; - // ilk has been initialised - if (ilkRate == 0) revert IlkNotInitialized(ilkIndex); - - Vault memory _vault = $.vaults[ilkIndex][u]; - _vault.collateral = _add(_vault.collateral, changeInCollateral); - _vault.normalizedDebt = _add(_vault.normalizedDebt, changeInNormalizedDebt); - - uint104 _totalNormalizedDebt = _add($.ilks[ilkIndex].totalNormalizedDebt, changeInNormalizedDebt).toUint104(); - - // Prevent stack too deep - { - uint256 newTotalDebtInVault = ilkRate * _vault.normalizedDebt; - // either debt has decreased, or debt ceilings are not exceeded - if ( - both( - changeInNormalizedDebt > 0, - uint256(_totalNormalizedDebt) * uint256(ilkRate) > $.ilks[ilkIndex].debtCeiling - ) - ) { - revert CeilingExceeded(uint256(_totalNormalizedDebt) * uint256(ilkRate), $.ilks[ilkIndex].debtCeiling); - } - uint256 ilkSpot = $.ilks[ilkIndex].spot.getSpot(); - // vault is either less risky than before, or it is safe - if ( - both( - either(changeInNormalizedDebt > 0, changeInCollateral < 0), - newTotalDebtInVault > _vault.collateral * ilkSpot - ) - ) revert UnsafePositionChange(newTotalDebtInVault, _vault.collateral, ilkSpot); - - // vault is either more safe, or the owner consents - if (both(either(changeInNormalizedDebt > 0, changeInCollateral < 0), !isAllowed(u, _msgSender()))) { - revert UnsafePositionChangeWithoutConsent(ilkIndex, u, _msgSender()); - } - - // collateral src consents - if (both(changeInCollateral > 0, !isAllowed(v, _msgSender()))) { - revert UseOfCollateralWithoutConsent(ilkIndex, v, _msgSender()); - } - // debt dst consents - // Since changeInDebt is no longer being deducted in the form of - // internal accounting but rather directly in the erc20 WETH form, this - // contract must also have an approved role for the debt dst address on - // th erc20 WETH contract. Or else, the transfer will fail. - if (both(changeInNormalizedDebt < 0, !isAllowed(w, _msgSender()))) { - revert TakingWethWithoutConsent(w, _msgSender()); - } - - // vault has no debt, or a non-dusty amount - if (both(_vault.normalizedDebt != 0, newTotalDebtInVault < $.ilks[ilkIndex].dust)) { - revert VaultCannotBeDusty(newTotalDebtInVault, $.ilks[ilkIndex].dust); - } - } - - int256 changeInDebt = ilkRate.toInt256() * changeInNormalizedDebt; - - // mutation `v` -> `w` - $.gem[ilkIndex][w] = _sub($.gem[ilkIndex][v], changeInCollateral); - $.vaults[ilkIndex][u] = _vault; - $.ilks[ilkIndex].totalNormalizedDebt = _totalNormalizedDebt; - newTotalDebt = _add($.debt, changeInDebt); - $.debt = newTotalDebt; - - // If changeInDebt < 0, it is a repayment and WETH is being transferred - // into the protocol - _transferWeth(w, changeInDebt); - } - - // --- Settlement --- - - /** - * @dev To be used by protocol to settle bad debt using reserves - * NOTE: Can pay another user's bad debt with the sender's asset - * @param user the address that owns the bad debt being paid off - * @param rad amount of debt to be repaid (45 decimals) - */ - function repayBadDebt(address user, uint256 rad) external whenNotPaused(Pauses.SAFE) { - IonPoolStorage storage $ = _getIonPoolStorage(); - - $.unbackedDebt[user] -= rad; - $.totalUnbackedDebt -= rad; - $.debt -= rad; - - // Must be negative since it is a repayment - _transferWeth(_msgSender(), -(rad.toInt256())); - - emit RepayBadDebt(user, _msgSender(), rad); - } - - // --- Helpers --- - - /** - * @dev Helper function to deal with borrowing and repaying debt. A positive - * amount is a borrow while negative amount is a repayment - * @param user receiver if transfer to, or sender if transfer from - * @param amount amount to transfer [RAD] - */ - function _transferWeth(address user, int256 amount) internal { - if (amount == 0) return; - IonPoolStorage storage $ = _getIonPoolStorage(); - - if (amount < 0) { - uint256 amountUint = uint256(-amount); - uint256 amountWad = amountUint / RAY; - if (amountUint % RAY > 0) ++amountWad; - - $.weth += amountWad; - underlying().safeTransferFrom(user, address(this), amountWad); - } else { - // Round down in protocol's favor - uint256 amountWad = uint256(amount) / RAY; - - $.weth -= amountWad; - - underlying().safeTransfer(user, amountWad); - } - } - - // --- CDP Confiscation --- - - /** - * @dev This function foregoes pausability for pausability at the - * liquidation module layer - * @param ilkIndex index of the collateral. - * @param u user to confiscate the vault from. - * @param v address to either credit `gem` to or deduct `gem` from - * @param changeInCollateral collateral to add or remove from the vault - * @param changeInNormalizedDebt debt to add or remove from the vault - */ - function confiscateVault( - uint8 ilkIndex, - address u, - address v, - address w, - int256 changeInCollateral, - int256 changeInNormalizedDebt - ) - external - onlyRole(LIQUIDATOR_ROLE) - { - _accrueInterestForIlk(ilkIndex); - - IonPoolStorage storage $ = _getIonPoolStorage(); - - Vault storage _vault = $.vaults[ilkIndex][u]; - Ilk storage ilk = $.ilks[ilkIndex]; - uint104 ilkRate = ilk.rate; - - _vault.collateral = _add(_vault.collateral, changeInCollateral); - _vault.normalizedDebt = _add(_vault.normalizedDebt, changeInNormalizedDebt); - ilk.totalNormalizedDebt = _add(uint256(ilk.totalNormalizedDebt), changeInNormalizedDebt).toUint104(); - - // Unsafe cast OK since we know that ilkRate is less than 2^104 - int256 changeInDebt = int256(uint256(ilkRate)) * changeInNormalizedDebt; - - $.gem[ilkIndex][v] = _sub($.gem[ilkIndex][v], changeInCollateral); - $.unbackedDebt[w] = _sub($.unbackedDebt[w], changeInDebt); - $.totalUnbackedDebt = _sub($.totalUnbackedDebt, changeInDebt); - - emit ConfiscateVault(ilkIndex, u, v, w, changeInCollateral, changeInNormalizedDebt); - } - - // --- Fungibility --- - - /** - * @dev To be called by GemJoin contracts. After a user deposits collateral, credit the user with collateral - * internally - * @param ilkIndex collateral - * @param usr user - * @param wad amount to add or remove - */ - function mintAndBurnGem( - uint8 ilkIndex, - address usr, - int256 wad - ) - external - onlyRole(GEM_JOIN_ROLE) - { - IonPoolStorage storage $ = _getIonPoolStorage(); - - $.gem[ilkIndex][usr] = _add($.gem[ilkIndex][usr], wad); - - emit MintAndBurnGem(ilkIndex, usr, wad); - } - - /** - * @dev Transfer gem across the internal accounting of the pool - * @param ilkIndex index of the collateral - * @param src source of the gem - * @param dst destination of the gem - * @param wad amount of gem - */ - function transferGem(uint8 ilkIndex, address src, address dst, uint256 wad) external whenNotPaused(Pauses.UNSAFE) { - if (!isAllowed(src, _msgSender())) revert GemTransferWithoutConsent(ilkIndex, src, _msgSender()); - - IonPoolStorage storage $ = _getIonPoolStorage(); - - $.gem[ilkIndex][src] -= wad; - $.gem[ilkIndex][dst] += wad; - emit TransferGem(ilkIndex, src, dst, wad); - } - - // --- Getters --- - - /** - * @return The total amount of collateral in the pool. - */ - function ilkCount() public view returns (uint256) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.ilks.length; - } - - /** - * @return The index of the collateral with `ilkAddress`. - */ - function getIlkIndex(address ilkAddress) public view returns (uint8) { - IonPoolStorage storage $ = _getIonPoolStorage(); - bytes32 addressInBytes32 = bytes32(uint256(uint160(ilkAddress))); - - // Since there should never be more than 256 collaterals, an unsafe cast - // should be fine - return uint8($.ilkAddresses._inner._positions[addressInBytes32] - 1); - } - - /** - * @return The address of the collateral at index `ilkIndex`. - */ - function getIlkAddress(uint256 ilkIndex) public view returns (address) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.ilkAddresses.at(ilkIndex); - } - - /** - * @return Whether or not an address is a supported collateral. - */ - function addressContains(address ilk) public view returns (bool) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.ilkAddresses.contains(ilk); - } - - /** - * @return The total amount of addresses. - */ - function addressesLength() public view returns (uint256) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.ilkAddresses.length(); - } - - /** - * @return The total amount of normalized debt for collateral with index - * `ilkIndex`. - */ - function totalNormalizedDebt(uint8 ilkIndex) external view returns (uint256) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.ilks[ilkIndex].totalNormalizedDebt; - } - - /** - * @return The rate (debt accumulator) for collateral with index `ilkIndex`. - */ - function rate(uint8 ilkIndex) external view returns (uint256) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.ilks[ilkIndex].rate; - } - - /** - * @return The timestamp of the last rate update for collateral with index - * `ilkIndex`. - */ - function lastRateUpdate(uint8 ilkIndex) external view returns (uint256) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.ilks[ilkIndex].lastRateUpdate; - } - - /** - * @return The spot oracle for collateral with index `ilkIndex`. - */ - function spot(uint8 ilkIndex) external view returns (SpotOracle) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.ilks[ilkIndex].spot; - } - - /** - * @return debt ceiling for collateral with index `ilkIndex`. - */ - function debtCeiling(uint8 ilkIndex) external view returns (uint256) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.ilks[ilkIndex].debtCeiling; - } - - /** - * @return dust amount for collateral with index `ilkIndex`. - */ - function dust(uint8 ilkIndex) external view returns (uint256) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.ilks[ilkIndex].dust; - } - - /** - * @return The amount of collateral `user` has for collateral with index `ilkIndex`. - */ - function collateral(uint8 ilkIndex, address user) external view returns (uint256) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.vaults[ilkIndex][user].collateral; - } - - /** - * @return The amount of normalized debt `user` has for collateral with index `ilkIndex`. - */ - function normalizedDebt(uint8 ilkIndex, address user) external view returns (uint256) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.vaults[ilkIndex][user].normalizedDebt; - } - - /** - * @return All data within vault for `user` with index `ilkIndex`. - */ - function vault(uint8 ilkIndex, address user) external view returns (uint256, uint256) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return ($.vaults[ilkIndex][user].collateral, $.vaults[ilkIndex][user].normalizedDebt); - } - - /** - * @return Amount of `gem` that `user` has for collateral with index `ilkIndex`. - */ - function gem(uint8 ilkIndex, address user) external view returns (uint256) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.gem[ilkIndex][user]; - } - - /** - * @return The amount of unbacked debt `user` has. - */ - function unbackedDebt(address user) external view returns (uint256) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.unbackedDebt[user]; - } - - /** - * @return Whether or not `operator` is an `operator` on `user`'s positions. - */ - function isOperator(address user, address operator) external view returns (bool) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.isOperator[user][operator] == 1; - } - - /** - * @return Whether or not `operator` has permission to make unsafe changes - * to `user`'s positions. - */ - function isAllowed(address user, address operator) public view returns (bool) { - IonPoolStorage storage $ = _getIonPoolStorage(); - - return either(user == operator, $.isOperator[user][operator] == 1); - } - - /** - * @dev This includes unbacked debt. - * @return The total amount of debt. - */ - function debt() external view returns (uint256) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.debt; - } - - /** - * @return The total amount of unbacked debt. - */ - function totalUnbackedDebt() external view returns (uint256) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.totalUnbackedDebt; - } - - /** - * @return The address of interest rate module. - */ - function interestRateModule() external view returns (address) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return address($.interestRateModule); - } - - /** - * @return The address of the whitelist. - */ - function whitelist() external view returns (address) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return address($.whitelist); - } - - /** - * @return The total amount of ETH liquidity in the pool. - */ - function weth() external view returns (uint256) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.weth; - } - - /** - * @dev Gets the current borrow rate for borrowing against a given collateral. - */ - function getCurrentBorrowRate(uint8 ilkIndex) public view returns (uint256 borrowRate, uint256 reserveFactor) { - IonPoolStorage storage $ = _getIonPoolStorage(); - - uint256 totalEthSupply = totalSupply(); - uint256 _totalNormalizedDebt = $.ilks[ilkIndex].totalNormalizedDebt; - uint256 _rate = $.ilks[ilkIndex].rate; - - uint256 totalDebt = _totalNormalizedDebt * _rate; // [WAD] * [RAY] / [WAD] = [RAY] - - (borrowRate, reserveFactor) = $.interestRateModule.calculateInterestRate(ilkIndex, totalDebt, totalEthSupply); - borrowRate += RAY; - } - - /** - * @dev Calculates the increase in debt and supply factors for a given - * `ilkIndex` should it's interest be accrued. - * - */ - function calculateRewardAndDebtDistribution(uint8 ilkIndex) - external - view - returns ( - uint256 supplyFactorIncrease, - uint256 treasuryMintAmount, - uint104 newRateIncrease, - uint256 newDebtIncrease, - uint48 newTimestampIncrease - ) - { - return _calculateRewardAndDebtDistribution(ilkIndex, totalSupply()); - } - - /** - * @dev Address of the implementation. This is stored immutably on the - * implementation so that it can be read by the proxy. - */ - function implementation() external view returns (address) { - return ADDRESS_THIS; - } - - // --- Auth --- - - /** - * @dev Allows an `operator` to make unsafe changes to `_msgSender()`s - * positions. - */ - function addOperator(address operator) external { - IonPoolStorage storage $ = _getIonPoolStorage(); - - $.isOperator[_msgSender()][operator] = 1; - - emit AddOperator(_msgSender(), operator); - } - - /** - * @dev Disallows an `operator` to make unsafe changes to `_msgSender()`s - * positions. - */ - function removeOperator(address operator) external { - IonPoolStorage storage $ = _getIonPoolStorage(); - - $.isOperator[_msgSender()][operator] = 0; - - emit RemoveOperator(_msgSender(), operator); - } - - // --- Math --- - - function _add(uint256 x, int256 y) internal pure returns (uint256 z) { - // Overflow desirable - unchecked { - z = x + uint256(y); - } - if (y < 0 && z > x) revert ArithmeticError(); - if (y > 0 && z < x) revert ArithmeticError(); - } - - function _sub(uint256 x, int256 y) internal pure returns (uint256 z) { - // Underflow desirable - unchecked { - z = x - uint256(y); - } - if (y > 0 && z > x) revert ArithmeticError(); - if (y < 0 && z < x) revert ArithmeticError(); - } - - /** - * @dev x and the returned value are to be interpreted as fixed-point - * integers with scaling factor b. For example, if b == 100, this specifies - * two decimal digits of precision and the normal decimal value 2.1 would be - * represented as 210; rpow(210, 2, 100) returns 441 (the two-decimal digit - * fixed-point representation of 2.1^2 = 4.41) (From MCD docs) - * @param x base - * @param n exponent - * @param b scaling factor - */ - function _rpow(uint256 x, uint256 n, uint256 b) internal pure returns (uint256 z) { - assembly { - switch x - case 0 { - switch n - case 0 { z := b } - default { z := 0 } - } - default { - switch mod(n, 2) - case 0 { z := b } - default { z := x } - let half := div(b, 2) // for rounding. - for { n := div(n, 2) } n { n := div(n, 2) } { - let xx := mul(x, x) - if iszero(eq(div(xx, x), x)) { revert(0, 0) } - let xxRound := add(xx, half) - if lt(xxRound, xx) { revert(0, 0) } - x := div(xxRound, b) - if mod(n, 2) { - let zx := mul(z, x) - if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) { revert(0, 0) } - let zxRound := add(zx, half) - if lt(zxRound, zx) { revert(0, 0) } - z := div(zxRound, b) - } - } - } - } - } - - // --- Boolean --- - - function either(bool x, bool y) internal pure returns (bool z) { - assembly { - z := or(x, y) - } - } - - function both(bool x, bool y) internal pure returns (bool z) { - assembly { - z := and(x, y) - } - } -} diff --git a/certora/mutations/Liquidation/Liquidation_P.sol b/certora/mutations/Liquidation/Liquidation_P.sol deleted file mode 100644 index 97382806..00000000 --- a/certora/mutations/Liquidation/Liquidation_P.sol +++ /dev/null @@ -1,257 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.21; - -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import { WadRayMath, RAY } from "./libraries/math/WadRayMath.sol"; -import { IonPool } from "src/IonPool.sol"; -import { ReserveOracle } from "src/oracles/reserve/ReserveOracle.sol"; -import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol"; - -contract Liquidation { - using SafeERC20 for IERC20; - using WadRayMath for uint256; - using SafeCast for uint256; - - error LiquidationThresholdCannotBeZero(); - error ExchangeRateCannotBeZero(); - error VaultIsNotUnsafe(uint256 healthRatio); - error InvalidReserveOraclesLength(uint256 length); - error InvalidLiquidationThresholdsLength(uint256 length); - - // --- Parameters --- - - uint256 public immutable TARGET_HEALTH; // [ray] ex) 1.25e27 is 125% - uint256 public immutable BASE_DISCOUNT; // [ray] ex) 0.02e27 is 2% - - uint256 public immutable MAX_DISCOUNT_0; // [ray] ex) 0.2e27 is 20% - uint256 public immutable MAX_DISCOUNT_1; - uint256 public immutable MAX_DISCOUNT_2; - - // liquidation thresholds - uint256 public immutable LIQUIDATION_THRESHOLD_0; // [ray] liquidation threshold for ilkIndex 0 - uint256 public immutable LIQUIDATION_THRESHOLD_1; // [ray] - uint256 public immutable LIQUIDATION_THRESHOLD_2; // [ray] - - // exchange rates - address public immutable RESERVE_ORACLE_0; // reserve oracle providing exchange rate for ilkIndex 0 - address public immutable RESERVE_ORACLE_1; - address public immutable RESERVE_ORACLE_2; - - address public immutable PROTOCOL; // receives confiscated vault debt and collateral - - IonPool public immutable POOL; - IERC20 public immutable UNDERLYING; - - // --- Events --- - event Liquidate(address indexed kpr, uint8 indexed ilkIndex, uint256 repay, uint256 gemOut); - - constructor( - address _ionPool, - address _protocol, - address[] memory _reserveOracles, - uint256[] memory _liquidationThresholds, - uint256 _targetHealth, - uint256 _reserveFactor, - uint256[] memory _maxDiscount - ) { - IonPool ionPool_ = IonPool(_ionPool); - POOL = ionPool_; - PROTOCOL = _protocol; - - uint256 ilkCount = POOL.ilkCount(); - if (_reserveOracles.length != ilkCount) { - revert InvalidReserveOraclesLength(_reserveOracles.length); - } - if (_liquidationThresholds.length != ilkCount) { - revert InvalidLiquidationThresholdsLength(_liquidationThresholds.length); - } - - TARGET_HEALTH = _targetHealth; - BASE_DISCOUNT = _reserveFactor; - - MAX_DISCOUNT_0 = _maxDiscount[0]; - MAX_DISCOUNT_1 = _maxDiscount[1]; - MAX_DISCOUNT_2 = _maxDiscount[2]; - - IERC20 underlying = ionPool_.underlying(); - underlying.approve(address(ionPool_), type(uint256).max); // approve ionPool to transfer the UNDERLYING asset - UNDERLYING = underlying; - - LIQUIDATION_THRESHOLD_0 = _liquidationThresholds[0]; - LIQUIDATION_THRESHOLD_1 = _liquidationThresholds[1]; - LIQUIDATION_THRESHOLD_2 = _liquidationThresholds[2]; - - RESERVE_ORACLE_0 = _reserveOracles[0]; - RESERVE_ORACLE_1 = _reserveOracles[1]; - RESERVE_ORACLE_2 = _reserveOracles[2]; - } - - struct Configs { - uint256 liquidationThreshold; - uint256 maxDiscount; - address reserveOracle; - } - /** - * @notice Returns the exchange rate and liquidation threshold for the given ilkIndex. - */ - function _getConfigs(uint8 ilkIndex) - internal - view - returns (Configs memory configs) - { - address reserveOracle; - if (ilkIndex == 0) { - configs.reserveOracle = RESERVE_ORACLE_0; - configs.liquidationThreshold = LIQUIDATION_THRESHOLD_0; - configs.maxDiscount = MAX_DISCOUNT_0; - } else if (ilkIndex == 1) { - configs.reserveOracle = RESERVE_ORACLE_1; - configs.liquidationThreshold = LIQUIDATION_THRESHOLD_1; - configs.maxDiscount = MAX_DISCOUNT_1; - } else if (ilkIndex == 2) { - configs.reserveOracle = RESERVE_ORACLE_2; - configs.liquidationThreshold = LIQUIDATION_THRESHOLD_2; - configs.maxDiscount = MAX_DISCOUNT_2; - } - } - - /** - * @notice Internal helper function for calculating the repay amount. - * @param debtValue [rad] totalDebt - * @param collateralValue [rad] collateral * exchangeRate * liquidationThreshold - * @param liquidationThreshold [ray] - * @param discount [ray] - * @return repay [rad] - */ - function _getRepayAmt( - uint256 debtValue, - uint256 collateralValue, - uint256 liquidationThreshold, - uint256 discount - ) - internal - view - returns (uint256 repay) - { - // repayNum = (targetHealth * totalDebt - collateral * exchangeRate * liquidationThreshold) - // repayDen = (targetHealth - (liquidationThreshold / (1 - discount))) - // repay = repayNum / repayDen - - // round up repay in protocol favor for safer post-liquidation position - uint256 repayNum = debtValue.rayMulUp(TARGET_HEALTH) - collateralValue; // [rad] - [rad] = [rad] - uint256 repayDen = TARGET_HEALTH - liquidationThreshold.rayDivUp(RAY - discount); // [ray] - repay = repayNum.rayDivUp(repayDen); // [rad] * RAY / [ray] = [rad] - } - - struct LiquidateArgs { - uint256 repay; - uint256 gemOut; - uint256 dart; - uint256 fee; - uint256 price; - } - - /** - * @notice Executes collateral sale and repayment of debt by liquidators. - * @param ilkIndex index of the collateral in IonPool - * @param vault the position to be liquidated - * @param kpr payer of the debt and receiver of the collateral - */ - function liquidate(uint8 ilkIndex, address vault, address kpr) external { - LiquidateArgs memory liquidateArgs; - - Configs memory configs = _getConfigs(ilkIndex); - - // exchangeRate is reported in uint72 in [wad], but should be converted to uint256 [ray] - uint256 exchangeRate = uint256(ReserveOracle(configs.reserveOracle).currentExchangeRate()).scaleUpToRay(18); - (uint256 collateral, uint256 normalizedDebt) = POOL.vault(ilkIndex, vault); - uint256 rate = POOL.rate(ilkIndex); - - if (exchangeRate == 0) { - revert ExchangeRateCannotBeZero(); - } - if (configs.liquidationThreshold == 0) { - revert LiquidationThresholdCannotBeZero(); - } - - // collateralValue = collateral * exchangeRate * liquidationThreshold - // debtValue = normalizedDebt * rate - // healthRatio = collateralValue / debtValue - // collateralValue = [wad] * [ray] * [ray] / RAY = [rad] - // debtValue = [wad] * [ray] = [rad] - // healthRatio = [rad] * RAY / [rad] = [ray] - // round down in protocol favor - uint256 collateralValue = (collateral * exchangeRate).rayMulDown(configs.liquidationThreshold); - { - uint256 healthRatio = collateralValue.rayDivDown(normalizedDebt * rate); // round down in protocol favor - if (healthRatio >= RAY) { - revert VaultIsNotUnsafe(healthRatio); - } - - uint256 discount = BASE_DISCOUNT + (RAY - healthRatio); // [ray] + ([ray] - [ray]) - // mutation: `<=` -> `>=` - discount = discount >= configs.maxDiscount ? discount : configs.maxDiscount; // cap discount to maxDiscount - liquidateArgs.price = exchangeRate.rayMulUp(RAY - discount); // ETH price per LST, round up in protocol - // favor - liquidateArgs.repay = _getRepayAmt(normalizedDebt * rate, collateralValue, configs.liquidationThreshold, discount); - } - - // First branch: protocol liquidation - // if repay > total debt, more debt needs to be paid off than available to go back to target health - // Move exactly all collateral and debt to the protocol. - // Second branch: resulting debt is below dust - // There is enough collateral to cover the debt and go back to target health, - // but it would leave a debt amount less than dust. - // Force keeper to pay off all debt including dust and readjust the amount of collateral to sell. - // Resulting debt should always be zero. - // Third branch: partial liquidation to target health ratio - // There is enough collateral to be sold to pay off debt. - // Liquidator pays portion of the debt and receives collateral. - // The resulting health ratio should equal target health. - if (liquidateArgs.repay > normalizedDebt * rate) { - // [rad] > [rad] - liquidateArgs.dart = normalizedDebt; // [wad] - liquidateArgs.gemOut = collateral; // [wad] - POOL.confiscateVault( - ilkIndex, vault, PROTOCOL, PROTOCOL, -int256(liquidateArgs.gemOut), -int256(liquidateArgs.dart) - ); - emit Liquidate(kpr, ilkIndex, liquidateArgs.dart, liquidateArgs.gemOut); - return; // early return - } else if (normalizedDebt * rate - liquidateArgs.repay < POOL.dust(ilkIndex)) { - // [rad] - [rad] < [rad] - liquidateArgs.repay = normalizedDebt * rate; // bound repay to total debt - liquidateArgs.dart = normalizedDebt; // pay off all debt including dust - liquidateArgs.gemOut = normalizedDebt * rate / liquidateArgs.price; // round down in protocol favor - } else { - // if (normalizedDebt * rate - liquidateArgs.repay >= dust) do partial liquidation - // round up in protocol favor - liquidateArgs.dart = liquidateArgs.repay / rate; // [rad] / [ray] = [wad] - if (liquidateArgs.repay % rate > 0) ++liquidateArgs.dart; // round up in protocol favor - // round down in protocol favor - liquidateArgs.gemOut = liquidateArgs.repay / liquidateArgs.price; // readjust amount of collateral - liquidateArgs.repay = liquidateArgs.dart * rate; // 27 decimals precision loss on original repay - } - - // below code is only reached for dust or partial liquidations - - // exact amount to be transferred in `_transferWeth` - uint256 transferAmt = (liquidateArgs.repay / RAY); - if (liquidateArgs.repay % RAY > 0) ++transferAmt; // round up in protocol favor - - // transfer WETH from keeper to this contract - UNDERLYING.safeTransferFrom(msg.sender, address(this), transferAmt); - - // take the debt to pay off and the collateral to sell from the vault - // kpr gets the gemOut - POOL.confiscateVault( - ilkIndex, vault, kpr, address(this), -(liquidateArgs.gemOut.toInt256()), -(liquidateArgs.dart.toInt256()) - ); - - // pay off the unbacked debt - POOL.repayBadDebt(address(this), liquidateArgs.repay); - - emit Liquidate(kpr, ilkIndex, liquidateArgs.dart, liquidateArgs.gemOut); - } -} diff --git a/certora/specs/InterestRate.spec b/certora/specs/InterestRate.spec deleted file mode 100644 index 9859f4c3..00000000 --- a/certora/specs/InterestRate.spec +++ /dev/null @@ -1 +0,0 @@ -use builtin rule sanity; diff --git a/certora/specs/IonPool.spec b/certora/specs/IonPool.spec deleted file mode 100644 index 8935dc95..00000000 --- a/certora/specs/IonPool.spec +++ /dev/null @@ -1,57 +0,0 @@ -import "erc20.spec"; - -use builtin rule sanity; - -methods { - // Interest rate model - function _.calculateInterestRate(uint256, uint256, uint256) external => DISPATCHER(true); - function _.COLLATERAL_COUNT() external => DISPATCHER(true); - - // Spot oracle - function _.getSpot() external => getSpotCVL() expect uint256; - - // Whitelist - function _.isWhitelistedBorrower(uint8 ilkIndex, address poolCaller, address addr, bytes32[] proof) external => getWhitelistCVL(poolCaller) expect bool; - function _.isWhitelistedLender(address poolCaller, address addr, bytes32[] proof) external => getWhitelistCVL(poolCaller) expect bool; - - // Chainlink - function _.latestRoundData() external => latestRoundDataCVL() expect (uint80, int256, uint256, uint256, uint80); - - function _.getStETHByWstETH(uint256 amount) external => getStETHByWstETHCVL(amount) expect (uint256); - - // mulDiv summary for better run time - function _.mulDiv(uint x, uint y, uint denominator) internal => mulDivCVL(x,y,denominator) expect uint; -} - -ghost uint80 roundId; -ghost int256 answer; -ghost uint256 startedAt; -ghost uint256 updatedAt; -ghost uint80 answeredInRound; - -function latestRoundDataCVL() returns (uint80, int256, uint256, uint256, uint80) { - return (roundId, answer, startedAt, updatedAt, answeredInRound); -} - -ghost uint256 spot; - -function getSpotCVL() returns uint256 { - return spot; -} - -ghost mapping(uint256 => uint256) getStETHByWstETH_Ghost; - -ghost mapping(address => bool) isWhitelisted_Ghost; - -function getWhitelistCVL(address user) returns bool { - return isWhitelisted_Ghost[user]; -} - -function getStETHByWstETHCVL(uint256 amount) returns uint256 { - return getStETHByWstETH_Ghost[amount]; -} - -function mulDivCVL(uint x, uint y, uint denominator) returns uint { - require(denominator != 0); - return require_uint256(x*y/denominator); -} \ No newline at end of file diff --git a/certora/specs/Liquidation.spec b/certora/specs/Liquidation.spec deleted file mode 100644 index 972eb9de..00000000 --- a/certora/specs/Liquidation.spec +++ /dev/null @@ -1,53 +0,0 @@ -import "erc20.spec"; - -using ERC20A as underlying; -using ERC20B as underlyingForPool; -using IonPool as Ion; - -use builtin rule sanity; - -methods { - function _.currentExchangeRate() external => DISPATCHER(true); - - // mulDiv summary for better run time - function _.mulDiv(uint x, uint y, uint denominator) internal => cvlMulDiv(x,y,denominator) expect uint; - - // InterestRate - // Summarizing this function will improve run time, use NONDET if output doesn't matter - function _.calculateInterestRate(uint256,uint256,uint256) external => DISPATCHER(true); - - // YieldOracle - function _.apys(uint256) external => PER_CALLEE_CONSTANT; - - // envfree definitions - function Ion.underlying() external returns (address) envfree; - function underlying.balanceOf(address) external returns (uint256) envfree; - function underlyingForPool.balanceOf(address) external returns (uint256) envfree; -} - -function cvlMulDiv(uint x, uint y, uint denominator) returns uint { - require(denominator != 0); - return require_uint256(x*y/denominator); -} - -rule basicFRule(env e) { - uint8 ilkIndex; - address vault; - address kpr; - - require Ion.underlying() == underlyingForPool; - - uint256 underlyingBalanceBefore = underlying.balanceOf(currentContract); - uint256 underForPoolBefore = underlyingForPool.balanceOf(currentContract); - - // aliasing assumptions - // require vault != kpr; - // require e.msg.sender != currentContract; - - liquidate(e, ilkIndex, vault, kpr); - - uint256 underlyingBalanceAfter = underlying.balanceOf(currentContract); - uint256 underForPoolAfter = underlyingForPool.balanceOf(currentContract); - - assert underlyingBalanceAfter > underlyingBalanceBefore => underForPoolAfter > underForPoolBefore, "Unexpected balance change"; -} \ No newline at end of file diff --git a/certora/specs/erc20.spec b/certora/specs/erc20.spec deleted file mode 100644 index ca1cabec..00000000 --- a/certora/specs/erc20.spec +++ /dev/null @@ -1,12 +0,0 @@ -// erc20 methods -methods { - function _.name() external => DISPATCHER(true); - function _.symbol() external => DISPATCHER(true); - function _.decimals() external => DISPATCHER(true); - function _.totalSupply() external => DISPATCHER(true); - function _.balanceOf(address) external => DISPATCHER(true); - function _.allowance(address,address) external => DISPATCHER(true); - function _.approve(address,uint256) external => DISPATCHER(true); - function _.transfer(address,uint256) external => DISPATCHER(true); - function _.transferFrom(address,address,uint256) external => DISPATCHER(true); -} diff --git a/foundry.toml b/foundry.toml index 5a4c56ba..f7be527d 100644 --- a/foundry.toml +++ b/foundry.toml @@ -14,7 +14,7 @@ remappings = ["@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "forge-safe/=lib/forge-safe/src/"] fs_permissions = [{ access = "read-write", path = "./"}] optimizer = true -optimizer_runs = 300 +optimizer_runs = 200 no_match_contract = "Echidna" no_match_path = "script/**/*.sol" gas_reports = ["IonHandler", "IonRegistry", "TransparentUpgradeableProxy", "IonPool", "WstEthHandler", "EthXHandler", "SwEthHandler", "GemJoin", "InterestRate", "Whitelist", "WeEthHandler"] diff --git a/script/ValidateInterface.s.sol b/script/ValidateInterface.s.sol index 05c3071c..d60272e5 100644 --- a/script/ValidateInterface.s.sol +++ b/script/ValidateInterface.s.sol @@ -16,11 +16,9 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; * checking there is code at the provided address and calling a few functions. */ abstract contract ValidateInterface { - function _validateInterface(IonPool ionPool) internal view { + function _validateInterfaceIonPool(IonPool ionPool) internal view { require(address(ionPool).code.length > 0, "ionPool address must have code"); ionPool.balanceOf(address(this)); - ionPool.debt(); - ionPool.isOperator(address(this), address(this)); } function _validateInterface(IERC20 ilkAddress) internal view { diff --git a/script/actions/Pause.sol b/script/actions/Pause.sol index 96461f76..b00d9823 100644 --- a/script/actions/Pause.sol +++ b/script/actions/Pause.sol @@ -12,7 +12,7 @@ address constant SAFE = 0xcecc1978A819D4A3c0A2ee7C260ECb7A10732EEF; contract PausePool is BaseScript, BatchScript { function run(bool send, IonPool ionPool) public broadcast { - _validateInterface(ionPool); + // _validateInterface(ionPool); bytes memory pause = abi.encodeWithSelector(IonPool.pause.selector); @@ -24,7 +24,7 @@ contract PausePool is BaseScript, BatchScript { contract UnpausePool is BaseScript, BatchScript { function run(bool send, IonPool ionPool) public broadcast { - _validateInterface(ionPool); + // _validateInterface(ionPool); bytes memory unpause = abi.encodeWithSelector(IonPool.unpause.selector); @@ -36,7 +36,7 @@ contract UnpausePool is BaseScript, BatchScript { contract PauseGemJoin is BaseScript, BatchScript { function run(bool send, GemJoin gemJoin) public broadcast { - _validateInterface(gemJoin); + // _validateInterface(gemJoin); bytes memory pause = abi.encodeWithSelector(GemJoin.pause.selector, gemJoin); @@ -61,11 +61,11 @@ contract UnpauseGemJoin is BaseScript, BatchScript { */ contract PauseSystem is BaseScript, BatchScript { function run(bool send, GemJoin gemJoin) public broadcast { - _validateInterface(gemJoin); + // _validateInterface(gemJoin); IonPool pool = IonPool(gemJoin.POOL()); - _validateInterface(pool); + // _validateInterface(pool); bytes memory pause = abi.encodeWithSelector(IonPool.pause.selector); @@ -82,11 +82,11 @@ contract PauseSystem is BaseScript, BatchScript { */ contract UnpauseSystem is BaseScript, BatchScript { function run(bool send, GemJoin gemJoin) public broadcast { - _validateInterface(gemJoin); + // _validateInterface(gemJoin); IonPool pool = IonPool(gemJoin.POOL()); - _validateInterface(pool); + // _validateInterface(pool); bytes memory unpause = abi.encodeWithSelector(IonPool.unpause.selector); diff --git a/script/actions/params/UpdateDebtCeiling.s.sol b/script/actions/params/UpdateDebtCeiling.s.sol index c0164ebd..ca528e38 100644 --- a/script/actions/params/UpdateDebtCeiling.s.sol +++ b/script/actions/params/UpdateDebtCeiling.s.sol @@ -13,7 +13,7 @@ contract UpdateDebtCeiling is BaseScript, BatchScript { function run(bool _send, IonPool ionPool, uint256 newDebtCeiling) public { require(newDebtCeiling == 0 || newDebtCeiling >= 1e45, "debt ceiling is nominated in RAD"); - _validateInterface(ionPool); + // _validateInterface(ionPool); bytes memory txData = abi.encodeWithSelector( IonPool.updateIlkDebtCeiling.selector, diff --git a/script/actions/params/UpdateDust.s.sol b/script/actions/params/UpdateDust.s.sol index 6186aace..965c9ca5 100644 --- a/script/actions/params/UpdateDust.s.sol +++ b/script/actions/params/UpdateDust.s.sol @@ -13,7 +13,7 @@ contract UpdateDust is BaseScript, BatchScript { function run(bool _send, IonPool ionPool, uint256 newDust) public { require(newDust == 0 || newDust >= 1e45, "dust is nominated in RAD"); - _validateInterface(ionPool); + // _validateInterface(ionPool); bytes memory txData = abi.encodeWithSelector( IonPool.updateIlkDust.selector, diff --git a/script/actions/params/UpdateInterestRateModule.s.sol b/script/actions/params/UpdateInterestRateModule.s.sol index 0e506059..160ef70d 100644 --- a/script/actions/params/UpdateInterestRateModule.s.sol +++ b/script/actions/params/UpdateInterestRateModule.s.sol @@ -12,8 +12,8 @@ address constant SAFE = 0xcecc1978A819D4A3c0A2ee7C260ECb7A10732EEF; contract UpdateInterestRateModule is BaseScript, BatchScript { function run(bool _send, IonPool ionPool, InterestRate newModule) public { - _validateInterface(ionPool); - _validateInterface(newModule); + // _validateInterface(ionPool); + // _validateInterface(newModule); bytes memory txData = abi.encodeWithSelector(IonPool.updateInterestRateModule.selector, newModule); diff --git a/script/actions/params/UpdateLenderRoot.s.sol b/script/actions/params/UpdateLenderRoot.s.sol index 80622f73..d4dc0946 100644 --- a/script/actions/params/UpdateLenderRoot.s.sol +++ b/script/actions/params/UpdateLenderRoot.s.sol @@ -11,7 +11,7 @@ address constant SAFE = 0xcecc1978A819D4A3c0A2ee7C260ECb7A10732EEF; contract UpdateLenderRoot is BaseScript, BatchScript { function run(bool _send, Whitelist whitelist, bytes32 newRoot) public { - _validateInterface(whitelist); + // _validateInterface(whitelist); bytes memory txData = abi.encodeWithSelector(Whitelist.updateLendersRoot.selector, newRoot); diff --git a/script/actions/params/UpdateSpot.s.sol b/script/actions/params/UpdateSpot.s.sol index c98ce8b1..69a1fd1f 100644 --- a/script/actions/params/UpdateSpot.s.sol +++ b/script/actions/params/UpdateSpot.s.sol @@ -12,8 +12,8 @@ address constant SAFE = 0xcecc1978A819D4A3c0A2ee7C260ECb7A10732EEF; contract UpdateSpot is BaseScript, BatchScript { function run(bool _send, IonPool ionPool, SpotOracle newSpot) public { - _validateInterface(ionPool); - _validateInterface(newSpot); + // _validateInterface(ionPool); + // _validateInterface(newSpot); bytes memory txData = abi.encodeWithSelector( IonPool.updateIlkSpot.selector, diff --git a/script/actions/params/UpdateSupplyCap.s.sol b/script/actions/params/UpdateSupplyCap.s.sol index 4de84ec4..f8c306c5 100644 --- a/script/actions/params/UpdateSupplyCap.s.sol +++ b/script/actions/params/UpdateSupplyCap.s.sol @@ -11,7 +11,7 @@ address constant SAFE = 0xcecc1978A819D4A3c0A2ee7C260ECb7A10732EEF; contract UpdateSupplyCap is BaseScript, BatchScript { function run(bool _send, IonPool ionPool, address newSupplyCap) public { - _validateInterface(ionPool); + // _validateInterface(ionPool); bytes memory txData = abi.encodeWithSelector(IonPool.updateSupplyCap.selector, newSupplyCap); diff --git a/script/actions/params/UpdateWhitelist.s.sol b/script/actions/params/UpdateWhitelist.s.sol index 62bd7d90..68be0113 100644 --- a/script/actions/params/UpdateWhitelist.s.sol +++ b/script/actions/params/UpdateWhitelist.s.sol @@ -12,8 +12,8 @@ address constant SAFE = 0xcecc1978A819D4A3c0A2ee7C260ECb7A10732EEF; contract UpdateWhitelist is BaseScript, BatchScript { function run(bool _send, IonPool ionPool, Whitelist newWhitelist) public { - _validateInterface(ionPool); - _validateInterface(newWhitelist); + // _validateInterface(ionPool); + // _validateInterface(newWhitelist); bytes memory txData = abi.encodeWithSelector(IonPool.updateWhitelist.selector, newWhitelist); diff --git a/script/deploy-test/00_DeployTestBase.t.sol b/script/deploy-test/00_DeployTestBase.t.sol index b131206b..5fb9a23b 100644 --- a/script/deploy-test/00_DeployTestBase.t.sol +++ b/script/deploy-test/00_DeployTestBase.t.sol @@ -1,11 +1,16 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.21; +import { IonLens } from "../../src/periphery/IonLens.sol"; + import { Test } from "forge-std/Test.sol"; abstract contract DeployTestBase is Test { + IonLens public lens; + function setUp() public { uint256 mainnetFork = vm.createFork(vm.envString("DEPLOY_TEST_RPC_URL")); vm.selectFork(mainnetFork); + lens = new IonLens(); } } diff --git a/script/deploy-test/04_DeployIonPool.t.sol b/script/deploy-test/04_DeployIonPool.t.sol index be375da8..f21f361d 100644 --- a/script/deploy-test/04_DeployIonPool.t.sol +++ b/script/deploy-test/04_DeployIonPool.t.sol @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.21; +import { IIonPool } from "../../src/interfaces/IIonPool.sol"; import { IonPool } from "../../src/IonPool.sol"; import { DeployTestBase } from "./00_DeployTestBase.t.sol"; import { DeployIonPoolScript } from "../deploy/04_DeployIonPool.s.sol"; @@ -9,14 +10,15 @@ address constant CREATEX_PUBLIC_KEY = 0x01bd9aBD70D74D8eC70D338bD6099ca29DA3F9B4 contract DeployIonPoolTest is DeployTestBase, DeployIonPoolScript { function checkState(IonPool ionPool) public { - assertGt(address(ionPool).code.length, 0, "code"); + address ionPoolAddr = address(ionPool); + assertGt(ionPoolAddr.code.length, 0, "code"); assertEq(ionPool.owner(), initialDefaultAdmin, "owner"); assertEq(ionPool.defaultAdmin(), initialDefaultAdmin, "initial default admin"); assertEq(address(ionPool.underlying()), underlying, "underlying"); assertEq(ionPool.treasury(), treasury, "treasury"); assertEq(ionPool.decimals(), 18, "decimals"); - assertEq(ionPool.interestRateModule(), address(interestRateModule), "interest rate module"); - assertEq(ionPool.whitelist(), address(whitelist), "whitelist"); + assertEq(lens.interestRateModule(IIonPool(ionPoolAddr)), address(interestRateModule), "interest rate module"); + assertEq(lens.whitelist(IIonPool(ionPoolAddr)), address(whitelist), "whitelist"); vm.startPrank(initialDefaultAdmin); ionPool.beginDefaultAdminTransfer(protocol); diff --git a/script/deploy-test/06_SetupCollateral.t.sol b/script/deploy-test/06_SetupCollateral.t.sol index b543c6b6..40ecf082 100644 --- a/script/deploy-test/06_SetupCollateral.t.sol +++ b/script/deploy-test/06_SetupCollateral.t.sol @@ -1,20 +1,21 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.21; +import { IIonPool } from "../../src/interfaces/IIonPool.sol"; import { DeployTestBase } from "./00_DeployTestBase.t.sol"; import { SetupCollateralScript } from "../deploy/06_SetupCollateral.s.sol"; contract SetupCollateralTest is DeployTestBase, SetupCollateralScript { function checkState() public { - assertEq(ionPool.ilkCount(), 1, "ilk count"); - assertEq(ionPool.getIlkIndex(ilkAddress), 0, "ilk index"); + IIonPool iIonPool = IIonPool(address(ionPool)); + assertEq(lens.ilkCount(iIonPool), 1, "ilk count"); + assertEq(lens.getIlkIndex(iIonPool, ilkAddress), 0, "ilk index"); assertEq(ionPool.getIlkAddress(0), ilkAddress, "get ilk address"); - assertTrue(ionPool.addressContains(ilkAddress), "address contains"); - assertEq(address(ionPool.spot(0)), address(spotOracle), "spot oracle"); - assertEq(ionPool.debtCeiling(0), 0, "debt ceiling must be zero on init"); - assertEq(ionPool.dust(0), dust, "dust"); + assertEq(address(lens.spot(iIonPool, 0)), address(spotOracle), "spot oracle"); + assertEq(lens.debtCeiling(iIonPool, 0), debtCeiling, "debt ceiling"); + assertEq(lens.dust(iIonPool, 0), dust, "dust"); } function test_PreExecution() public { diff --git a/script/deploy/04_DeployIonPool.s.sol b/script/deploy/04_DeployIonPool.s.sol index 1cd14fae..029683d6 100644 --- a/script/deploy/04_DeployIonPool.s.sol +++ b/script/deploy/04_DeployIonPool.s.sol @@ -35,7 +35,7 @@ contract DeployIonPoolScript is DeployScript { _validateInterface(whitelist); ionImpl = IonPool(0xAd71a9e73e235A61caEb10059B64459FAB23B8C7); - _validateInterface(ionImpl); + _validateInterfaceIonPool(ionImpl); // if (deployCreate2) { // ionImpl = new IonPool{ salt: DEFAULT_SALT }(); diff --git a/script/deploy/06_SetupCollateral.s.sol b/script/deploy/06_SetupCollateral.s.sol index 6bead8b1..ff1dd952 100644 --- a/script/deploy/06_SetupCollateral.s.sol +++ b/script/deploy/06_SetupCollateral.s.sol @@ -21,7 +21,7 @@ contract SetupCollateralScript is DeployScript { uint256 dust = config.readUint(".dust"); function run() public broadcast { - _validateInterface(ionPool); + _validateInterfaceIonPool(ionPool); _validateInterface(IERC20(ilkAddress)); _validateInterface(spotOracle); diff --git a/script/deploy/07_DeployGemJoin.s.sol b/script/deploy/07_DeployGemJoin.s.sol index 428e0bf8..c8ee3a8f 100644 --- a/script/deploy/07_DeployGemJoin.s.sol +++ b/script/deploy/07_DeployGemJoin.s.sol @@ -20,7 +20,7 @@ contract DeployGemJoinScript is DeployScript { function run() public broadcast returns (GemJoin gemJoin) { IERC20 ilkERC20 = IERC20(ilkAddress); - _validateInterface(ionPool); + _validateInterfaceIonPool(ionPool); _validateInterface(ilkERC20); if (deployCreate2) { diff --git a/script/deploy/08_DeployHandlers.s.sol b/script/deploy/08_DeployHandlers.s.sol index b8b48154..4597528c 100644 --- a/script/deploy/08_DeployHandlers.s.sol +++ b/script/deploy/08_DeployHandlers.s.sol @@ -24,9 +24,9 @@ contract DeployHandlersScript is DeployScript { Whitelist whitelist = Whitelist(config.readAddress(".whitelist")); function run() public broadcast returns (IonHandlerBase handler) { - _validateInterface(ionPool); _validateInterface(gemJoin); _validateInterface(whitelist); + _validateInterfaceIonPool(ionPool); if (deployCreate2) { handler = new RswEthHandler{ salt: DEFAULT_SALT }( diff --git a/script/deploy/09_DeployLiquidation.s.sol b/script/deploy/09_DeployLiquidation.s.sol index c76edfba..a416b5ea 100644 --- a/script/deploy/09_DeployLiquidation.s.sol +++ b/script/deploy/09_DeployLiquidation.s.sol @@ -2,9 +2,9 @@ pragma solidity 0.8.21; import { DeployScript } from "../Deploy.s.sol"; +import { IonPool } from "./../../src/IonPool.sol"; import { Liquidation } from "../../src/Liquidation.sol"; import { WadRayMath, RAY } from "../../src/libraries/math/WadRayMath.sol"; -import { IonPool } from "../../src/IonPool.sol"; import { CREATEX } from "../../src/Constants.sol"; import { ReserveOracle } from "../../src/oracles/reserve/ReserveOracle.sol"; @@ -32,7 +32,7 @@ contract DeployLiquidationScript is DeployScript { bytes32 salt = config.readBytes32(".salt"); function run() public broadcast returns (Liquidation liquidation) { - _validateInterface(ionPool); + _validateInterfaceIonPool(ionPool); _validateInterface(ReserveOracle(reserveOracle)); require(targetHealth >= RAY, "target health lower"); @@ -48,7 +48,7 @@ contract DeployLiquidationScript is DeployScript { // NOTE: Liquidation contract reads the ilkCount() of the IonPool which // should always be 1. - require(ionPool.ilkCount() == ILK_COUNT, "ionPool ilk count"); + // require(lens.ilkCount(ionPool) == ILK_COUNT, "ionPool ilk count"); bytes memory initCode = type(Liquidation).creationCode; diff --git a/script/deploy/10_AdminTransfer.s.sol b/script/deploy/10_AdminTransfer.s.sol index fa392af7..105a2e20 100644 --- a/script/deploy/10_AdminTransfer.s.sol +++ b/script/deploy/10_AdminTransfer.s.sol @@ -33,9 +33,9 @@ contract AdminTransferScript is DeployScript { function run() public broadcast { require(address(protocol) != address(0), "protocol address"); - _validateInterface(ionPool); _validateInterface(yieldOracle); _validateInterface(whitelist); + _validateInterfaceIonPool(ionPool); require(proxyAdmin.owner() == initialDefaultAdmin, "proxy admin owner"); diff --git a/slither.db.json b/slither.db.json index 7f7e34c2..4f72ac90 100644 --- a/slither.db.json +++ b/slither.db.json @@ -1 +1 @@ -[{"elements": [{"type": "function", "name": "constructor", "source_mapping": {"start": 1093, "length": 441, "filename_relative": "src/YieldOraclePendle.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/YieldOraclePendle.sol", "filename_short": "src/YieldOraclePendle.sol", "is_dependency": false, "lines": [35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "YieldOraclePendle", "source_mapping": {"start": 624, "length": 1786, "filename_relative": "src/YieldOraclePendle.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/YieldOraclePendle.sol", "filename_short": "src/YieldOraclePendle.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70], "starting_column": 1, "ending_column": 2}}, "signature": "constructor(IPMarketV3,uint32,uint256)"}}, {"type": "node", "name": "(observationCardinalityNext) = _market._storage()", "source_mapping": {"start": 1180, "length": 62, "filename_relative": "src/YieldOraclePendle.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/YieldOraclePendle.sol", "filename_short": "src/YieldOraclePendle.sol", "is_dependency": false, "lines": [36], "starting_column": 9, "ending_column": 71}, "type_specific_fields": {"parent": {"type": "function", "name": "constructor", "source_mapping": {"start": 1093, "length": 441, "filename_relative": "src/YieldOraclePendle.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/YieldOraclePendle.sol", "filename_short": "src/YieldOraclePendle.sol", "is_dependency": false, "lines": [35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "YieldOraclePendle", "source_mapping": {"start": 624, "length": 1786, "filename_relative": "src/YieldOraclePendle.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/YieldOraclePendle.sol", "filename_short": "src/YieldOraclePendle.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70], "starting_column": 1, "ending_column": 2}}, "signature": "constructor(IPMarketV3,uint32,uint256)"}}}}], "description": "YieldOraclePendle.constructor(IPMarketV3,uint32,uint256) (src/YieldOraclePendle.sol#35-45) ignores return value by (observationCardinalityNext) = _market._storage() (src/YieldOraclePendle.sol#36)\n", "markdown": "[YieldOraclePendle.constructor(IPMarketV3,uint32,uint256)](src/YieldOraclePendle.sol#L35-L45) ignores return value by [(observationCardinalityNext) = _market._storage()](src/YieldOraclePendle.sol#L36)\n", "first_markdown_element": "src/YieldOraclePendle.sol#L35-L45", "id": "4d69cd6bd4dcd29b44c9b3cfd3a16accfbd17963ae4a5ef9819260f35f895a6b", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "constructor", "source_mapping": {"start": 3515, "length": 1329, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Liquidation", "source_mapping": {"start": 1568, "length": 13159, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327], "starting_column": 1, "ending_column": 2}}, "signature": "constructor(address,address,address,uint256,uint256,uint256,uint256)"}}, {"type": "node", "name": "underlying.approve(address(ionPool_),type()(uint256).max)", "source_mapping": {"start": 4598, "length": 56, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [112], "starting_column": 9, "ending_column": 65}, "type_specific_fields": {"parent": {"type": "function", "name": "constructor", "source_mapping": {"start": 3515, "length": 1329, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Liquidation", "source_mapping": {"start": 1568, "length": 13159, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327], "starting_column": 1, "ending_column": 2}}, "signature": "constructor(address,address,address,uint256,uint256,uint256,uint256)"}}}}], "description": "Liquidation.constructor(address,address,address,uint256,uint256,uint256,uint256) (src/Liquidation.sol#81-118) ignores return value by underlying.approve(address(ionPool_),type()(uint256).max) (src/Liquidation.sol#112)\n", "markdown": "[Liquidation.constructor(address,address,address,uint256,uint256,uint256,uint256)](src/Liquidation.sol#L81-L118) ignores return value by [underlying.approve(address(ionPool_),type()(uint256).max)](src/Liquidation.sol#L112)\n", "first_markdown_element": "src/Liquidation.sol#L81-L118", "id": "b08aa534552ae8f484a961e182cce93a4818bcc79a7321400c7a23e0e11c6474", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 42965, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43178, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "switch_expr_43126_77_22__rpow_asm_0 == 0", "source_mapping": {"start": 43151, "length": 17, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1175], "starting_column": 17, "ending_column": 34}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42965, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43178, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1170-1199) uses a dangerous strict equality:\n\t- switch_expr_43126_77_22__rpow_asm_0 == 0 (src/IonPool.sol#1175)\n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1170-L1199) uses a dangerous strict equality:\n\t- [switch_expr_43126_77_22__rpow_asm_0 == 0](src/IonPool.sol#L1175)\n", "first_markdown_element": "src/IonPool.sol#L1170-L1199", "id": "a9eecfb5591160e2711a9efafbe4dd1b66ea78fb3ef69f794d4017a81f885c90", "check": "incorrect-equality", "impact": "Medium", "confidence": "High"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 42965, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43178, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "switch_expr_43256_85_22__rpow_asm_0 == 0", "source_mapping": {"start": 43289, "length": 17, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1180], "starting_column": 17, "ending_column": 34}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42965, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43178, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1170-1199) uses a dangerous strict equality:\n\t- switch_expr_43256_85_22__rpow_asm_0 == 0 (src/IonPool.sol#1180)\n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1170-L1199) uses a dangerous strict equality:\n\t- [switch_expr_43256_85_22__rpow_asm_0 == 0](src/IonPool.sol#L1180)\n", "first_markdown_element": "src/IonPool.sol#L1170-L1199", "id": "89241166989564bd79148c9ae0ed92000760df5906b0f7a29e30ef26a700ee71", "check": "incorrect-equality", "impact": "Medium", "confidence": "High"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 42965, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43178, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "switch_expr_43256_85_22__rpow_asm_0 = n % 2", "source_mapping": {"start": 43263, "length": 9, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1179], "starting_column": 24, "ending_column": 33}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42965, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43178, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1170-1199) uses a weak PRNG: \"switch_expr_43256_85_22__rpow_asm_0 = n % 2 (src/IonPool.sol#1179)\" \n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1170-L1199) uses a weak PRNG: \"[switch_expr_43256_85_22__rpow_asm_0 = n % 2](src/IonPool.sol#L1179)\" \n", "first_markdown_element": "src/IonPool.sol#L1170-L1199", "id": "9b2881e796d5f2c5c16db582de2b116fb1ae42141949f0a718161a5171992411", "check": "weak-prng", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "constructor", "source_mapping": {"start": 3564, "length": 2307, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Liquidation", "source_mapping": {"start": 1568, "length": 14186, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354], "starting_column": 1, "ending_column": 2}}, "signature": "constructor(address,address,address[],uint256[],uint256,uint256,uint256[])"}}, {"type": "node", "name": "underlying.approve(address(ionPool_),type()(uint256).max)", "source_mapping": {"start": 5617, "length": 56, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [139], "starting_column": 9, "ending_column": 65}, "type_specific_fields": {"parent": {"type": "function", "name": "constructor", "source_mapping": {"start": 3564, "length": 2307, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Liquidation", "source_mapping": {"start": 1568, "length": 14186, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354], "starting_column": 1, "ending_column": 2}}, "signature": "constructor(address,address,address[],uint256[],uint256,uint256,uint256[])"}}}}], "description": "Liquidation.constructor(address,address,address[],uint256[],uint256,uint256,uint256[]) (src/Liquidation.sol#82-145) ignores return value by underlying.approve(address(ionPool_),type()(uint256).max) (src/Liquidation.sol#139)\n", "markdown": "[Liquidation.constructor(address,address,address[],uint256[],uint256,uint256,uint256[])](src/Liquidation.sol#L82-L145) ignores return value by [underlying.approve(address(ionPool_),type()(uint256).max)](src/Liquidation.sol#L139)\n", "first_markdown_element": "src/Liquidation.sol#L82-L145", "id": "0ead649660500376fb6ebf97e74126d79006fd0374d9047c453cb9038d23ab9e", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 42966, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "switch_expr_43257_85_22__rpow_asm_0 = n % 2", "source_mapping": {"start": 43264, "length": 9, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1179], "starting_column": 24, "ending_column": 33}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42966, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1170-1199) uses a weak PRNG: \"switch_expr_43257_85_22__rpow_asm_0 = n % 2 (src/IonPool.sol#1179)\" \n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1170-L1199) uses a weak PRNG: \"[switch_expr_43257_85_22__rpow_asm_0 = n % 2](src/IonPool.sol#L1179)\" \n", "first_markdown_element": "src/IonPool.sol#L1170-L1199", "id": "2e6c4206ae3cf0bb20483db6726d6d4e489026d172b834d3d7a50be5ac083489", "check": "weak-prng", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 42966, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "n % 2", "source_mapping": {"start": 43732, "length": 332, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1189, 1190, 1191, 1192, 1193, 1194, 1195], "starting_column": 21, "ending_column": 22}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42966, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1170-1199) uses a weak PRNG: \"n % 2 (src/IonPool.sol#1189-1195)\" \n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1170-L1199) uses a weak PRNG: \"[n % 2](src/IonPool.sol#L1189-L1195)\" \n", "first_markdown_element": "src/IonPool.sol#L1170-L1199", "id": "1df50148902ccbaf5ad824ededb5cb08a94439c8ac8e8344705fc2c1d6f9670a", "check": "weak-prng", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 42966, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "x = xxRound__rpow_asm_0 / b", "source_mapping": {"start": 43691, "length": 20, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1188], "starting_column": 21, "ending_column": 41}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42966, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}, {"type": "node", "name": "zx__rpow_asm_0 = z * x", "source_mapping": {"start": 43771, "length": 19, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1190], "starting_column": 25, "ending_column": 44}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42966, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1170-1199) performs a multiplication on the result of a division:\n\t- x = xxRound__rpow_asm_0 / b (src/IonPool.sol#1188)\n\t- zx__rpow_asm_0 = z * x (src/IonPool.sol#1190)\n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1170-L1199) performs a multiplication on the result of a division:\n\t- [x = xxRound__rpow_asm_0 / b](src/IonPool.sol#L1188)\n\t- [zx__rpow_asm_0 = z * x](src/IonPool.sol#L1190)\n", "first_markdown_element": "src/IonPool.sol#L1170-L1199", "id": "e13a06bedaf78263e13bf3c3d6bfb900a7b788cd2b97b865248df2c76304176d", "check": "divide-before-multiply", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "_calculateRewardAndDebtDistributionForIlk", "source_mapping": {"start": 17645, "length": 2705, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_calculateRewardAndDebtDistributionForIlk(uint8,uint256)"}}, {"type": "node", "name": "_totalNormalizedDebt == 0 || block.timestamp == ilk.lastRateUpdate", "source_mapping": {"start": 18193, "length": 66, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [481], "starting_column": 13, "ending_column": 79}, "type_specific_fields": {"parent": {"type": "function", "name": "_calculateRewardAndDebtDistributionForIlk", "source_mapping": {"start": 17645, "length": 2705, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_calculateRewardAndDebtDistributionForIlk(uint8,uint256)"}}}}], "description": "IonPool._calculateRewardAndDebtDistributionForIlk(uint8,uint256) (src/IonPool.sol#463-524) uses a dangerous strict equality:\n\t- _totalNormalizedDebt == 0 || block.timestamp == ilk.lastRateUpdate (src/IonPool.sol#481)\n", "markdown": "[IonPool._calculateRewardAndDebtDistributionForIlk(uint8,uint256)](src/IonPool.sol#L463-L524) uses a dangerous strict equality:\n\t- [_totalNormalizedDebt == 0 || block.timestamp == ilk.lastRateUpdate](src/IonPool.sol#L481)\n", "first_markdown_element": "src/IonPool.sol#L463-L524", "id": "a9e34a881524f6c4bebc0c7b632e3742b780e7c7b7f11c4569c4a75473302590", "check": "incorrect-equality", "impact": "Medium", "confidence": "High"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 42966, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "switch_expr_43127_77_22__rpow_asm_0 == 0", "source_mapping": {"start": 43152, "length": 17, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1175], "starting_column": 17, "ending_column": 34}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42966, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1170-1199) uses a dangerous strict equality:\n\t- switch_expr_43127_77_22__rpow_asm_0 == 0 (src/IonPool.sol#1175)\n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1170-L1199) uses a dangerous strict equality:\n\t- [switch_expr_43127_77_22__rpow_asm_0 == 0](src/IonPool.sol#L1175)\n", "first_markdown_element": "src/IonPool.sol#L1170-L1199", "id": "0aeef70ed3186a6259f90fa5a7512ff33187086811f5125dd65ce607ca18c345", "check": "incorrect-equality", "impact": "Medium", "confidence": "High"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 42966, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "switch_expr_43257_85_22__rpow_asm_0 == 0", "source_mapping": {"start": 43290, "length": 17, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1180], "starting_column": 17, "ending_column": 34}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42966, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1170-1199) uses a dangerous strict equality:\n\t- switch_expr_43257_85_22__rpow_asm_0 == 0 (src/IonPool.sol#1180)\n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1170-L1199) uses a dangerous strict equality:\n\t- [switch_expr_43257_85_22__rpow_asm_0 == 0](src/IonPool.sol#L1180)\n", "first_markdown_element": "src/IonPool.sol#L1170-L1199", "id": "a8d667bf9d11a3f287e2cd3d8f71e8f9a43908002e8435c8d4ac4310647487e2", "check": "incorrect-equality", "impact": "Medium", "confidence": "High"}, {"elements": [{"type": "function", "name": "onlyWhitelistedBorrowers", "source_mapping": {"start": 4773, "length": 241, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [107, 108, 109, 110, 111], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "onlyWhitelistedBorrowers(uint8,address,bytes32[])"}}, {"type": "node", "name": "$.whitelist.isWhitelistedBorrower(ilkIndex,msg.sender,user,proof)", "source_mapping": {"start": 4928, "length": 68, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [109], "starting_column": 9, "ending_column": 77}, "type_specific_fields": {"parent": {"type": "function", "name": "onlyWhitelistedBorrowers", "source_mapping": {"start": 4773, "length": 241, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [107, 108, 109, 110, 111], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "onlyWhitelistedBorrowers(uint8,address,bytes32[])"}}}}], "description": "IonPool.onlyWhitelistedBorrowers(uint8,address,bytes32[]) (src/IonPool.sol#107-111) ignores return value by $.whitelist.isWhitelistedBorrower(ilkIndex,msg.sender,user,proof) (src/IonPool.sol#109)\n", "markdown": "[IonPool.onlyWhitelistedBorrowers(uint8,address,bytes32[])](src/IonPool.sol#L107-L111) ignores return value by [$.whitelist.isWhitelistedBorrower(ilkIndex,msg.sender,user,proof)](src/IonPool.sol#L109)\n", "first_markdown_element": "src/IonPool.sol#L107-L111", "id": "761b88b057bfa6fa8dd56ab567df85eef4db22c074bfb3ddd35fbcd3abdb574f", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "onlyWhitelistedLenders", "source_mapping": {"start": 5020, "length": 211, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [113, 114, 115, 116, 117], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "onlyWhitelistedLenders(address,bytes32[])"}}, {"type": "node", "name": "$.whitelist.isWhitelistedLender(msg.sender,user,proof)", "source_mapping": {"start": 5157, "length": 56, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [115], "starting_column": 9, "ending_column": 65}, "type_specific_fields": {"parent": {"type": "function", "name": "onlyWhitelistedLenders", "source_mapping": {"start": 5020, "length": 211, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [113, 114, 115, 116, 117], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "onlyWhitelistedLenders(address,bytes32[])"}}}}], "description": "IonPool.onlyWhitelistedLenders(address,bytes32[]) (src/IonPool.sol#113-117) ignores return value by $.whitelist.isWhitelistedLender(msg.sender,user,proof) (src/IonPool.sol#115)\n", "markdown": "[IonPool.onlyWhitelistedLenders(address,bytes32[])](src/IonPool.sol#L113-L117) ignores return value by [$.whitelist.isWhitelistedLender(msg.sender,user,proof)](src/IonPool.sol#L115)\n", "first_markdown_element": "src/IonPool.sol#L113-L117", "id": "cca4c7341bcdb3e1a8568a94b7d33e336b54ce4ac14741670c3b3ba40fb3aada", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "variable", "name": "liquidateArgs", "source_mapping": {"start": 11678, "length": 34, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [283], "starting_column": 9, "ending_column": 43}, "type_specific_fields": {"parent": {"type": "function", "name": "liquidate", "source_mapping": {"start": 11500, "length": 5266, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Liquidation", "source_mapping": {"start": 1568, "length": 15200, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376], "starting_column": 1, "ending_column": 2}}, "signature": "liquidate(uint8,address,address)"}}}}], "description": "Liquidation.liquidate(uint8,address,address).liquidateArgs (src/Liquidation.sol#283) is a local variable never initialized\n", "markdown": "[Liquidation.liquidate(uint8,address,address).liquidateArgs](src/Liquidation.sol#L283) is a local variable never initialized\n", "first_markdown_element": "src/Liquidation.sol#L283", "id": "ffe1155d0802748feccc7d9afda276f94c8dee2313454ab721a09aab225e6490", "check": "uninitialized-local", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "constructor", "source_mapping": {"start": 3880, "length": 2616, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Liquidation", "source_mapping": {"start": 1568, "length": 15200, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376], "starting_column": 1, "ending_column": 2}}, "signature": "constructor(address,address,address[],uint256[],uint256,uint256,uint256[])"}}, {"type": "node", "name": "underlying.approve(address(ionPool_),type()(uint256).max)", "source_mapping": {"start": 6022, "length": 56, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [148], "starting_column": 9, "ending_column": 65}, "type_specific_fields": {"parent": {"type": "function", "name": "constructor", "source_mapping": {"start": 3880, "length": 2616, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Liquidation", "source_mapping": {"start": 1568, "length": 15200, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376], "starting_column": 1, "ending_column": 2}}, "signature": "constructor(address,address,address[],uint256[],uint256,uint256,uint256[])"}}}}], "description": "Liquidation.constructor(address,address,address[],uint256[],uint256,uint256,uint256[]) (src/Liquidation.sol#88-158) ignores return value by underlying.approve(address(ionPool_),type()(uint256).max) (src/Liquidation.sol#148)\n", "markdown": "[Liquidation.constructor(address,address,address[],uint256[],uint256,uint256,uint256[])](src/Liquidation.sol#L88-L158) ignores return value by [underlying.approve(address(ionPool_),type()(uint256).max)](src/Liquidation.sol#L148)\n", "first_markdown_element": "src/Liquidation.sol#L88-L158", "id": "a84764301472d096a8c6d7d6d1dea9bd6ebf4a32f6feda1dc7d28f73dbffc092", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "variable", "name": "newApy", "source_mapping": {"start": 7029, "length": 13, "filename_relative": "src/YieldOracle.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/YieldOracle.sol", "filename_short": "src/YieldOracle.sol", "is_dependency": false, "lines": [173], "starting_column": 13, "ending_column": 26}, "type_specific_fields": {"parent": {"type": "function", "name": "_updateAll", "source_mapping": {"start": 5871, "length": 2256, "filename_relative": "src/YieldOracle.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/YieldOracle.sol", "filename_short": "src/YieldOracle.sol", "is_dependency": false, "lines": [152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "YieldOracle", "source_mapping": {"start": 3047, "length": 5881, "filename_relative": "src/YieldOracle.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/YieldOracle.sol", "filename_short": "src/YieldOracle.sol", "is_dependency": false, "lines": [57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224], "starting_column": 1, "ending_column": 2}}, "signature": "_updateAll()"}}}}], "description": "YieldOracle._updateAll().newApy (src/YieldOracle.sol#173) is a local variable never initialized\n", "markdown": "[YieldOracle._updateAll().newApy](src/YieldOracle.sol#L173) is a local variable never initialized\n", "first_markdown_element": "src/YieldOracle.sol#L173", "id": "7d319877a770571b86cab95fbe692df49358b94fbec30adffb598ee1aa902b90", "check": "uninitialized-local", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "updateAll", "source_mapping": {"start": 5437, "length": 116, "filename_relative": "src/YieldOracle.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/YieldOracle.sol", "filename_short": "src/YieldOracle.sol", "is_dependency": false, "lines": [138, 139, 140, 141], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "YieldOracle", "source_mapping": {"start": 3047, "length": 5881, "filename_relative": "src/YieldOracle.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/YieldOracle.sol", "filename_short": "src/YieldOracle.sol", "is_dependency": false, "lines": [57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224], "starting_column": 1, "ending_column": 2}}, "signature": "updateAll()"}}, {"type": "node", "name": "ionPool.accrueInterest()", "source_mapping": {"start": 5500, "length": 24, "filename_relative": "src/YieldOracle.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/YieldOracle.sol", "filename_short": "src/YieldOracle.sol", "is_dependency": false, "lines": [139], "starting_column": 32, "ending_column": 56}, "type_specific_fields": {"parent": {"type": "function", "name": "updateAll", "source_mapping": {"start": 5437, "length": 116, "filename_relative": "src/YieldOracle.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/YieldOracle.sol", "filename_short": "src/YieldOracle.sol", "is_dependency": false, "lines": [138, 139, 140, 141], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "YieldOracle", "source_mapping": {"start": 3047, "length": 5881, "filename_relative": "src/YieldOracle.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/YieldOracle.sol", "filename_short": "src/YieldOracle.sol", "is_dependency": false, "lines": [57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224], "starting_column": 1, "ending_column": 2}}, "signature": "updateAll()"}}}}], "description": "YieldOracle.updateAll() (src/YieldOracle.sol#138-141) ignores return value by ionPool.accrueInterest() (src/YieldOracle.sol#139)\n", "markdown": "[YieldOracle.updateAll()](src/YieldOracle.sol#L138-L141) ignores return value by [ionPool.accrueInterest()](src/YieldOracle.sol#L139)\n", "first_markdown_element": "src/YieldOracle.sol#L138-L141", "id": "986198a2f39a095fc081f4d8f67285aea44be178e4aca0f2d3eb45de0d5a86bc", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 42470, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "n % 2", "source_mapping": {"start": 43236, "length": 332, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1181, 1182, 1183, 1184, 1185, 1186, 1187], "starting_column": 21, "ending_column": 22}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42470, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1162-1191) uses a weak PRNG: \"n % 2 (src/IonPool.sol#1181-1187)\" \n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1162-L1191) uses a weak PRNG: \"[n % 2](src/IonPool.sol#L1181-L1187)\" \n", "first_markdown_element": "src/IonPool.sol#L1162-L1191", "id": "b99a435ac73cbca621d51aa00210c242607d5ec5b8902caa170e892c50b1231d", "check": "weak-prng", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 42470, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "switch_expr_42761_85_22__rpow_asm_0 = n % 2", "source_mapping": {"start": 42768, "length": 9, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1171], "starting_column": 24, "ending_column": 33}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42470, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1162-1191) uses a weak PRNG: \"switch_expr_42761_85_22__rpow_asm_0 = n % 2 (src/IonPool.sol#1171)\" \n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1162-L1191) uses a weak PRNG: \"[switch_expr_42761_85_22__rpow_asm_0 = n % 2](src/IonPool.sol#L1171)\" \n", "first_markdown_element": "src/IonPool.sol#L1162-L1191", "id": "1ede5f71fed7a5bbccce2844dd49b2414703f14a521a65eaae6d1571b8628612", "check": "weak-prng", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 42470, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "x = xxRound__rpow_asm_0 / b", "source_mapping": {"start": 43195, "length": 20, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1180], "starting_column": 21, "ending_column": 41}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42470, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}, {"type": "node", "name": "zx__rpow_asm_0 = z * x", "source_mapping": {"start": 43275, "length": 19, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1182], "starting_column": 25, "ending_column": 44}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42470, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1162-1191) performs a multiplication on the result of a division:\n\t- x = xxRound__rpow_asm_0 / b (src/IonPool.sol#1180)\n\t- zx__rpow_asm_0 = z * x (src/IonPool.sol#1182)\n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1162-L1191) performs a multiplication on the result of a division:\n\t- [x = xxRound__rpow_asm_0 / b](src/IonPool.sol#L1180)\n\t- [zx__rpow_asm_0 = z * x](src/IonPool.sol#L1182)\n", "first_markdown_element": "src/IonPool.sol#L1162-L1191", "id": "61fb6f963add510ca4bd5eca10bd92a6cfd1c96b8f889e0fb493c0da9df689c7", "check": "divide-before-multiply", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "_calculateRewardAndDebtDistributionForIlk", "source_mapping": {"start": 17163, "length": 2705, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_calculateRewardAndDebtDistributionForIlk(uint8,uint256)"}}, {"type": "node", "name": "_totalNormalizedDebt == 0 || block.timestamp == ilk.lastRateUpdate", "source_mapping": {"start": 17711, "length": 66, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [473], "starting_column": 13, "ending_column": 79}, "type_specific_fields": {"parent": {"type": "function", "name": "_calculateRewardAndDebtDistributionForIlk", "source_mapping": {"start": 17163, "length": 2705, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_calculateRewardAndDebtDistributionForIlk(uint8,uint256)"}}}}], "description": "IonPool._calculateRewardAndDebtDistributionForIlk(uint8,uint256) (src/IonPool.sol#455-516) uses a dangerous strict equality:\n\t- _totalNormalizedDebt == 0 || block.timestamp == ilk.lastRateUpdate (src/IonPool.sol#473)\n", "markdown": "[IonPool._calculateRewardAndDebtDistributionForIlk(uint8,uint256)](src/IonPool.sol#L455-L516) uses a dangerous strict equality:\n\t- [_totalNormalizedDebt == 0 || block.timestamp == ilk.lastRateUpdate](src/IonPool.sol#L473)\n", "first_markdown_element": "src/IonPool.sol#L455-L516", "id": "2937d1c975b61df063ba0217fa75862e55e8e9bfaffa9ae912f496914e924270", "check": "incorrect-equality", "impact": "Medium", "confidence": "High"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 42470, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "switch_expr_42631_77_22__rpow_asm_0 == 0", "source_mapping": {"start": 42656, "length": 17, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1167], "starting_column": 17, "ending_column": 34}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42470, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1162-1191) uses a dangerous strict equality:\n\t- switch_expr_42631_77_22__rpow_asm_0 == 0 (src/IonPool.sol#1167)\n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1162-L1191) uses a dangerous strict equality:\n\t- [switch_expr_42631_77_22__rpow_asm_0 == 0](src/IonPool.sol#L1167)\n", "first_markdown_element": "src/IonPool.sol#L1162-L1191", "id": "4ffcdd084cc7f8264895d8c6b78c5e24203f215a35068f6502ed627e436e4e69", "check": "incorrect-equality", "impact": "Medium", "confidence": "High"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 42470, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "switch_expr_42761_85_22__rpow_asm_0 == 0", "source_mapping": {"start": 42794, "length": 17, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1172], "starting_column": 17, "ending_column": 34}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42470, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1162-1191) uses a dangerous strict equality:\n\t- switch_expr_42761_85_22__rpow_asm_0 == 0 (src/IonPool.sol#1172)\n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1162-L1191) uses a dangerous strict equality:\n\t- [switch_expr_42761_85_22__rpow_asm_0 == 0](src/IonPool.sol#L1172)\n", "first_markdown_element": "src/IonPool.sol#L1162-L1191", "id": "6101a9579050ebf7d5fb9a6c0f35c6e4358fe2c7037d454d08570b3303990f4b", "check": "incorrect-equality", "impact": "Medium", "confidence": "High"}, {"elements": [{"type": "variable", "name": "newIlk", "source_mapping": {"start": 8804, "length": 17, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [213], "starting_column": 9, "ending_column": 26}, "type_specific_fields": {"parent": {"type": "function", "name": "initializeIlk", "source_mapping": {"start": 8198, "length": 869, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "initializeIlk(address)"}}}}], "description": "IonPool.initializeIlk(address).newIlk (src/IonPool.sol#213) is a local variable never initialized\n", "markdown": "[IonPool.initializeIlk(address).newIlk](src/IonPool.sol#L213) is a local variable never initialized\n", "first_markdown_element": "src/IonPool.sol#L213", "id": "6a23cce259d35b88a8d40e057d4b227447146af50568c2e5ea0c601f29707288", "check": "uninitialized-local", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "variable", "name": "totalTreasuryMintAmount", "source_mapping": {"start": 13946, "length": 31, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [362], "starting_column": 9, "ending_column": 40}, "type_specific_fields": {"parent": {"type": "function", "name": "_accrueInterest", "source_mapping": {"start": 13710, "length": 1389, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_accrueInterest()"}}}}], "description": "IonPool._accrueInterest().totalTreasuryMintAmount (src/IonPool.sol#362) is a local variable never initialized\n", "markdown": "[IonPool._accrueInterest().totalTreasuryMintAmount](src/IonPool.sol#L362) is a local variable never initialized\n", "first_markdown_element": "src/IonPool.sol#L362", "id": "c24a80daa1b2e5cbc9699d0278ab6c73c06927b9e005af4828303cc1e05d5db6", "check": "uninitialized-local", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "variable", "name": "totalSupplyFactorIncrease", "source_mapping": {"start": 13903, "length": 33, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [361], "starting_column": 9, "ending_column": 42}, "type_specific_fields": {"parent": {"type": "function", "name": "_accrueInterest", "source_mapping": {"start": 13710, "length": 1389, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_accrueInterest()"}}}}], "description": "IonPool._accrueInterest().totalSupplyFactorIncrease (src/IonPool.sol#361) is a local variable never initialized\n", "markdown": "[IonPool._accrueInterest().totalSupplyFactorIncrease](src/IonPool.sol#L361) is a local variable never initialized\n", "first_markdown_element": "src/IonPool.sol#L361", "id": "4c8b75067942ddef87b9fedfe5592846f62d4a18f7ad6ddb0b27bb76b8c66075", "check": "uninitialized-local", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "variable", "name": "totalDebtIncrease", "source_mapping": {"start": 13987, "length": 25, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [363], "starting_column": 9, "ending_column": 34}, "type_specific_fields": {"parent": {"type": "function", "name": "_accrueInterest", "source_mapping": {"start": 13710, "length": 1389, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_accrueInterest()"}}}}], "description": "IonPool._accrueInterest().totalDebtIncrease (src/IonPool.sol#363) is a local variable never initialized\n", "markdown": "[IonPool._accrueInterest().totalDebtIncrease](src/IonPool.sol#L363) is a local variable never initialized\n", "first_markdown_element": "src/IonPool.sol#L363", "id": "6ee5d8cacb31b86be0c9ebba32774b18e0e729453529abdfb7a0ab120e4db29f", "check": "uninitialized-local", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "onlyWhitelistedBorrowers", "source_mapping": {"start": 4707, "length": 241, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [106, 107, 108, 109, 110], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "onlyWhitelistedBorrowers(uint8,address,bytes32[])"}}, {"type": "node", "name": "$.whitelist.isWhitelistedBorrower(ilkIndex,msg.sender,user,proof)", "source_mapping": {"start": 4862, "length": 68, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [108], "starting_column": 9, "ending_column": 77}, "type_specific_fields": {"parent": {"type": "function", "name": "onlyWhitelistedBorrowers", "source_mapping": {"start": 4707, "length": 241, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [106, 107, 108, 109, 110], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "onlyWhitelistedBorrowers(uint8,address,bytes32[])"}}}}], "description": "IonPool.onlyWhitelistedBorrowers(uint8,address,bytes32[]) (src/IonPool.sol#106-110) ignores return value by $.whitelist.isWhitelistedBorrower(ilkIndex,msg.sender,user,proof) (src/IonPool.sol#108)\n", "markdown": "[IonPool.onlyWhitelistedBorrowers(uint8,address,bytes32[])](src/IonPool.sol#L106-L110) ignores return value by [$.whitelist.isWhitelistedBorrower(ilkIndex,msg.sender,user,proof)](src/IonPool.sol#L108)\n", "first_markdown_element": "src/IonPool.sol#L106-L110", "id": "2f3da301dbb905b7d9a3940bb38b866271e35e6597cb8e4e8d53e380051ec0c9", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "onlyWhitelistedLenders", "source_mapping": {"start": 4954, "length": 211, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [112, 113, 114, 115, 116], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "onlyWhitelistedLenders(address,bytes32[])"}}, {"type": "node", "name": "$.whitelist.isWhitelistedLender(msg.sender,user,proof)", "source_mapping": {"start": 5091, "length": 56, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [114], "starting_column": 9, "ending_column": 65}, "type_specific_fields": {"parent": {"type": "function", "name": "onlyWhitelistedLenders", "source_mapping": {"start": 4954, "length": 211, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [112, 113, 114, 115, 116], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "onlyWhitelistedLenders(address,bytes32[])"}}}}], "description": "IonPool.onlyWhitelistedLenders(address,bytes32[]) (src/IonPool.sol#112-116) ignores return value by $.whitelist.isWhitelistedLender(msg.sender,user,proof) (src/IonPool.sol#114)\n", "markdown": "[IonPool.onlyWhitelistedLenders(address,bytes32[])](src/IonPool.sol#L112-L116) ignores return value by [$.whitelist.isWhitelistedLender(msg.sender,user,proof)](src/IonPool.sol#L114)\n", "first_markdown_element": "src/IonPool.sol#L112-L116", "id": "098fd68edbffd1a0d045df48178321fcfca7b408e65a20783d946e601fcc8bf0", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "variable", "name": "packedConfig_b", "source_mapping": {"start": 10213, "length": 22, "filename_relative": "src/InterestRate.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/InterestRate.sol", "filename_short": "src/InterestRate.sol", "is_dependency": false, "lines": [229], "starting_column": 9, "ending_column": 31}, "type_specific_fields": {"parent": {"type": "function", "name": "_unpackCollateralConfig", "source_mapping": {"start": 9996, "length": 3195, "filename_relative": "src/InterestRate.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/InterestRate.sol", "filename_short": "src/InterestRate.sol", "is_dependency": false, "lines": [225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "InterestRate", "source_mapping": {"start": 4333, "length": 13006, "filename_relative": "src/InterestRate.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/InterestRate.sol", "filename_short": "src/InterestRate.sol", "is_dependency": false, "lines": [91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382], "starting_column": 1, "ending_column": 2}}, "signature": "_unpackCollateralConfig(uint256)"}}}}], "description": "InterestRate._unpackCollateralConfig(uint256).packedConfig_b (src/InterestRate.sol#229) is a local variable never initialized\n", "markdown": "[InterestRate._unpackCollateralConfig(uint256).packedConfig_b](src/InterestRate.sol#L229) is a local variable never initialized\n", "first_markdown_element": "src/InterestRate.sol#L229", "id": "6644dfaf7e5259440f5dd2558ba44e78bd00d7dd570cf261ea41dba41e494ef2", "check": "uninitialized-local", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "variable", "name": "packedConfig_a", "source_mapping": {"start": 10181, "length": 22, "filename_relative": "src/InterestRate.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/InterestRate.sol", "filename_short": "src/InterestRate.sol", "is_dependency": false, "lines": [228], "starting_column": 9, "ending_column": 31}, "type_specific_fields": {"parent": {"type": "function", "name": "_unpackCollateralConfig", "source_mapping": {"start": 9996, "length": 3195, "filename_relative": "src/InterestRate.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/InterestRate.sol", "filename_short": "src/InterestRate.sol", "is_dependency": false, "lines": [225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "InterestRate", "source_mapping": {"start": 4333, "length": 13006, "filename_relative": "src/InterestRate.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/InterestRate.sol", "filename_short": "src/InterestRate.sol", "is_dependency": false, "lines": [91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382], "starting_column": 1, "ending_column": 2}}, "signature": "_unpackCollateralConfig(uint256)"}}}}], "description": "InterestRate._unpackCollateralConfig(uint256).packedConfig_a (src/InterestRate.sol#228) is a local variable never initialized\n", "markdown": "[InterestRate._unpackCollateralConfig(uint256).packedConfig_a](src/InterestRate.sol#L228) is a local variable never initialized\n", "first_markdown_element": "src/InterestRate.sol#L228", "id": "8ca8908a076e96cb1aa7383b5398e6e5d3bcda6d1889be74d6ce61df3804cc72", "check": "uninitialized-local", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "variable", "name": "packedConfig_c", "source_mapping": {"start": 10245, "length": 22, "filename_relative": "src/InterestRate.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/InterestRate.sol", "filename_short": "src/InterestRate.sol", "is_dependency": false, "lines": [230], "starting_column": 9, "ending_column": 31}, "type_specific_fields": {"parent": {"type": "function", "name": "_unpackCollateralConfig", "source_mapping": {"start": 9996, "length": 3195, "filename_relative": "src/InterestRate.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/InterestRate.sol", "filename_short": "src/InterestRate.sol", "is_dependency": false, "lines": [225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "InterestRate", "source_mapping": {"start": 4333, "length": 13006, "filename_relative": "src/InterestRate.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/InterestRate.sol", "filename_short": "src/InterestRate.sol", "is_dependency": false, "lines": [91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382], "starting_column": 1, "ending_column": 2}}, "signature": "_unpackCollateralConfig(uint256)"}}}}], "description": "InterestRate._unpackCollateralConfig(uint256).packedConfig_c (src/InterestRate.sol#230) is a local variable never initialized\n", "markdown": "[InterestRate._unpackCollateralConfig(uint256).packedConfig_c](src/InterestRate.sol#L230) is a local variable never initialized\n", "first_markdown_element": "src/InterestRate.sol#L230", "id": "072ca14da132fc55ac0995765578fdac60d248e6c492239498275b38d901e8a5", "check": "uninitialized-local", "impact": "Medium", "confidence": "Medium"}] \ No newline at end of file +[{"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 38781, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1217, "length": 38997, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "switch_expr_39072_85_27__rpow_asm_0 = n % 2", "source_mapping": {"start": 39079, "length": 9, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1050], "starting_column": 24, "ending_column": 33}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 38781, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1217, "length": 38997, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1041-1070) uses a weak PRNG: \"switch_expr_39072_85_27__rpow_asm_0 = n % 2 (src/IonPool.sol#1050)\" \n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1041-L1070) uses a weak PRNG: \"[switch_expr_39072_85_27__rpow_asm_0 = n % 2](src/IonPool.sol#L1050)\" \n", "first_markdown_element": "src/IonPool.sol#L1041-L1070", "id": "db8f9ea0f8e5ea068416a2807fbebd3df34438c33989d4569661bd01aaf4a838", "check": "weak-prng", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 38781, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1217, "length": 38997, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "n % 2", "source_mapping": {"start": 39547, "length": 332, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1060, 1061, 1062, 1063, 1064, 1065, 1066], "starting_column": 21, "ending_column": 22}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 38781, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1217, "length": 38997, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1041-1070) uses a weak PRNG: \"n % 2 (src/IonPool.sol#1060-1066)\" \n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1041-L1070) uses a weak PRNG: \"[n % 2](src/IonPool.sol#L1060-L1066)\" \n", "first_markdown_element": "src/IonPool.sol#L1041-L1070", "id": "c68dce6189b4ef266f3711d8e463b4aff5bf071df76a892932f7c620a0d8b8d3", "check": "weak-prng", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 38781, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1217, "length": 38997, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "x = xxRound__rpow_asm_0 / b", "source_mapping": {"start": 39506, "length": 20, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1059], "starting_column": 21, "ending_column": 41}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 38781, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1217, "length": 38997, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}, {"type": "node", "name": "zx__rpow_asm_0 = z * x", "source_mapping": {"start": 39586, "length": 19, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1061], "starting_column": 25, "ending_column": 44}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 38781, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1217, "length": 38997, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1041-1070) performs a multiplication on the result of a division:\n\t- x = xxRound__rpow_asm_0 / b (src/IonPool.sol#1059)\n\t- zx__rpow_asm_0 = z * x (src/IonPool.sol#1061)\n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1041-L1070) performs a multiplication on the result of a division:\n\t- [x = xxRound__rpow_asm_0 / b](src/IonPool.sol#L1059)\n\t- [zx__rpow_asm_0 = z * x](src/IonPool.sol#L1061)\n", "first_markdown_element": "src/IonPool.sol#L1041-L1070", "id": "9e6fe8d826b02e475e36f40f49a6574db08f02cbe6722afdf4be6d951b84bfaf", "check": "divide-before-multiply", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "_calculateRewardAndDebtDistributionForIlk", "source_mapping": {"start": 17646, "length": 2886, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1217, "length": 38997, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085], "starting_column": 1, "ending_column": 2}}, "signature": "_calculateRewardAndDebtDistributionForIlk(uint8,uint256)"}}, {"type": "node", "name": "_totalNormalizedDebt == 0 || block.timestamp == ilk.lastRateUpdate || paused()", "source_mapping": {"start": 18366, "length": 78, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [484], "starting_column": 13, "ending_column": 91}, "type_specific_fields": {"parent": {"type": "function", "name": "_calculateRewardAndDebtDistributionForIlk", "source_mapping": {"start": 17646, "length": 2886, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1217, "length": 38997, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085], "starting_column": 1, "ending_column": 2}}, "signature": "_calculateRewardAndDebtDistributionForIlk(uint8,uint256)"}}}}], "description": "IonPool._calculateRewardAndDebtDistributionForIlk(uint8,uint256) (src/IonPool.sol#463-527) uses a dangerous strict equality:\n\t- _totalNormalizedDebt == 0 || block.timestamp == ilk.lastRateUpdate || paused() (src/IonPool.sol#484)\n", "markdown": "[IonPool._calculateRewardAndDebtDistributionForIlk(uint8,uint256)](src/IonPool.sol#L463-L527) uses a dangerous strict equality:\n\t- [_totalNormalizedDebt == 0 || block.timestamp == ilk.lastRateUpdate || paused()](src/IonPool.sol#L484)\n", "first_markdown_element": "src/IonPool.sol#L463-L527", "id": "7ff531fb669e8b2930e49874e387a2c770b1b3ed586abe05211e76e483f3c791", "check": "incorrect-equality", "impact": "Medium", "confidence": "High"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 38781, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1217, "length": 38997, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "switch_expr_38942_77_27__rpow_asm_0 == 0", "source_mapping": {"start": 38967, "length": 17, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1046], "starting_column": 17, "ending_column": 34}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 38781, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1217, "length": 38997, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1041-1070) uses a dangerous strict equality:\n\t- switch_expr_38942_77_27__rpow_asm_0 == 0 (src/IonPool.sol#1046)\n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1041-L1070) uses a dangerous strict equality:\n\t- [switch_expr_38942_77_27__rpow_asm_0 == 0](src/IonPool.sol#L1046)\n", "first_markdown_element": "src/IonPool.sol#L1041-L1070", "id": "8e43519e13d4fd841587d7a18b26d73e75445046527d7672fb8b3bc8b0146bf1", "check": "incorrect-equality", "impact": "Medium", "confidence": "High"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 38781, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1217, "length": 38997, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "switch_expr_39072_85_27__rpow_asm_0 == 0", "source_mapping": {"start": 39105, "length": 17, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1051], "starting_column": 17, "ending_column": 34}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 38781, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1217, "length": 38997, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1041-1070) uses a dangerous strict equality:\n\t- switch_expr_39072_85_27__rpow_asm_0 == 0 (src/IonPool.sol#1051)\n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1041-L1070) uses a dangerous strict equality:\n\t- [switch_expr_39072_85_27__rpow_asm_0 == 0](src/IonPool.sol#L1051)\n", "first_markdown_element": "src/IonPool.sol#L1041-L1070", "id": "1e139320af358400ae60e667440304e0281b8c93171bde1daa1ee8abf0dd619a", "check": "incorrect-equality", "impact": "Medium", "confidence": "High"}, {"elements": [{"type": "function", "name": "onlyWhitelistedBorrowers", "source_mapping": {"start": 4769, "length": 243, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [107, 108, 109, 110, 111], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1217, "length": 38997, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085], "starting_column": 1, "ending_column": 2}}, "signature": "onlyWhitelistedBorrowers(uint8,address,bytes32[])"}}, {"type": "node", "name": "$.whitelist.isWhitelistedBorrower(ilkIndex,_msgSender(),user,proof)", "source_mapping": {"start": 4924, "length": 70, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [109], "starting_column": 9, "ending_column": 79}, "type_specific_fields": {"parent": {"type": "function", "name": "onlyWhitelistedBorrowers", "source_mapping": {"start": 4769, "length": 243, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [107, 108, 109, 110, 111], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1217, "length": 38997, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085], "starting_column": 1, "ending_column": 2}}, "signature": "onlyWhitelistedBorrowers(uint8,address,bytes32[])"}}}}], "description": "IonPool.onlyWhitelistedBorrowers(uint8,address,bytes32[]) (src/IonPool.sol#107-111) ignores return value by $.whitelist.isWhitelistedBorrower(ilkIndex,_msgSender(),user,proof) (src/IonPool.sol#109)\n", "markdown": "[IonPool.onlyWhitelistedBorrowers(uint8,address,bytes32[])](src/IonPool.sol#L107-L111) ignores return value by [$.whitelist.isWhitelistedBorrower(ilkIndex,_msgSender(),user,proof)](src/IonPool.sol#L109)\n", "first_markdown_element": "src/IonPool.sol#L107-L111", "id": "0e45b83be1ca289428e9d767d164ac52610f1ab9556bd10ea855b93c405bf08f", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "onlyWhitelistedLenders", "source_mapping": {"start": 5018, "length": 213, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [113, 114, 115, 116, 117], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1217, "length": 38997, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085], "starting_column": 1, "ending_column": 2}}, "signature": "onlyWhitelistedLenders(address,bytes32[])"}}, {"type": "node", "name": "$.whitelist.isWhitelistedLender(_msgSender(),user,proof)", "source_mapping": {"start": 5155, "length": 58, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [115], "starting_column": 9, "ending_column": 67}, "type_specific_fields": {"parent": {"type": "function", "name": "onlyWhitelistedLenders", "source_mapping": {"start": 5018, "length": 213, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [113, 114, 115, 116, 117], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1217, "length": 38997, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/junkim/Development/projects/ion/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085], "starting_column": 1, "ending_column": 2}}, "signature": "onlyWhitelistedLenders(address,bytes32[])"}}}}], "description": "IonPool.onlyWhitelistedLenders(address,bytes32[]) (src/IonPool.sol#113-117) ignores return value by $.whitelist.isWhitelistedLender(_msgSender(),user,proof) (src/IonPool.sol#115)\n", "markdown": "[IonPool.onlyWhitelistedLenders(address,bytes32[])](src/IonPool.sol#L113-L117) ignores return value by [$.whitelist.isWhitelistedLender(_msgSender(),user,proof)](src/IonPool.sol#L115)\n", "first_markdown_element": "src/IonPool.sol#L113-L117", "id": "58ce547e0d898fe99a64e43b0be381a706206a2927811a072efc282ba0bf28b3", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "constructor", "source_mapping": {"start": 1093, "length": 441, "filename_relative": "src/YieldOraclePendle.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/YieldOraclePendle.sol", "filename_short": "src/YieldOraclePendle.sol", "is_dependency": false, "lines": [35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "YieldOraclePendle", "source_mapping": {"start": 624, "length": 1786, "filename_relative": "src/YieldOraclePendle.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/YieldOraclePendle.sol", "filename_short": "src/YieldOraclePendle.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70], "starting_column": 1, "ending_column": 2}}, "signature": "constructor(IPMarketV3,uint32,uint256)"}}, {"type": "node", "name": "(observationCardinalityNext) = _market._storage()", "source_mapping": {"start": 1180, "length": 62, "filename_relative": "src/YieldOraclePendle.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/YieldOraclePendle.sol", "filename_short": "src/YieldOraclePendle.sol", "is_dependency": false, "lines": [36], "starting_column": 9, "ending_column": 71}, "type_specific_fields": {"parent": {"type": "function", "name": "constructor", "source_mapping": {"start": 1093, "length": 441, "filename_relative": "src/YieldOraclePendle.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/YieldOraclePendle.sol", "filename_short": "src/YieldOraclePendle.sol", "is_dependency": false, "lines": [35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "YieldOraclePendle", "source_mapping": {"start": 624, "length": 1786, "filename_relative": "src/YieldOraclePendle.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/YieldOraclePendle.sol", "filename_short": "src/YieldOraclePendle.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70], "starting_column": 1, "ending_column": 2}}, "signature": "constructor(IPMarketV3,uint32,uint256)"}}}}], "description": "YieldOraclePendle.constructor(IPMarketV3,uint32,uint256) (src/YieldOraclePendle.sol#35-45) ignores return value by (observationCardinalityNext) = _market._storage() (src/YieldOraclePendle.sol#36)\n", "markdown": "[YieldOraclePendle.constructor(IPMarketV3,uint32,uint256)](src/YieldOraclePendle.sol#L35-L45) ignores return value by [(observationCardinalityNext) = _market._storage()](src/YieldOraclePendle.sol#L36)\n", "first_markdown_element": "src/YieldOraclePendle.sol#L35-L45", "id": "4d69cd6bd4dcd29b44c9b3cfd3a16accfbd17963ae4a5ef9819260f35f895a6b", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "constructor", "source_mapping": {"start": 3515, "length": 1329, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Liquidation", "source_mapping": {"start": 1568, "length": 13159, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327], "starting_column": 1, "ending_column": 2}}, "signature": "constructor(address,address,address,uint256,uint256,uint256,uint256)"}}, {"type": "node", "name": "underlying.approve(address(ionPool_),type()(uint256).max)", "source_mapping": {"start": 4598, "length": 56, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [112], "starting_column": 9, "ending_column": 65}, "type_specific_fields": {"parent": {"type": "function", "name": "constructor", "source_mapping": {"start": 3515, "length": 1329, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Liquidation", "source_mapping": {"start": 1568, "length": 13159, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327], "starting_column": 1, "ending_column": 2}}, "signature": "constructor(address,address,address,uint256,uint256,uint256,uint256)"}}}}], "description": "Liquidation.constructor(address,address,address,uint256,uint256,uint256,uint256) (src/Liquidation.sol#81-118) ignores return value by underlying.approve(address(ionPool_),type()(uint256).max) (src/Liquidation.sol#112)\n", "markdown": "[Liquidation.constructor(address,address,address,uint256,uint256,uint256,uint256)](src/Liquidation.sol#L81-L118) ignores return value by [underlying.approve(address(ionPool_),type()(uint256).max)](src/Liquidation.sol#L112)\n", "first_markdown_element": "src/Liquidation.sol#L81-L118", "id": "b08aa534552ae8f484a961e182cce93a4818bcc79a7321400c7a23e0e11c6474", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 42965, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43178, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "switch_expr_43126_77_22__rpow_asm_0 == 0", "source_mapping": {"start": 43151, "length": 17, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1175], "starting_column": 17, "ending_column": 34}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42965, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43178, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1170-1199) uses a dangerous strict equality:\n\t- switch_expr_43126_77_22__rpow_asm_0 == 0 (src/IonPool.sol#1175)\n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1170-L1199) uses a dangerous strict equality:\n\t- [switch_expr_43126_77_22__rpow_asm_0 == 0](src/IonPool.sol#L1175)\n", "first_markdown_element": "src/IonPool.sol#L1170-L1199", "id": "a9eecfb5591160e2711a9efafbe4dd1b66ea78fb3ef69f794d4017a81f885c90", "check": "incorrect-equality", "impact": "Medium", "confidence": "High"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 42965, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43178, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "switch_expr_43256_85_22__rpow_asm_0 == 0", "source_mapping": {"start": 43289, "length": 17, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1180], "starting_column": 17, "ending_column": 34}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42965, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43178, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1170-1199) uses a dangerous strict equality:\n\t- switch_expr_43256_85_22__rpow_asm_0 == 0 (src/IonPool.sol#1180)\n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1170-L1199) uses a dangerous strict equality:\n\t- [switch_expr_43256_85_22__rpow_asm_0 == 0](src/IonPool.sol#L1180)\n", "first_markdown_element": "src/IonPool.sol#L1170-L1199", "id": "89241166989564bd79148c9ae0ed92000760df5906b0f7a29e30ef26a700ee71", "check": "incorrect-equality", "impact": "Medium", "confidence": "High"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 42965, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43178, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "switch_expr_43256_85_22__rpow_asm_0 = n % 2", "source_mapping": {"start": 43263, "length": 9, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1179], "starting_column": 24, "ending_column": 33}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42965, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43178, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1170-1199) uses a weak PRNG: \"switch_expr_43256_85_22__rpow_asm_0 = n % 2 (src/IonPool.sol#1179)\" \n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1170-L1199) uses a weak PRNG: \"[switch_expr_43256_85_22__rpow_asm_0 = n % 2](src/IonPool.sol#L1179)\" \n", "first_markdown_element": "src/IonPool.sol#L1170-L1199", "id": "9b2881e796d5f2c5c16db582de2b116fb1ae42141949f0a718161a5171992411", "check": "weak-prng", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "constructor", "source_mapping": {"start": 3564, "length": 2307, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Liquidation", "source_mapping": {"start": 1568, "length": 14186, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354], "starting_column": 1, "ending_column": 2}}, "signature": "constructor(address,address,address[],uint256[],uint256,uint256,uint256[])"}}, {"type": "node", "name": "underlying.approve(address(ionPool_),type()(uint256).max)", "source_mapping": {"start": 5617, "length": 56, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [139], "starting_column": 9, "ending_column": 65}, "type_specific_fields": {"parent": {"type": "function", "name": "constructor", "source_mapping": {"start": 3564, "length": 2307, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Liquidation", "source_mapping": {"start": 1568, "length": 14186, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354], "starting_column": 1, "ending_column": 2}}, "signature": "constructor(address,address,address[],uint256[],uint256,uint256,uint256[])"}}}}], "description": "Liquidation.constructor(address,address,address[],uint256[],uint256,uint256,uint256[]) (src/Liquidation.sol#82-145) ignores return value by underlying.approve(address(ionPool_),type()(uint256).max) (src/Liquidation.sol#139)\n", "markdown": "[Liquidation.constructor(address,address,address[],uint256[],uint256,uint256,uint256[])](src/Liquidation.sol#L82-L145) ignores return value by [underlying.approve(address(ionPool_),type()(uint256).max)](src/Liquidation.sol#L139)\n", "first_markdown_element": "src/Liquidation.sol#L82-L145", "id": "0ead649660500376fb6ebf97e74126d79006fd0374d9047c453cb9038d23ab9e", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 42966, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "switch_expr_43257_85_22__rpow_asm_0 = n % 2", "source_mapping": {"start": 43264, "length": 9, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1179], "starting_column": 24, "ending_column": 33}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42966, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1170-1199) uses a weak PRNG: \"switch_expr_43257_85_22__rpow_asm_0 = n % 2 (src/IonPool.sol#1179)\" \n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1170-L1199) uses a weak PRNG: \"[switch_expr_43257_85_22__rpow_asm_0 = n % 2](src/IonPool.sol#L1179)\" \n", "first_markdown_element": "src/IonPool.sol#L1170-L1199", "id": "2e6c4206ae3cf0bb20483db6726d6d4e489026d172b834d3d7a50be5ac083489", "check": "weak-prng", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 42966, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "n % 2", "source_mapping": {"start": 43732, "length": 332, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1189, 1190, 1191, 1192, 1193, 1194, 1195], "starting_column": 21, "ending_column": 22}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42966, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1170-1199) uses a weak PRNG: \"n % 2 (src/IonPool.sol#1189-1195)\" \n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1170-L1199) uses a weak PRNG: \"[n % 2](src/IonPool.sol#L1189-L1195)\" \n", "first_markdown_element": "src/IonPool.sol#L1170-L1199", "id": "1df50148902ccbaf5ad824ededb5cb08a94439c8ac8e8344705fc2c1d6f9670a", "check": "weak-prng", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 42966, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "x = xxRound__rpow_asm_0 / b", "source_mapping": {"start": 43691, "length": 20, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1188], "starting_column": 21, "ending_column": 41}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42966, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}, {"type": "node", "name": "zx__rpow_asm_0 = z * x", "source_mapping": {"start": 43771, "length": 19, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1190], "starting_column": 25, "ending_column": 44}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42966, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1170-1199) performs a multiplication on the result of a division:\n\t- x = xxRound__rpow_asm_0 / b (src/IonPool.sol#1188)\n\t- zx__rpow_asm_0 = z * x (src/IonPool.sol#1190)\n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1170-L1199) performs a multiplication on the result of a division:\n\t- [x = xxRound__rpow_asm_0 / b](src/IonPool.sol#L1188)\n\t- [zx__rpow_asm_0 = z * x](src/IonPool.sol#L1190)\n", "first_markdown_element": "src/IonPool.sol#L1170-L1199", "id": "e13a06bedaf78263e13bf3c3d6bfb900a7b788cd2b97b865248df2c76304176d", "check": "divide-before-multiply", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "_calculateRewardAndDebtDistributionForIlk", "source_mapping": {"start": 17645, "length": 2705, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_calculateRewardAndDebtDistributionForIlk(uint8,uint256)"}}, {"type": "node", "name": "_totalNormalizedDebt == 0 || block.timestamp == ilk.lastRateUpdate", "source_mapping": {"start": 18193, "length": 66, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [481], "starting_column": 13, "ending_column": 79}, "type_specific_fields": {"parent": {"type": "function", "name": "_calculateRewardAndDebtDistributionForIlk", "source_mapping": {"start": 17645, "length": 2705, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_calculateRewardAndDebtDistributionForIlk(uint8,uint256)"}}}}], "description": "IonPool._calculateRewardAndDebtDistributionForIlk(uint8,uint256) (src/IonPool.sol#463-524) uses a dangerous strict equality:\n\t- _totalNormalizedDebt == 0 || block.timestamp == ilk.lastRateUpdate (src/IonPool.sol#481)\n", "markdown": "[IonPool._calculateRewardAndDebtDistributionForIlk(uint8,uint256)](src/IonPool.sol#L463-L524) uses a dangerous strict equality:\n\t- [_totalNormalizedDebt == 0 || block.timestamp == ilk.lastRateUpdate](src/IonPool.sol#L481)\n", "first_markdown_element": "src/IonPool.sol#L463-L524", "id": "a9e34a881524f6c4bebc0c7b632e3742b780e7c7b7f11c4569c4a75473302590", "check": "incorrect-equality", "impact": "Medium", "confidence": "High"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 42966, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "switch_expr_43127_77_22__rpow_asm_0 == 0", "source_mapping": {"start": 43152, "length": 17, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1175], "starting_column": 17, "ending_column": 34}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42966, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1170-1199) uses a dangerous strict equality:\n\t- switch_expr_43127_77_22__rpow_asm_0 == 0 (src/IonPool.sol#1175)\n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1170-L1199) uses a dangerous strict equality:\n\t- [switch_expr_43127_77_22__rpow_asm_0 == 0](src/IonPool.sol#L1175)\n", "first_markdown_element": "src/IonPool.sol#L1170-L1199", "id": "0aeef70ed3186a6259f90fa5a7512ff33187086811f5125dd65ce607ca18c345", "check": "incorrect-equality", "impact": "Medium", "confidence": "High"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 42966, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "switch_expr_43257_85_22__rpow_asm_0 == 0", "source_mapping": {"start": 43290, "length": 17, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1180], "starting_column": 17, "ending_column": 34}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42966, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1170-1199) uses a dangerous strict equality:\n\t- switch_expr_43257_85_22__rpow_asm_0 == 0 (src/IonPool.sol#1180)\n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1170-L1199) uses a dangerous strict equality:\n\t- [switch_expr_43257_85_22__rpow_asm_0 == 0](src/IonPool.sol#L1180)\n", "first_markdown_element": "src/IonPool.sol#L1170-L1199", "id": "a8d667bf9d11a3f287e2cd3d8f71e8f9a43908002e8435c8d4ac4310647487e2", "check": "incorrect-equality", "impact": "Medium", "confidence": "High"}, {"elements": [{"type": "function", "name": "onlyWhitelistedBorrowers", "source_mapping": {"start": 4773, "length": 241, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [107, 108, 109, 110, 111], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "onlyWhitelistedBorrowers(uint8,address,bytes32[])"}}, {"type": "node", "name": "$.whitelist.isWhitelistedBorrower(ilkIndex,msg.sender,user,proof)", "source_mapping": {"start": 4928, "length": 68, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [109], "starting_column": 9, "ending_column": 77}, "type_specific_fields": {"parent": {"type": "function", "name": "onlyWhitelistedBorrowers", "source_mapping": {"start": 4773, "length": 241, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [107, 108, 109, 110, 111], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "onlyWhitelistedBorrowers(uint8,address,bytes32[])"}}}}], "description": "IonPool.onlyWhitelistedBorrowers(uint8,address,bytes32[]) (src/IonPool.sol#107-111) ignores return value by $.whitelist.isWhitelistedBorrower(ilkIndex,msg.sender,user,proof) (src/IonPool.sol#109)\n", "markdown": "[IonPool.onlyWhitelistedBorrowers(uint8,address,bytes32[])](src/IonPool.sol#L107-L111) ignores return value by [$.whitelist.isWhitelistedBorrower(ilkIndex,msg.sender,user,proof)](src/IonPool.sol#L109)\n", "first_markdown_element": "src/IonPool.sol#L107-L111", "id": "761b88b057bfa6fa8dd56ab567df85eef4db22c074bfb3ddd35fbcd3abdb574f", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "onlyWhitelistedLenders", "source_mapping": {"start": 5020, "length": 211, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [113, 114, 115, 116, 117], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "onlyWhitelistedLenders(address,bytes32[])"}}, {"type": "node", "name": "$.whitelist.isWhitelistedLender(msg.sender,user,proof)", "source_mapping": {"start": 5157, "length": 56, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [115], "starting_column": 9, "ending_column": 65}, "type_specific_fields": {"parent": {"type": "function", "name": "onlyWhitelistedLenders", "source_mapping": {"start": 5020, "length": 211, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [113, 114, 115, 116, 117], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 43179, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214], "starting_column": 1, "ending_column": 2}}, "signature": "onlyWhitelistedLenders(address,bytes32[])"}}}}], "description": "IonPool.onlyWhitelistedLenders(address,bytes32[]) (src/IonPool.sol#113-117) ignores return value by $.whitelist.isWhitelistedLender(msg.sender,user,proof) (src/IonPool.sol#115)\n", "markdown": "[IonPool.onlyWhitelistedLenders(address,bytes32[])](src/IonPool.sol#L113-L117) ignores return value by [$.whitelist.isWhitelistedLender(msg.sender,user,proof)](src/IonPool.sol#L115)\n", "first_markdown_element": "src/IonPool.sol#L113-L117", "id": "cca4c7341bcdb3e1a8568a94b7d33e336b54ce4ac14741670c3b3ba40fb3aada", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "variable", "name": "liquidateArgs", "source_mapping": {"start": 11678, "length": 34, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [283], "starting_column": 9, "ending_column": 43}, "type_specific_fields": {"parent": {"type": "function", "name": "liquidate", "source_mapping": {"start": 11500, "length": 5266, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Liquidation", "source_mapping": {"start": 1568, "length": 15200, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376], "starting_column": 1, "ending_column": 2}}, "signature": "liquidate(uint8,address,address)"}}}}], "description": "Liquidation.liquidate(uint8,address,address).liquidateArgs (src/Liquidation.sol#283) is a local variable never initialized\n", "markdown": "[Liquidation.liquidate(uint8,address,address).liquidateArgs](src/Liquidation.sol#L283) is a local variable never initialized\n", "first_markdown_element": "src/Liquidation.sol#L283", "id": "ffe1155d0802748feccc7d9afda276f94c8dee2313454ab721a09aab225e6490", "check": "uninitialized-local", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "constructor", "source_mapping": {"start": 3880, "length": 2616, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Liquidation", "source_mapping": {"start": 1568, "length": 15200, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376], "starting_column": 1, "ending_column": 2}}, "signature": "constructor(address,address,address[],uint256[],uint256,uint256,uint256[])"}}, {"type": "node", "name": "underlying.approve(address(ionPool_),type()(uint256).max)", "source_mapping": {"start": 6022, "length": 56, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [148], "starting_column": 9, "ending_column": 65}, "type_specific_fields": {"parent": {"type": "function", "name": "constructor", "source_mapping": {"start": 3880, "length": 2616, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Liquidation", "source_mapping": {"start": 1568, "length": 15200, "filename_relative": "src/Liquidation.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/Liquidation.sol", "filename_short": "src/Liquidation.sol", "is_dependency": false, "lines": [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376], "starting_column": 1, "ending_column": 2}}, "signature": "constructor(address,address,address[],uint256[],uint256,uint256,uint256[])"}}}}], "description": "Liquidation.constructor(address,address,address[],uint256[],uint256,uint256,uint256[]) (src/Liquidation.sol#88-158) ignores return value by underlying.approve(address(ionPool_),type()(uint256).max) (src/Liquidation.sol#148)\n", "markdown": "[Liquidation.constructor(address,address,address[],uint256[],uint256,uint256,uint256[])](src/Liquidation.sol#L88-L158) ignores return value by [underlying.approve(address(ionPool_),type()(uint256).max)](src/Liquidation.sol#L148)\n", "first_markdown_element": "src/Liquidation.sol#L88-L158", "id": "a84764301472d096a8c6d7d6d1dea9bd6ebf4a32f6feda1dc7d28f73dbffc092", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "variable", "name": "newApy", "source_mapping": {"start": 7029, "length": 13, "filename_relative": "src/YieldOracle.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/YieldOracle.sol", "filename_short": "src/YieldOracle.sol", "is_dependency": false, "lines": [173], "starting_column": 13, "ending_column": 26}, "type_specific_fields": {"parent": {"type": "function", "name": "_updateAll", "source_mapping": {"start": 5871, "length": 2256, "filename_relative": "src/YieldOracle.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/YieldOracle.sol", "filename_short": "src/YieldOracle.sol", "is_dependency": false, "lines": [152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "YieldOracle", "source_mapping": {"start": 3047, "length": 5881, "filename_relative": "src/YieldOracle.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/YieldOracle.sol", "filename_short": "src/YieldOracle.sol", "is_dependency": false, "lines": [57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224], "starting_column": 1, "ending_column": 2}}, "signature": "_updateAll()"}}}}], "description": "YieldOracle._updateAll().newApy (src/YieldOracle.sol#173) is a local variable never initialized\n", "markdown": "[YieldOracle._updateAll().newApy](src/YieldOracle.sol#L173) is a local variable never initialized\n", "first_markdown_element": "src/YieldOracle.sol#L173", "id": "7d319877a770571b86cab95fbe692df49358b94fbec30adffb598ee1aa902b90", "check": "uninitialized-local", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "updateAll", "source_mapping": {"start": 5437, "length": 116, "filename_relative": "src/YieldOracle.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/YieldOracle.sol", "filename_short": "src/YieldOracle.sol", "is_dependency": false, "lines": [138, 139, 140, 141], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "YieldOracle", "source_mapping": {"start": 3047, "length": 5881, "filename_relative": "src/YieldOracle.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/YieldOracle.sol", "filename_short": "src/YieldOracle.sol", "is_dependency": false, "lines": [57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224], "starting_column": 1, "ending_column": 2}}, "signature": "updateAll()"}}, {"type": "node", "name": "ionPool.accrueInterest()", "source_mapping": {"start": 5500, "length": 24, "filename_relative": "src/YieldOracle.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/YieldOracle.sol", "filename_short": "src/YieldOracle.sol", "is_dependency": false, "lines": [139], "starting_column": 32, "ending_column": 56}, "type_specific_fields": {"parent": {"type": "function", "name": "updateAll", "source_mapping": {"start": 5437, "length": 116, "filename_relative": "src/YieldOracle.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/YieldOracle.sol", "filename_short": "src/YieldOracle.sol", "is_dependency": false, "lines": [138, 139, 140, 141], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "YieldOracle", "source_mapping": {"start": 3047, "length": 5881, "filename_relative": "src/YieldOracle.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/YieldOracle.sol", "filename_short": "src/YieldOracle.sol", "is_dependency": false, "lines": [57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224], "starting_column": 1, "ending_column": 2}}, "signature": "updateAll()"}}}}], "description": "YieldOracle.updateAll() (src/YieldOracle.sol#138-141) ignores return value by ionPool.accrueInterest() (src/YieldOracle.sol#139)\n", "markdown": "[YieldOracle.updateAll()](src/YieldOracle.sol#L138-L141) ignores return value by [ionPool.accrueInterest()](src/YieldOracle.sol#L139)\n", "first_markdown_element": "src/YieldOracle.sol#L138-L141", "id": "986198a2f39a095fc081f4d8f67285aea44be178e4aca0f2d3eb45de0d5a86bc", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 42470, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "n % 2", "source_mapping": {"start": 43236, "length": 332, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1181, 1182, 1183, 1184, 1185, 1186, 1187], "starting_column": 21, "ending_column": 22}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42470, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1162-1191) uses a weak PRNG: \"n % 2 (src/IonPool.sol#1181-1187)\" \n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1162-L1191) uses a weak PRNG: \"[n % 2](src/IonPool.sol#L1181-L1187)\" \n", "first_markdown_element": "src/IonPool.sol#L1162-L1191", "id": "b99a435ac73cbca621d51aa00210c242607d5ec5b8902caa170e892c50b1231d", "check": "weak-prng", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 42470, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "switch_expr_42761_85_22__rpow_asm_0 = n % 2", "source_mapping": {"start": 42768, "length": 9, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1171], "starting_column": 24, "ending_column": 33}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42470, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1162-1191) uses a weak PRNG: \"switch_expr_42761_85_22__rpow_asm_0 = n % 2 (src/IonPool.sol#1171)\" \n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1162-L1191) uses a weak PRNG: \"[switch_expr_42761_85_22__rpow_asm_0 = n % 2](src/IonPool.sol#L1171)\" \n", "first_markdown_element": "src/IonPool.sol#L1162-L1191", "id": "1ede5f71fed7a5bbccce2844dd49b2414703f14a521a65eaae6d1571b8628612", "check": "weak-prng", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 42470, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "x = xxRound__rpow_asm_0 / b", "source_mapping": {"start": 43195, "length": 20, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1180], "starting_column": 21, "ending_column": 41}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42470, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}, {"type": "node", "name": "zx__rpow_asm_0 = z * x", "source_mapping": {"start": 43275, "length": 19, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1182], "starting_column": 25, "ending_column": 44}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42470, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1162-1191) performs a multiplication on the result of a division:\n\t- x = xxRound__rpow_asm_0 / b (src/IonPool.sol#1180)\n\t- zx__rpow_asm_0 = z * x (src/IonPool.sol#1182)\n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1162-L1191) performs a multiplication on the result of a division:\n\t- [x = xxRound__rpow_asm_0 / b](src/IonPool.sol#L1180)\n\t- [zx__rpow_asm_0 = z * x](src/IonPool.sol#L1182)\n", "first_markdown_element": "src/IonPool.sol#L1162-L1191", "id": "61fb6f963add510ca4bd5eca10bd92a6cfd1c96b8f889e0fb493c0da9df689c7", "check": "divide-before-multiply", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "_calculateRewardAndDebtDistributionForIlk", "source_mapping": {"start": 17163, "length": 2705, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_calculateRewardAndDebtDistributionForIlk(uint8,uint256)"}}, {"type": "node", "name": "_totalNormalizedDebt == 0 || block.timestamp == ilk.lastRateUpdate", "source_mapping": {"start": 17711, "length": 66, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [473], "starting_column": 13, "ending_column": 79}, "type_specific_fields": {"parent": {"type": "function", "name": "_calculateRewardAndDebtDistributionForIlk", "source_mapping": {"start": 17163, "length": 2705, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_calculateRewardAndDebtDistributionForIlk(uint8,uint256)"}}}}], "description": "IonPool._calculateRewardAndDebtDistributionForIlk(uint8,uint256) (src/IonPool.sol#455-516) uses a dangerous strict equality:\n\t- _totalNormalizedDebt == 0 || block.timestamp == ilk.lastRateUpdate (src/IonPool.sol#473)\n", "markdown": "[IonPool._calculateRewardAndDebtDistributionForIlk(uint8,uint256)](src/IonPool.sol#L455-L516) uses a dangerous strict equality:\n\t- [_totalNormalizedDebt == 0 || block.timestamp == ilk.lastRateUpdate](src/IonPool.sol#L473)\n", "first_markdown_element": "src/IonPool.sol#L455-L516", "id": "2937d1c975b61df063ba0217fa75862e55e8e9bfaffa9ae912f496914e924270", "check": "incorrect-equality", "impact": "Medium", "confidence": "High"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 42470, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "switch_expr_42631_77_22__rpow_asm_0 == 0", "source_mapping": {"start": 42656, "length": 17, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1167], "starting_column": 17, "ending_column": 34}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42470, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1162-1191) uses a dangerous strict equality:\n\t- switch_expr_42631_77_22__rpow_asm_0 == 0 (src/IonPool.sol#1167)\n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1162-L1191) uses a dangerous strict equality:\n\t- [switch_expr_42631_77_22__rpow_asm_0 == 0](src/IonPool.sol#L1167)\n", "first_markdown_element": "src/IonPool.sol#L1162-L1191", "id": "4ffcdd084cc7f8264895d8c6b78c5e24203f215a35068f6502ed627e436e4e69", "check": "incorrect-equality", "impact": "Medium", "confidence": "High"}, {"elements": [{"type": "function", "name": "_rpow", "source_mapping": {"start": 42470, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}, {"type": "node", "name": "switch_expr_42761_85_22__rpow_asm_0 == 0", "source_mapping": {"start": 42794, "length": 17, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1172], "starting_column": 17, "ending_column": 34}, "type_specific_fields": {"parent": {"type": "function", "name": "_rpow", "source_mapping": {"start": 42470, "length": 1146, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_rpow(uint256,uint256,uint256)"}}}}], "description": "IonPool._rpow(uint256,uint256,uint256) (src/IonPool.sol#1162-1191) uses a dangerous strict equality:\n\t- switch_expr_42761_85_22__rpow_asm_0 == 0 (src/IonPool.sol#1172)\n", "markdown": "[IonPool._rpow(uint256,uint256,uint256)](src/IonPool.sol#L1162-L1191) uses a dangerous strict equality:\n\t- [switch_expr_42761_85_22__rpow_asm_0 == 0](src/IonPool.sol#L1172)\n", "first_markdown_element": "src/IonPool.sol#L1162-L1191", "id": "6101a9579050ebf7d5fb9a6c0f35c6e4358fe2c7037d454d08570b3303990f4b", "check": "incorrect-equality", "impact": "Medium", "confidence": "High"}, {"elements": [{"type": "variable", "name": "newIlk", "source_mapping": {"start": 8804, "length": 17, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [213], "starting_column": 9, "ending_column": 26}, "type_specific_fields": {"parent": {"type": "function", "name": "initializeIlk", "source_mapping": {"start": 8198, "length": 869, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "initializeIlk(address)"}}}}], "description": "IonPool.initializeIlk(address).newIlk (src/IonPool.sol#213) is a local variable never initialized\n", "markdown": "[IonPool.initializeIlk(address).newIlk](src/IonPool.sol#L213) is a local variable never initialized\n", "first_markdown_element": "src/IonPool.sol#L213", "id": "6a23cce259d35b88a8d40e057d4b227447146af50568c2e5ea0c601f29707288", "check": "uninitialized-local", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "variable", "name": "totalTreasuryMintAmount", "source_mapping": {"start": 13946, "length": 31, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [362], "starting_column": 9, "ending_column": 40}, "type_specific_fields": {"parent": {"type": "function", "name": "_accrueInterest", "source_mapping": {"start": 13710, "length": 1389, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_accrueInterest()"}}}}], "description": "IonPool._accrueInterest().totalTreasuryMintAmount (src/IonPool.sol#362) is a local variable never initialized\n", "markdown": "[IonPool._accrueInterest().totalTreasuryMintAmount](src/IonPool.sol#L362) is a local variable never initialized\n", "first_markdown_element": "src/IonPool.sol#L362", "id": "c24a80daa1b2e5cbc9699d0278ab6c73c06927b9e005af4828303cc1e05d5db6", "check": "uninitialized-local", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "variable", "name": "totalSupplyFactorIncrease", "source_mapping": {"start": 13903, "length": 33, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [361], "starting_column": 9, "ending_column": 42}, "type_specific_fields": {"parent": {"type": "function", "name": "_accrueInterest", "source_mapping": {"start": 13710, "length": 1389, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_accrueInterest()"}}}}], "description": "IonPool._accrueInterest().totalSupplyFactorIncrease (src/IonPool.sol#361) is a local variable never initialized\n", "markdown": "[IonPool._accrueInterest().totalSupplyFactorIncrease](src/IonPool.sol#L361) is a local variable never initialized\n", "first_markdown_element": "src/IonPool.sol#L361", "id": "4c8b75067942ddef87b9fedfe5592846f62d4a18f7ad6ddb0b27bb76b8c66075", "check": "uninitialized-local", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "variable", "name": "totalDebtIncrease", "source_mapping": {"start": 13987, "length": 25, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [363], "starting_column": 9, "ending_column": 34}, "type_specific_fields": {"parent": {"type": "function", "name": "_accrueInterest", "source_mapping": {"start": 13710, "length": 1389, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "_accrueInterest()"}}}}], "description": "IonPool._accrueInterest().totalDebtIncrease (src/IonPool.sol#363) is a local variable never initialized\n", "markdown": "[IonPool._accrueInterest().totalDebtIncrease](src/IonPool.sol#L363) is a local variable never initialized\n", "first_markdown_element": "src/IonPool.sol#L363", "id": "6ee5d8cacb31b86be0c9ebba32774b18e0e729453529abdfb7a0ab120e4db29f", "check": "uninitialized-local", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "onlyWhitelistedBorrowers", "source_mapping": {"start": 4707, "length": 241, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [106, 107, 108, 109, 110], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "onlyWhitelistedBorrowers(uint8,address,bytes32[])"}}, {"type": "node", "name": "$.whitelist.isWhitelistedBorrower(ilkIndex,msg.sender,user,proof)", "source_mapping": {"start": 4862, "length": 68, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [108], "starting_column": 9, "ending_column": 77}, "type_specific_fields": {"parent": {"type": "function", "name": "onlyWhitelistedBorrowers", "source_mapping": {"start": 4707, "length": 241, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [106, 107, 108, 109, 110], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "onlyWhitelistedBorrowers(uint8,address,bytes32[])"}}}}], "description": "IonPool.onlyWhitelistedBorrowers(uint8,address,bytes32[]) (src/IonPool.sol#106-110) ignores return value by $.whitelist.isWhitelistedBorrower(ilkIndex,msg.sender,user,proof) (src/IonPool.sol#108)\n", "markdown": "[IonPool.onlyWhitelistedBorrowers(uint8,address,bytes32[])](src/IonPool.sol#L106-L110) ignores return value by [$.whitelist.isWhitelistedBorrower(ilkIndex,msg.sender,user,proof)](src/IonPool.sol#L108)\n", "first_markdown_element": "src/IonPool.sol#L106-L110", "id": "2f3da301dbb905b7d9a3940bb38b866271e35e6597cb8e4e8d53e380051ec0c9", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "onlyWhitelistedLenders", "source_mapping": {"start": 4954, "length": 211, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [112, 113, 114, 115, 116], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "onlyWhitelistedLenders(address,bytes32[])"}}, {"type": "node", "name": "$.whitelist.isWhitelistedLender(msg.sender,user,proof)", "source_mapping": {"start": 5091, "length": 56, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [114], "starting_column": 9, "ending_column": 65}, "type_specific_fields": {"parent": {"type": "function", "name": "onlyWhitelistedLenders", "source_mapping": {"start": 4954, "length": 211, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [112, 113, 114, 115, 116], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "IonPool", "source_mapping": {"start": 1220, "length": 42683, "filename_relative": "src/IonPool.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/IonPool.sol", "filename_short": "src/IonPool.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206], "starting_column": 1, "ending_column": 2}}, "signature": "onlyWhitelistedLenders(address,bytes32[])"}}}}], "description": "IonPool.onlyWhitelistedLenders(address,bytes32[]) (src/IonPool.sol#112-116) ignores return value by $.whitelist.isWhitelistedLender(msg.sender,user,proof) (src/IonPool.sol#114)\n", "markdown": "[IonPool.onlyWhitelistedLenders(address,bytes32[])](src/IonPool.sol#L112-L116) ignores return value by [$.whitelist.isWhitelistedLender(msg.sender,user,proof)](src/IonPool.sol#L114)\n", "first_markdown_element": "src/IonPool.sol#L112-L116", "id": "098fd68edbffd1a0d045df48178321fcfca7b408e65a20783d946e601fcc8bf0", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "variable", "name": "packedConfig_b", "source_mapping": {"start": 10213, "length": 22, "filename_relative": "src/InterestRate.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/InterestRate.sol", "filename_short": "src/InterestRate.sol", "is_dependency": false, "lines": [229], "starting_column": 9, "ending_column": 31}, "type_specific_fields": {"parent": {"type": "function", "name": "_unpackCollateralConfig", "source_mapping": {"start": 9996, "length": 3195, "filename_relative": "src/InterestRate.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/InterestRate.sol", "filename_short": "src/InterestRate.sol", "is_dependency": false, "lines": [225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "InterestRate", "source_mapping": {"start": 4333, "length": 13006, "filename_relative": "src/InterestRate.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/InterestRate.sol", "filename_short": "src/InterestRate.sol", "is_dependency": false, "lines": [91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382], "starting_column": 1, "ending_column": 2}}, "signature": "_unpackCollateralConfig(uint256)"}}}}], "description": "InterestRate._unpackCollateralConfig(uint256).packedConfig_b (src/InterestRate.sol#229) is a local variable never initialized\n", "markdown": "[InterestRate._unpackCollateralConfig(uint256).packedConfig_b](src/InterestRate.sol#L229) is a local variable never initialized\n", "first_markdown_element": "src/InterestRate.sol#L229", "id": "6644dfaf7e5259440f5dd2558ba44e78bd00d7dd570cf261ea41dba41e494ef2", "check": "uninitialized-local", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "variable", "name": "packedConfig_a", "source_mapping": {"start": 10181, "length": 22, "filename_relative": "src/InterestRate.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/InterestRate.sol", "filename_short": "src/InterestRate.sol", "is_dependency": false, "lines": [228], "starting_column": 9, "ending_column": 31}, "type_specific_fields": {"parent": {"type": "function", "name": "_unpackCollateralConfig", "source_mapping": {"start": 9996, "length": 3195, "filename_relative": "src/InterestRate.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/InterestRate.sol", "filename_short": "src/InterestRate.sol", "is_dependency": false, "lines": [225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "InterestRate", "source_mapping": {"start": 4333, "length": 13006, "filename_relative": "src/InterestRate.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/InterestRate.sol", "filename_short": "src/InterestRate.sol", "is_dependency": false, "lines": [91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382], "starting_column": 1, "ending_column": 2}}, "signature": "_unpackCollateralConfig(uint256)"}}}}], "description": "InterestRate._unpackCollateralConfig(uint256).packedConfig_a (src/InterestRate.sol#228) is a local variable never initialized\n", "markdown": "[InterestRate._unpackCollateralConfig(uint256).packedConfig_a](src/InterestRate.sol#L228) is a local variable never initialized\n", "first_markdown_element": "src/InterestRate.sol#L228", "id": "8ca8908a076e96cb1aa7383b5398e6e5d3bcda6d1889be74d6ce61df3804cc72", "check": "uninitialized-local", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "variable", "name": "packedConfig_c", "source_mapping": {"start": 10245, "length": 22, "filename_relative": "src/InterestRate.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/InterestRate.sol", "filename_short": "src/InterestRate.sol", "is_dependency": false, "lines": [230], "starting_column": 9, "ending_column": 31}, "type_specific_fields": {"parent": {"type": "function", "name": "_unpackCollateralConfig", "source_mapping": {"start": 9996, "length": 3195, "filename_relative": "src/InterestRate.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/InterestRate.sol", "filename_short": "src/InterestRate.sol", "is_dependency": false, "lines": [225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "InterestRate", "source_mapping": {"start": 4333, "length": 13006, "filename_relative": "src/InterestRate.sol", "filename_absolute": "/Users/hrikbhowal/Code/IonProjects/ion-protocol/src/InterestRate.sol", "filename_short": "src/InterestRate.sol", "is_dependency": false, "lines": [91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382], "starting_column": 1, "ending_column": 2}}, "signature": "_unpackCollateralConfig(uint256)"}}}}], "description": "InterestRate._unpackCollateralConfig(uint256).packedConfig_c (src/InterestRate.sol#230) is a local variable never initialized\n", "markdown": "[InterestRate._unpackCollateralConfig(uint256).packedConfig_c](src/InterestRate.sol#L230) is a local variable never initialized\n", "first_markdown_element": "src/InterestRate.sol#L230", "id": "072ca14da132fc55ac0995765578fdac60d248e6c492239498275b38d901e8a5", "check": "uninitialized-local", "impact": "Medium", "confidence": "Medium"}] \ No newline at end of file diff --git a/src/InterestRate.sol b/src/InterestRate.sol index b6a5b25f..d2f84798 100644 --- a/src/InterestRate.sol +++ b/src/InterestRate.sol @@ -325,9 +325,13 @@ contract InterestRate { if (distributionFactor == 0) { return (ilkData.minimumKinkRate, ilkData.reserveFactor.scaleUpToRay(4)); } + + // If the `totalEthSupply` is small enough to truncate to zero, then + // treat the utilization as zero. + uint256 totalEthSupplyScaled = totalEthSupply.wadMulDown(distributionFactor.scaleUpToWad(4)); + // [RAD] / [WAD] = [RAY] - uint256 utilizationRate = - totalEthSupply == 0 ? 0 : totalIlkDebt / (totalEthSupply.wadMulDown(distributionFactor.scaleUpToWad(4))); + uint256 utilizationRate = totalEthSupplyScaled == 0 ? 0 : totalIlkDebt / totalEthSupplyScaled; // Avoid stack too deep uint256 adjustedBelowKinkSlope; diff --git a/src/IonPool.sol b/src/IonPool.sol index 33fcacff..7eaaccab 100644 --- a/src/IonPool.sol +++ b/src/IonPool.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.21; import { Whitelist } from "./Whitelist.sol"; import { SpotOracle } from "./oracles/spot/SpotOracle.sol"; -import { RewardModule } from "./reward/RewardModule.sol"; +import { RewardToken } from "./token/RewardToken.sol"; import { InterestRate } from "./InterestRate.sol"; import { WadRayMath, RAY } from "./libraries/math/WadRayMath.sol"; @@ -23,7 +23,7 @@ import { PausableUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/P * * @custom:security-contact security@molecularlabs.io */ -contract IonPool is PausableUpgradeable, RewardModule { +contract IonPool is PausableUpgradeable, RewardToken { using SafeERC20 for IERC20; using SafeCast for *; using WadRayMath for *; @@ -106,13 +106,13 @@ contract IonPool is PausableUpgradeable, RewardModule { // --- Modifiers --- modifier onlyWhitelistedBorrowers(uint8 ilkIndex, address user, bytes32[] memory proof) { IonPoolStorage storage $ = _getIonPoolStorage(); - $.whitelist.isWhitelistedBorrower(ilkIndex, msg.sender, user, proof); + $.whitelist.isWhitelistedBorrower(ilkIndex, _msgSender(), user, proof); _; } modifier onlyWhitelistedLenders(address user, bytes32[] memory proof) { IonPoolStorage storage $ = _getIonPoolStorage(); - $.whitelist.isWhitelistedLender(msg.sender, user, proof); + $.whitelist.isWhitelistedLender(_msgSender(), user, proof); _; } @@ -136,14 +136,15 @@ contract IonPool is PausableUpgradeable, RewardModule { Ilk[] ilks; // remove() should never be called, it will mess up the ordering EnumerableSet.AddressSet ilkAddresses; + uint256 storageDiff; mapping(uint256 ilkIndex => mapping(address user => Vault)) vaults; mapping(uint256 ilkIndex => mapping(address user => uint256)) gem; // [WAD] mapping(address unbackedDebtor => uint256) unbackedDebt; // [RAD] mapping(address user => mapping(address operator => uint256)) isOperator; uint256 debt; // Total Debt [RAD] - uint256 weth; // liquidity in pool [WAD] - uint256 wethSupplyCap; // [WAD] - uint256 totalUnbackedDebt; // Total Unbacked WETH [RAD] + uint256 liquidity; // liquidity in pool [WAD] + uint256 supplyCap; // [WAD] + uint256 totalUnbackedDebt; // Total Unbacked Underlying [RAD] InterestRate interestRateModule; Whitelist whitelist; } @@ -176,7 +177,7 @@ contract IonPool is PausableUpgradeable, RewardModule { initializer { __AccessControlDefaultAdminRules_init(0, initialDefaultAdmin); - RewardModule._initialize(_underlying, _treasury, decimals_, name_, symbol_); + RewardToken._initialize(_underlying, _treasury, decimals_, name_, symbol_); _grantRole(ION, initialDefaultAdmin); @@ -278,7 +279,7 @@ contract IonPool is PausableUpgradeable, RewardModule { function updateSupplyCap(uint256 newSupplyCap) external onlyRole(ION) { IonPoolStorage storage $ = _getIonPoolStorage(); - $.wethSupplyCap = newSupplyCap; + $.supplyCap = newSupplyCap; emit SupplyCapUpdated(newSupplyCap); } @@ -478,7 +479,10 @@ contract IonPool is PausableUpgradeable, RewardModule { Ilk storage ilk = $.ilks[ilkIndex]; uint256 _totalNormalizedDebt = ilk.totalNormalizedDebt; - if (_totalNormalizedDebt == 0 || block.timestamp == ilk.lastRateUpdate) { + // Because all interest that would have accrued during a pause is + // cancelled upon `unpause`, we return zero interest while markets are + // paused. + if (_totalNormalizedDebt == 0 || block.timestamp == ilk.lastRateUpdate || paused()) { // Unsafe cast OK // block.timestamp - ilk.lastRateUpdate will almost always be 0 // here. The exception is on first borrow. @@ -490,14 +494,14 @@ contract IonPool is PausableUpgradeable, RewardModule { (uint256 borrowRate, uint256 reserveFactor) = $.interestRateModule.calculateInterestRate(ilkIndex, totalDebt, totalEthSupply); - if (borrowRate == 0) return (0, 0, 0, 0, 0); - - // Calculates borrowRate ^ (time) and returns the result with RAY precision - uint256 borrowRateExpT = _rpow(borrowRate + RAY, block.timestamp - ilk.lastRateUpdate, RAY); - // Unsafe cast OK timestampIncrease = uint48(block.timestamp) - ilk.lastRateUpdate; + if (borrowRate == 0) return (0, 0, 0, 0, timestampIncrease); + + // Calculates borrowRate ^ (time) and returns the result with RAY precision + uint256 borrowRateExpT = _rpow(borrowRate + RAY, timestampIncrease, RAY); + // Debt distribution // This form of rate accrual is much safer than distributing the new // debt increase to the total debt since low debt amounts won't cause @@ -537,7 +541,7 @@ contract IonPool is PausableUpgradeable, RewardModule { uint256 newTotalDebt = _accrueInterest(); IonPoolStorage storage $ = _getIonPoolStorage(); - $.weth -= amount; + $.liquidity -= amount; uint256 _supplyFactor = _burn({ user: _msgSender(), receiverOfUnderlying: receiverOfUnderlying, amount: amount }); @@ -564,11 +568,12 @@ contract IonPool is PausableUpgradeable, RewardModule { uint256 newTotalDebt = _accrueInterest(); IonPoolStorage storage $ = _getIonPoolStorage(); - $.weth += amount; + $.liquidity += amount; uint256 _supplyFactor = _mint({ user: user, senderOfUnderlying: _msgSender(), amount: amount }); - uint256 _supplyCap = $.wethSupplyCap; + uint256 _supplyCap = $.supplyCap; + if (totalSupply() > _supplyCap) revert DepositSurpassesSupplyCap(amount, _supplyCap); emit Supply(user, _msgSender(), amount, _supplyFactor, newTotalDebt); @@ -793,13 +798,13 @@ contract IonPool is PausableUpgradeable, RewardModule { uint256 amountWad = amountUint / RAY; if (amountUint % RAY > 0) ++amountWad; - $.weth += amountWad; + $.liquidity += amountWad; underlying().safeTransferFrom(user, address(this), amountWad); } else { // Round down in protocol's favor uint256 amountWad = uint256(amount) / RAY; - $.weth -= amountWad; + $.liquidity -= amountWad; underlying().safeTransfer(user, amountWad); } @@ -886,26 +891,6 @@ contract IonPool is PausableUpgradeable, RewardModule { // --- Getters --- - /** - * @return The total amount of collateral in the pool. - */ - function ilkCount() external view returns (uint256) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.ilks.length; - } - - /** - * @return The index of the collateral with `ilkAddress`. - */ - function getIlkIndex(address ilkAddress) external view returns (uint8) { - IonPoolStorage storage $ = _getIonPoolStorage(); - bytes32 addressInBytes32 = bytes32(uint256(uint160(ilkAddress))); - - // Since there should never be more than 256 collaterals, an unsafe cast - // should be fine - return uint8($.ilkAddresses._inner._positions[addressInBytes32] - 1); - } - /** * @return The address of the collateral at index `ilkIndex`. */ @@ -914,28 +899,6 @@ contract IonPool is PausableUpgradeable, RewardModule { return $.ilkAddresses.at(ilkIndex); } - /** - * @return Whether or not an address is a supported collateral. - */ - function addressContains(address ilk) external view returns (bool) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.ilkAddresses.contains(ilk); - } - - /** - * @return The total amount of normalized debt for collateral with index - * `ilkIndex`. - */ - function totalNormalizedDebt(uint8 ilkIndex) external view returns (uint256) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.ilks[ilkIndex].totalNormalizedDebt; - } - - function rateUnaccrued(uint8 ilkIndex) external view returns (uint256) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.ilks[ilkIndex].rate; - } - /** * @return The rate (debt accumulator) for collateral with index `ilkIndex`. */ @@ -947,31 +910,6 @@ contract IonPool is PausableUpgradeable, RewardModule { return $.ilks[ilkIndex].rate + newRateIncrease; } - /** - * @return The timestamp of the last rate update for collateral with index - * `ilkIndex`. - */ - function lastRateUpdate(uint8 ilkIndex) external view returns (uint256) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.ilks[ilkIndex].lastRateUpdate; - } - - /** - * @return The spot oracle for collateral with index `ilkIndex`. - */ - function spot(uint8 ilkIndex) external view returns (SpotOracle) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.ilks[ilkIndex].spot; - } - - /** - * @return debt ceiling for collateral with index `ilkIndex`. - */ - function debtCeiling(uint8 ilkIndex) external view returns (uint256) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.ilks[ilkIndex].debtCeiling; - } - /** * @return dust amount for collateral with index `ilkIndex`. */ @@ -1004,30 +942,6 @@ contract IonPool is PausableUpgradeable, RewardModule { return ($.vaults[ilkIndex][user].collateral, $.vaults[ilkIndex][user].normalizedDebt); } - /** - * @return Amount of `gem` that `user` has for collateral with index `ilkIndex`. - */ - function gem(uint8 ilkIndex, address user) external view returns (uint256) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.gem[ilkIndex][user]; - } - - /** - * @return The amount of unbacked debt `user` has. - */ - function unbackedDebt(address user) external view returns (uint256) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.unbackedDebt[user]; - } - - /** - * @return Whether or not `operator` is an `operator` on `user`'s positions. - */ - function isOperator(address user, address operator) external view returns (bool) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.isOperator[user][operator] == 1; - } - /** * @return Whether or not `operator` has permission to make unsafe changes * to `user`'s positions. @@ -1038,55 +952,6 @@ contract IonPool is PausableUpgradeable, RewardModule { return either(user == operator, $.isOperator[user][operator] == 1); } - function debtUnaccrued() external view returns (uint256) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.debt; - } - - /** - * @dev This includes unbacked debt. - * @return The total amount of debt. - */ - function debt() external view returns (uint256) { - IonPoolStorage storage $ = _getIonPoolStorage(); - - (,,, uint256 totalDebtIncrease,) = calculateRewardAndDebtDistribution(); - - return $.debt + totalDebtIncrease; - } - - /** - * @return The total amount of unbacked debt. - */ - function totalUnbackedDebt() external view returns (uint256) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.totalUnbackedDebt; - } - - /** - * @return The address of interest rate module. - */ - function interestRateModule() external view returns (address) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return address($.interestRateModule); - } - - /** - * @return The address of the whitelist. - */ - function whitelist() external view returns (address) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return address($.whitelist); - } - - /** - * @return The total amount of ETH liquidity in the pool. - */ - function weth() external view returns (uint256) { - IonPoolStorage storage $ = _getIonPoolStorage(); - return $.weth; - } - /** * @dev Gets the current borrow rate for borrowing against a given collateral. */ @@ -1094,6 +959,7 @@ contract IonPool is PausableUpgradeable, RewardModule { IonPoolStorage storage $ = _getIonPoolStorage(); uint256 totalEthSupply = totalSupplyUnaccrued(); + uint256 _totalNormalizedDebt = $.ilks[ilkIndex].totalNormalizedDebt; uint256 _rate = $.ilks[ilkIndex].rate; @@ -1103,6 +969,12 @@ contract IonPool is PausableUpgradeable, RewardModule { borrowRate += RAY; } + function extsload(bytes32 slot) external view returns (bytes32 value) { + assembly { + value := sload(slot) + } + } + /** * @dev Address of the implementation. This is stored immutably on the * implementation so that it can be read by the proxy. diff --git a/src/interfaces/IGemJoin.sol b/src/interfaces/IGemJoin.sol new file mode 100644 index 00000000..d6ba9376 --- /dev/null +++ b/src/interfaces/IGemJoin.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.4; + +interface IGemJoin { + error AddressEmptyCode(address target); + error AddressInsufficientBalance(address account); + error EnforcedPause(); + error ExpectedPause(); + error FailedInnerCall(); + error Int256Overflow(); + error OwnableInvalidOwner(address owner); + error OwnableUnauthorizedAccount(address account); + error SafeERC20FailedOperation(address token); + error WrongIlkAddress(uint8 ilkIndex, address gem); + + event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner); + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + event Paused(address account); + event Unpaused(address account); + + function GEM() external view returns (address); + function ILK_INDEX() external view returns (uint8); + function POOL() external view returns (address); + function acceptOwnership() external; + function exit(address user, uint256 amount) external; + function join(address user, uint256 amount) external; + function owner() external view returns (address); + function pause() external; + function paused() external view returns (bool); + function pendingOwner() external view returns (address); + function renounceOwnership() external; + function totalGem() external view returns (uint256); + function transferOwnership(address newOwner) external; + function unpause() external; +} diff --git a/src/interfaces/IInterestRate.sol b/src/interfaces/IInterestRate.sol new file mode 100644 index 00000000..436f756d --- /dev/null +++ b/src/interfaces/IInterestRate.sol @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.4; + +interface IInterestRate { + struct IlkData { + uint96 adjustedProfitMargin; + uint96 minimumKinkRate; + uint16 reserveFactor; + uint96 adjustedBaseRate; + uint96 minimumBaseRate; + uint16 optimalUtilizationRate; + uint16 distributionFactor; + uint96 adjustedAboveKinkSlope; + uint96 minimumAboveKinkSlope; + } + + error CollateralIndexOutOfBounds(); + error DistributionFactorsDoNotSumToOne(uint256 sum); + error InvalidIlkDataListLength(uint256 length); + error InvalidMinimumKinkRate(uint256 minimumKinkRate, uint256 minimumBaseRate); + error InvalidOptimalUtilizationRate(uint256 optimalUtilizationRate); + error InvalidReserveFactor(uint256 reserveFactor); + error InvalidYieldOracleAddress(); + error MathOverflowedMulDiv(); + error NotScalingUp(uint256 from, uint256 to); + error TotalDebtsLength(uint256 COLLATERAL_COUNT, uint256 totalIlkDebtsLength); + + function COLLATERAL_COUNT() external view returns (uint256); + function YIELD_ORACLE() external view returns (address); + function calculateInterestRate( + uint256 ilkIndex, + uint256 totalIlkDebt, + uint256 totalEthSupply + ) + external + view + returns (uint256, uint256); + function unpackCollateralConfig(uint256 index) external view returns (IlkData memory ilkData); +} diff --git a/src/interfaces/IIonLens.sol b/src/interfaces/IIonLens.sol new file mode 100644 index 00000000..118460ec --- /dev/null +++ b/src/interfaces/IIonLens.sol @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.4; + +import { IIonPool } from "./IIonPool.sol"; + +interface IIonLens { + function queryPoolSlot(IIonPool pool, uint256 slot) external view returns (uint256 value); + + function ilkCount(IIonPool pool) external view returns (uint256); + + function getIlkIndex(IIonPool pool, address ilkAddress) external view returns (uint8); + + function totalNormalizedDebt(IIonPool pool, uint8 ilkIndex) external view returns (uint256); + + function rateUnaccrued(IIonPool pool, uint8 ilkIndex) external view returns (uint256); + + function lastRateUpdate(IIonPool pool, uint8 ilkIndex) external view returns (uint256); + + function spot(IIonPool pool, uint8 ilkIndex) external view returns (address); + + function debtCeiling(IIonPool pool, uint8 ilkIndex) external view returns (uint256); + + function dust(IIonPool pool, uint8 ilkIndex) external view returns (uint256); + + function gem(IIonPool pool, uint8 ilkIndex, address user) external view returns (uint256); + + function unbackedDebt(IIonPool pool, address unbackedDebtor) external view returns (uint256); + + function isOperator(IIonPool pool, address user, address operator) external view returns (bool); + + function debtUnaccrued(IIonPool pool) external view returns (uint256); + + function debt(IIonPool pool) external view returns (uint256); + + function liquidity(IIonPool pool) external view returns (uint256); + + function supplyCap(IIonPool pool) external view returns (uint256); + + function totalUnbackedDebt(IIonPool pool) external view returns (uint256); + + function interestRateModule(IIonPool pool) external view returns (address); + + function whitelist(IIonPool pool) external view returns (address); +} diff --git a/src/interfaces/IIonPool.sol b/src/interfaces/IIonPool.sol new file mode 100644 index 00000000..b7b9e587 --- /dev/null +++ b/src/interfaces/IIonPool.sol @@ -0,0 +1,238 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.4; + +interface IIonPool { + error AccessControlBadConfirmation(); + error AccessControlEnforcedDefaultAdminDelay(uint48 schedule); + error AccessControlEnforcedDefaultAdminRules(); + error AccessControlInvalidDefaultAdmin(address defaultAdmin); + error AccessControlUnauthorizedAccount(address account, bytes32 neededRole); + error AddressEmptyCode(address target); + error AddressInsufficientBalance(address account); + error ArithmeticError(); + error CeilingExceeded(uint256 newDebt, uint256 debtCeiling); + error DepositSurpassesSupplyCap(uint256 depositAmount, uint256 supplyCap); + error EnforcedPause(); + error ExpectedPause(); + error FailedInnerCall(); + error GemTransferWithoutConsent(uint8 ilkIndex, address user, address unconsentedOperator); + error IlkAlreadyAdded(address ilkAddress); + error IlkNotInitialized(uint256 ilkIndex); + error InsufficientBalance(address account, uint256 balance, uint256 needed); + error InvalidBurnAmount(); + error InvalidIlkAddress(); + error InvalidInitialization(); + error InvalidInterestRateModule(address invalidInterestRateModule); + error InvalidMintAmount(); + error InvalidReceiver(address receiver); + error InvalidSender(address sender); + error InvalidTreasuryAddress(); + error InvalidUnderlyingAddress(); + error InvalidWhitelist(); + error MathOverflowedMulDiv(); + error MaxIlksReached(); + error NotInitializing(); + error NotScalingUp(uint256 from, uint256 to); + error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value); + error SafeCastOverflowedUintToInt(uint256 value); + error SafeERC20FailedOperation(address token); + error TakingWethWithoutConsent(address payer, address unconsentedOperator); + error UnsafePositionChange(uint256 newTotalDebtInVault, uint256 collateral, uint256 spot); + error UnsafePositionChangeWithoutConsent(uint8 ilkIndex, address user, address unconsentedOperator); + error UseOfCollateralWithoutConsent(uint8 ilkIndex, address depositor, address unconsentedOperator); + error VaultCannotBeDusty(uint256 amountLeft, uint256 dust); + + event AddOperator(address indexed user, address indexed operator); + event Borrow( + uint8 indexed ilkIndex, + address indexed user, + address indexed recipient, + uint256 amountOfNormalizedDebt, + uint256 ilkRate, + uint256 totalDebt + ); + event ConfiscateVault( + uint8 indexed ilkIndex, + address indexed u, + address v, + address indexed w, + int256 changeInCollateral, + int256 changeInNormalizedDebt + ); + event DefaultAdminDelayChangeCanceled(); + event DefaultAdminDelayChangeScheduled(uint48 newDelay, uint48 effectSchedule); + event DefaultAdminTransferCanceled(); + event DefaultAdminTransferScheduled(address indexed newAdmin, uint48 acceptSchedule); + event DepositCollateral(uint8 indexed ilkIndex, address indexed user, address indexed depositor, uint256 amount); + event IlkDebtCeilingUpdated(uint8 indexed ilkIndex, uint256 newDebtCeiling); + event IlkDustUpdated(uint8 indexed ilkIndex, uint256 newDust); + event IlkInitialized(uint8 indexed ilkIndex, address indexed ilkAddress); + event IlkSpotUpdated(uint8 indexed ilkIndex, address newSpot); + event Initialized(uint64 version); + event InterestRateModuleUpdated(address newModule); + event MintAndBurnGem(uint8 indexed ilkIndex, address indexed usr, int256 wad); + event MintToTreasury(address indexed treasury, uint256 amount, uint256 supplyFactor); + event Paused(address account); + event RemoveOperator(address indexed user, address indexed operator); + event Repay( + uint8 indexed ilkIndex, + address indexed user, + address indexed payer, + uint256 amountOfNormalizedDebt, + uint256 ilkRate, + uint256 totalDebt + ); + event RepayBadDebt(address indexed user, address indexed payer, uint256 rad); + event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); + event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); + event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); + event Supply( + address indexed user, address indexed underlyingFrom, uint256 amount, uint256 supplyFactor, uint256 newDebt + ); + event SupplyCapUpdated(uint256 newSupplyCap); + event Transfer(address indexed from, address indexed to, uint256 value); + event TransferGem(uint8 indexed ilkIndex, address indexed src, address indexed dst, uint256 wad); + event TreasuryUpdate(address treasury); + event Unpaused(address account); + event WhitelistUpdated(address newWhitelist); + event Withdraw(address indexed user, address indexed target, uint256 amount, uint256 supplyFactor, uint256 newDebt); + event WithdrawCollateral(uint8 indexed ilkIndex, address indexed user, address indexed recipient, uint256 amount); + + function DEFAULT_ADMIN_ROLE() external view returns (bytes32); + function GEM_JOIN_ROLE() external view returns (bytes32); + function ION() external view returns (bytes32); + function LIQUIDATOR_ROLE() external view returns (bytes32); + function PAUSE_ROLE() external view returns (bytes32); + function acceptDefaultAdminTransfer() external; + function accrueInterest() external returns (uint256 newTotalDebt); + function addOperator(address operator) external; + function addressContains(address ilk) external view returns (bool); + function balanceOf(address user) external view returns (uint256); + function beginDefaultAdminTransfer(address newAdmin) external; + function borrow( + uint8 ilkIndex, + address user, + address recipient, + uint256 amountOfNormalizedDebt, + bytes32[] memory proof + ) + external; + function calculateRewardAndDebtDistribution() + external + view + returns ( + uint256 totalSupplyFactorIncrease, + uint256 totalTreasuryMintAmount, + uint104[] memory rateIncreases, + uint256 totalDebtIncrease, + uint48[] memory timestampIncreases + ); + function calculateRewardAndDebtDistributionForIlk(uint8 ilkIndex) + external + view + returns (uint104 newRateIncrease, uint48 timestampIncrease); + function cancelDefaultAdminTransfer() external; + function changeDefaultAdminDelay(uint48 newDelay) external; + function collateral(uint8 ilkIndex, address user) external view returns (uint256); + function confiscateVault( + uint8 ilkIndex, + address u, + address v, + address w, + int256 changeInCollateral, + int256 changeInNormalizedDebt + ) + external; + function debt() external view returns (uint256); + function debtCeiling(uint8 ilkIndex) external view returns (uint256); + function debtUnaccrued() external view returns (uint256); + function decimals() external view returns (uint8); + function defaultAdmin() external view returns (address); + function defaultAdminDelay() external view returns (uint48); + function defaultAdminDelayIncreaseWait() external view returns (uint48); + function depositCollateral( + uint8 ilkIndex, + address user, + address depositor, + uint256 amount, + bytes32[] memory proof + ) + external; + function dust(uint8 ilkIndex) external view returns (uint256); + function gem(uint8 ilkIndex, address user) external view returns (uint256); + function getCurrentBorrowRate(uint8 ilkIndex) external view returns (uint256 borrowRate, uint256 reserveFactor); + function getIlkAddress(uint256 ilkIndex) external view returns (address); + function getIlkIndex(address ilkAddress) external view returns (uint8); + function getRoleAdmin(bytes32 role) external view returns (bytes32); + function grantRole(bytes32 role, address account) external; + function hasRole(bytes32 role, address account) external view returns (bool); + function ilkCount() external view returns (uint256); + function implementation() external view returns (address); + function initialize( + address _underlying, + address _treasury, + uint8 decimals_, + string memory name_, + string memory symbol_, + address initialDefaultAdmin, + address _interestRateModule, + address _whitelist + ) + external; + function initializeIlk(address ilkAddress) external; + function interestRateModule() external view returns (address); + function isAllowed(address user, address operator) external view returns (bool); + function isOperator(address user, address operator) external view returns (bool); + function lastRateUpdate(uint8 ilkIndex) external view returns (uint256); + function mintAndBurnGem(uint8 ilkIndex, address usr, int256 wad) external; + function name() external view returns (string memory); + function normalizedBalanceOf(address user) external view returns (uint256); + function normalizedDebt(uint8 ilkIndex, address user) external view returns (uint256); + function normalizedTotalSupply() external view returns (uint256); + function normalizedTotalSupplyUnaccrued() external view returns (uint256); + function owner() external view returns (address); + function pause() external; + function paused() external view returns (bool); + function pendingDefaultAdmin() external view returns (address newAdmin, uint48 schedule); + function pendingDefaultAdminDelay() external view returns (uint48 newDelay, uint48 schedule); + function rate(uint8 ilkIndex) external view returns (uint256); + function rateUnaccrued(uint8 ilkIndex) external view returns (uint256); + function removeOperator(address operator) external; + function renounceRole(bytes32 role, address account) external; + function repay(uint8 ilkIndex, address user, address payer, uint256 amountOfNormalizedDebt) external; + function repayBadDebt(address user, uint256 rad) external; + function revokeRole(bytes32 role, address account) external; + function rollbackDefaultAdminDelay() external; + function spot(uint8 ilkIndex) external view returns (address); + function supply(address user, uint256 amount, bytes32[] memory proof) external; + function supplyFactor() external view returns (uint256); + function supplyFactorUnaccrued() external view returns (uint256); + function supportsInterface(bytes4 interfaceId) external view returns (bool); + function symbol() external view returns (string memory); + function totalNormalizedDebt(uint8 ilkIndex) external view returns (uint256); + function totalSupply() external view returns (uint256); + function totalSupplyUnaccrued() external view returns (uint256); + function totalUnbackedDebt() external view returns (uint256); + function transferGem(uint8 ilkIndex, address src, address dst, uint256 wad) external; + function treasury() external view returns (address); + function unbackedDebt(address user) external view returns (uint256); + function underlying() external view returns (address); + function unpause() external; + function updateIlkDebtCeiling(uint8 ilkIndex, uint256 newCeiling) external; + function updateIlkDust(uint8 ilkIndex, uint256 newDust) external; + function updateIlkSpot(uint8 ilkIndex, address newSpot) external; + function updateInterestRateModule(address _interestRateModule) external; + function updateSupplyCap(uint256 newSupplyCap) external; + function updateTreasury(address newTreasury) external; + function updateWhitelist(address _whitelist) external; + function vault(uint8 ilkIndex, address user) external view returns (uint256, uint256); + function weth() external view returns (uint256); + function whitelist() external view returns (address); + function withdraw(address receiverOfUnderlying, uint256 amount) external; + function withdrawCollateral(uint8 ilkIndex, address user, address recipient, uint256 amount) external; + + function getTotalUnderlyingClaims() external view returns (uint256); + function getUnderlyingClaimOf(address user) external view returns (uint256); + function extsload(bytes32 slot) external view returns (bytes32); + function balanceOfUnaccrued(address user) external view returns (uint256); +} diff --git a/src/interfaces/IVault.sol b/src/interfaces/IVault.sol new file mode 100644 index 00000000..65669ea1 --- /dev/null +++ b/src/interfaces/IVault.sol @@ -0,0 +1,142 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.4; + +interface IVault { + struct MarketAllocation { + address pool; + int256 assets; + } + + error AccessControlBadConfirmation(); + error AccessControlEnforcedDefaultAdminDelay(uint48 schedule); + error AccessControlEnforcedDefaultAdminRules(); + error AccessControlInvalidDefaultAdmin(address defaultAdmin); + error AccessControlUnauthorizedAccount(address account, bytes32 neededRole); + error AddressEmptyCode(address target); + error AddressInsufficientBalance(address account); + error AllSupplyCapsReached(); + error AllocationCapExceeded(); + error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); + error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); + error ERC20InvalidApprover(address approver); + error ERC20InvalidReceiver(address receiver); + error ERC20InvalidSender(address sender); + error ERC20InvalidSpender(address spender); + error ERC4626ExceededMaxDeposit(address receiver, uint256 assets, uint256 max); + error ERC4626ExceededMaxMint(address receiver, uint256 shares, uint256 max); + error ERC4626ExceededMaxRedeem(address owner, uint256 shares, uint256 max); + error ERC4626ExceededMaxWithdraw(address owner, uint256 assets, uint256 max); + error FailedInnerCall(); + error InvalidIdleMarketRemovalNonZeroBalance(); + error InvalidMarketRemovalNonZeroSupply(); + error InvalidQueueContainsDuplicates(); + error InvalidQueueLength(); + error InvalidQueueMarketNotSupported(); + error InvalidReallocation(); + error InvalidSupportedMarkets(); + error IonPoolsArrayAndNewCapsArrayMustBeOfEqualLength(); + error MarketAlreadySupported(); + error MarketNotSupported(); + error MarketsAndAllocationCapLengthMustBeEqual(); + error MathOverflowedMulDiv(); + error NotEnoughLiquidityToWithdraw(); + error ReentrancyGuardReentrantCall(); + error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value); + error SafeERC20FailedOperation(address token); + + event Approval(address indexed owner, address indexed spender, uint256 value); + event DefaultAdminDelayChangeCanceled(); + event DefaultAdminDelayChangeScheduled(uint48 newDelay, uint48 effectSchedule); + event DefaultAdminTransferCanceled(); + event DefaultAdminTransferScheduled(address indexed newAdmin, uint48 acceptSchedule); + event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); + event FeeAccrued(uint256 feeShares, uint256 newTotalAssets); + event ReallocateSupply(address indexed pool, uint256 assets); + event ReallocateWithdraw(address indexed pool, uint256 assets); + event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); + event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); + event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); + event Transfer(address indexed from, address indexed to, uint256 value); + event UpdateLastTotalAssets(uint256 lastTotalAssets, uint256 newLastTotalAssets); + event UpdateSupplyQueue(address indexed caller, address newSupplyQueue); + event UpdateWithdrawQueue(address indexed caller, address newWithdrawQueue); + event Withdraw( + address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares + ); + + function ALLOCATOR_ROLE() external view returns (bytes32); + function DECIMALS_OFFSET() external view returns (uint8); + function DEFAULT_ADMIN_ROLE() external view returns (bytes32); + function OWNER_ROLE() external view returns (bytes32); + function acceptDefaultAdminTransfer() external; + function addSupportedMarkets( + address marketsToAdd, + uint256[] memory allocationCaps, + address newSupplyQueue, + address newWithdrawQueue + ) + external; + function allowance(address owner, address spender) external view returns (uint256); + function approve(address spender, uint256 value) external returns (bool); + function asset() external view returns (address); + function balanceOf(address account) external view returns (uint256); + function baseAsset() external view returns (address); + function beginDefaultAdminTransfer(address newAdmin) external; + function cancelDefaultAdminTransfer() external; + function caps(address) external view returns (uint256); + function changeDefaultAdminDelay(uint48 newDelay) external; + function convertToAssets(uint256 shares) external view returns (uint256); + function convertToShares(uint256 assets) external view returns (uint256); + function decimals() external view returns (uint8); + function defaultAdmin() external view returns (address); + function defaultAdminDelay() external view returns (uint48); + function defaultAdminDelayIncreaseWait() external view returns (uint48); + function deposit(uint256 assets, address receiver) external returns (uint256 shares); + function feePercentage() external view returns (uint256); + function feeRecipient() external view returns (address); + function getRoleAdmin(bytes32 role) external view returns (bytes32); + function getSupportedMarkets() external view returns (address[] memory); + function grantRole(bytes32 role, address account) external; + function hasRole(bytes32 role, address account) external view returns (bool); + function ionLens() external view returns (address); + function lastTotalAssets() external view returns (uint256); + function maxDeposit(address) external view returns (uint256); + function maxMint(address) external view returns (uint256); + function maxRedeem(address owner) external view returns (uint256); + function maxWithdraw(address owner) external view returns (uint256 assets); + function mint(uint256 shares, address receiver) external returns (uint256 assets); + function multicall(bytes[] memory data) external returns (bytes[] memory results); + function name() external view returns (string memory); + function owner() external view returns (address); + function pendingDefaultAdmin() external view returns (address newAdmin, uint48 schedule); + function pendingDefaultAdminDelay() external view returns (uint48 newDelay, uint48 schedule); + function previewDeposit(uint256 assets) external view returns (uint256); + function previewMint(uint256 shares) external view returns (uint256); + function previewRedeem(uint256 shares) external view returns (uint256); + function previewWithdraw(uint256 assets) external view returns (uint256); + function reallocate(MarketAllocation[] memory allocations) external; + function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); + function removeSupportedMarkets( + address marketsToRemove, + address newSupplyQueue, + address newWithdrawQueue + ) + external; + function renounceRole(bytes32 role, address account) external; + function revokeRole(bytes32 role, address account) external; + function rollbackDefaultAdminDelay() external; + function supplyQueue(uint256) external view returns (address); + function supportsInterface(bytes4 interfaceId) external view returns (bool); + function symbol() external view returns (string memory); + function totalAssets() external view returns (uint256 assets); + function totalSupply() external view returns (uint256); + function transfer(address to, uint256 value) external returns (bool); + function transferFrom(address from, address to, uint256 value) external returns (bool); + function updateAllocationCaps(address ionPools, uint256[] memory newCaps) external; + function updateFeePercentage(uint256 _feePercentage) external; + function updateFeeRecipient(address _feeRecipient) external; + function updateSupplyQueue(address newSupplyQueue) external; + function updateWithdrawQueue(address newWithdrawQueue) external; + function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares); + function withdrawQueue(uint256) external view returns (address); +} diff --git a/src/interfaces/IWhitelist.sol b/src/interfaces/IWhitelist.sol new file mode 100644 index 00000000..13d2c9bb --- /dev/null +++ b/src/interfaces/IWhitelist.sol @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.4; + +interface IWhitelist { + error NotWhitelistedBorrower(uint8 ilkIndex, address addr); + error NotWhitelistedLender(address addr); + error OwnableInvalidOwner(address owner); + error OwnableUnauthorizedAccount(address account); + + event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner); + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + + function acceptOwnership() external; + function approveProtocolWhitelist(address addr) external; + function borrowersRoot(uint8 ilkIndex) external view returns (bytes32); + function isWhitelistedBorrower( + uint8 ilkIndex, + address poolCaller, + address addr, + bytes32[] memory proof + ) + external + view + returns (bool); + function isWhitelistedLender( + address poolCaller, + address addr, + bytes32[] memory proof + ) + external + view + returns (bool); + function lendersRoot() external view returns (bytes32); + function owner() external view returns (address); + function pendingOwner() external view returns (address); + function protocolWhitelist(address protocolControlledAddress) external view returns (bool); + function renounceOwnership() external; + function revokeProtocolWhitelist(address addr) external; + function transferOwnership(address newOwner) external; + function updateBorrowersRoot(uint8 ilkIndex, bytes32 _borrowersRoot) external; + function updateLendersRoot(bytes32 _lendersRoot) external; +} diff --git a/src/periphery/IonInvariants.sol b/src/periphery/IonInvariants.sol index f2a996fa..2302f985 100644 --- a/src/periphery/IonInvariants.sol +++ b/src/periphery/IonInvariants.sol @@ -1,7 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.21; -import { IonPool } from "../IonPool.sol"; +import { IIonLens } from "../interfaces/IIonLens.sol"; +import { IIonPool } from "../interfaces/IIonPool.sol"; import { WadRayMath } from "../libraries/math/WadRayMath.sol"; /** @@ -13,12 +14,18 @@ import { WadRayMath } from "../libraries/math/WadRayMath.sol"; contract IonInvariants { using WadRayMath for uint256; + IIonLens lens; + + constructor(IIonLens _lens) { + lens = _lens; + } + /** * @notice Liquidity in pool + debt to pool >= total supply. */ - function Invariant1(IonPool ionPool) external view { + function Invariant1(IIonPool ionPool) external view { require( - ionPool.weth().scaleUpToRad(18) + ionPool.debtUnaccrued() + lens.liquidity(ionPool).scaleUpToRad(18) + lens.debtUnaccrued(ionPool) >= ionPool.normalizedTotalSupplyUnaccrued() * ionPool.supplyFactorUnaccrued() ); } @@ -26,35 +33,36 @@ contract IonInvariants { /** * @notice [Sum of all (ilk total normalized debt * ilk rate)] + unbacked debt >= debt to pool. */ - function Invariant2(IonPool ionPool) external view { + function Invariant2(IIonPool ionPool) external view { uint256 totalDebt; - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { - uint256 totalNormalizedDebt = ionPool.totalNormalizedDebt(i); - uint256 ilkRate = ionPool.rateUnaccrued(i); + for (uint8 i = 0; i < lens.ilkCount(ionPool); i++) { + uint256 totalNormalizedDebt = lens.totalNormalizedDebt(ionPool, i); + uint256 ilkRate = lens.rateUnaccrued(ionPool, i); totalDebt += totalNormalizedDebt * ilkRate; } - require(totalDebt + ionPool.totalUnbackedDebt() == ionPool.debtUnaccrued()); + require(totalDebt + lens.totalUnbackedDebt(ionPool) == lens.debtUnaccrued(ionPool)); } /** * @notice Invariant1 accrued */ - function Invariant3(IonPool ionPool) external view { + function Invariant3(IIonPool ionPool) external view { require( - ionPool.weth().scaleUpToRad(18) + ionPool.debt() >= ionPool.normalizedTotalSupply() * ionPool.supplyFactor() + lens.liquidity(ionPool).scaleUpToRad(18) + lens.debt(ionPool) + >= ionPool.normalizedTotalSupply() * ionPool.supplyFactor() ); } /** * @notice Invariant2 accrued */ - function Invariant4(IonPool ionPool) external view { + function Invariant4(IIonPool ionPool) external view { uint256 totalDebt; - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { - uint256 totalNormalizedDebt = ionPool.totalNormalizedDebt(i); + for (uint8 i = 0; i < lens.ilkCount(ionPool); i++) { + uint256 totalNormalizedDebt = lens.totalNormalizedDebt(ionPool, i); uint256 ilkRate = ionPool.rate(i); totalDebt += totalNormalizedDebt * ilkRate; } - require(totalDebt + ionPool.totalUnbackedDebt() == ionPool.debt()); + require(totalDebt + lens.totalUnbackedDebt(ionPool) == lens.debt(ionPool)); } } diff --git a/src/periphery/IonLens.sol b/src/periphery/IonLens.sol new file mode 100644 index 00000000..37bfc3b2 --- /dev/null +++ b/src/periphery/IonLens.sol @@ -0,0 +1,385 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +import { IIonPool } from "../interfaces/IIonPool.sol"; +import { IIonLens } from "../interfaces/IIonLens.sol"; + +import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import { StorageSlot } from "@openzeppelin/contracts/utils/StorageSlot.sol"; + +struct IlkSlot0 { + uint104 totalNormalizedDebt; // Total Normalised Debt [WAD] + uint104 rate; // Accumulated Rates [RAY] + uint48 lastRateUpdate; // block.timestamp of last update; overflows in 800_000 years} +} + +contract IonLens is IIonLens { + // --- Data --- + struct Ilk { + IlkSlot0 slot0; + StorageSlot.AddressSlot spot; // Oracle that provides price with safety margin + StorageSlot.Uint256Slot debtCeiling; // Debt Ceiling [RAD] + StorageSlot.Uint256Slot dust; // Vault Debt Floor [RAD] + } + + struct Vault { + StorageSlot.Uint256Slot collateral; // Locked Collateral [WAD] + StorageSlot.Uint256Slot normalizedDebt; // Normalised Debt [WAD] + } + + /// @custom:storage-location erc7201:ion.storage.IonPool + struct IonPoolStorage { + Ilk[] ilks; + // remove() should never be called, it will mess up the ordering + EnumerableSet.AddressSet ilkAddresses; + mapping(uint256 ilkIndex => mapping(address user => Vault)) vaults; + mapping(uint256 ilkIndex => mapping(address user => StorageSlot.Uint256Slot)) gem; // [WAD] + mapping(address unbackedDebtor => StorageSlot.Uint256Slot) unbackedDebt; // [RAD] + mapping(address user => mapping(address operator => StorageSlot.Uint256Slot)) isOperator; + StorageSlot.Uint256Slot debt; // Total Debt [RAD] + StorageSlot.Uint256Slot liquidity; // liquidity in pool [WAD] + StorageSlot.Uint256Slot supplyCap; // [WAD] + StorageSlot.Uint256Slot totalUnbackedDebt; // Total Unbacked Underlying [RAD] + StorageSlot.AddressSlot interestRateModule; + StorageSlot.AddressSlot whitelist; + } + + // keccak256(abi.encode(uint256(keccak256("ion.storage.IonPool")) - 1)) & ~uint56(0xff)) + // solhint-disable-next-line + bytes32 private constant IonPoolStorageLocation = 0xceba3d526b4d5afd91d1b752bf1fd37917c20a6daf576bcb41dd1c57c1f67e00; + + bytes4 private constant EXTSLOAD_SELECTOR = 0x1e2eaeaf; + + error SloadFailed(); + error InvalidFieldSlot(); + + constructor() { + IonPoolStorage storage $ = _getIonPoolStorage(); + + // 4 collaterals should be enough. Must be initialized here to not + // trigger an access-out-of-bounds error. + $.ilks.push(); + $.ilks.push(); + $.ilks.push(); + $.ilks.push(); + } + + function _getIonPoolStorage() internal pure returns (IonPoolStorage storage $) { + assembly { + $.slot := IonPoolStorageLocation + } + } + + function _toUint256PointerMapping(mapping(bytes32 => uint256) storage inPtr) + private + pure + returns (mapping(address => StorageSlot.Uint256Slot) storage outPtr) + { + assembly { + outPtr.slot := inPtr.slot + } + } + + function queryPoolSlot(IIonPool pool, uint256 slot) public view returns (uint256 value) { + assembly ("memory-safe") { + mstore(0x00, EXTSLOAD_SELECTOR) + mstore(0x04, slot) + if iszero(staticcall(gas(), pool, 0x00, 0x24, 0x00, 0x20)) { + mstore(0x00, 0x74d9f8d3) // SloadFailed() + revert(0x1c, 0x04) + } + value := mload(0x00) + } + } + + /** + * @return The total amount of collateral in the pool. + */ + function ilkCount(IIonPool pool) external view returns (uint256) { + IonPoolStorage storage $ = _getIonPoolStorage(); + Ilk[] storage ilks = $.ilks; + + uint256 slot; + assembly { + // Length of ilks array + slot := ilks.slot + } + + uint256 value = queryPoolSlot(pool, slot); + return value; + } + + /** + * @return The index of the collateral with `ilkAddress`. + */ + function getIlkIndex(IIonPool pool, address ilkAddress) external view returns (uint8) { + IonPoolStorage storage $ = _getIonPoolStorage(); + mapping(address => StorageSlot.Uint256Slot) storage ilksSlot = + _toUint256PointerMapping($.ilkAddresses._inner._positions); + + StorageSlot.Uint256Slot storage ptr = ilksSlot[ilkAddress]; + + uint256 slot; + assembly { + slot := ptr.slot + } + + uint256 value = queryPoolSlot(pool, slot); + return uint8(value) - 1; + } + + /** + * @return The total amount of normalized debt for collateral with index + * `ilkIndex`. + */ + function totalNormalizedDebt(IIonPool pool, uint8 ilkIndex) external view returns (uint256) { + IonPoolStorage storage $ = _getIonPoolStorage(); + IlkSlot0 storage ptr = $.ilks[ilkIndex].slot0; + + uint256 slot; + assembly { + slot := ptr.slot + } + + uint256 value = queryPoolSlot(pool, slot); + + // Truncate to uint104 + return uint104(value); + } + + /** + * @return The `rate` that has been persisted to storage. + */ + function rateUnaccrued(IIonPool pool, uint8 ilkIndex) external view returns (uint256) { + IonPoolStorage storage $ = _getIonPoolStorage(); + IlkSlot0 storage ptr = $.ilks[ilkIndex].slot0; + + uint256 slot; + assembly { + slot := ptr.slot + } + + uint256 value = queryPoolSlot(pool, slot); + value >>= 104; + + return uint104(value); + } + + /** + * @return The timestamp of the last rate update for collateral with index + * `ilkIndex`. + */ + function lastRateUpdate(IIonPool pool, uint8 ilkIndex) external view returns (uint256) { + IonPoolStorage storage $ = _getIonPoolStorage(); + IlkSlot0 storage ptr = $.ilks[ilkIndex].slot0; + + uint256 slot; + assembly { + slot := ptr.slot + } + + uint256 value = queryPoolSlot(pool, slot); + value >>= 104 + 104; + + return uint48(value); + } + + /** + * @return The spot oracle for collateral with index `ilkIndex`. + */ + function spot(IIonPool pool, uint8 ilkIndex) external view returns (address) { + IonPoolStorage storage $ = _getIonPoolStorage(); + StorageSlot.AddressSlot storage ptr = $.ilks[ilkIndex].spot; + + uint256 slot; + assembly { + slot := ptr.slot + } + + uint256 value = queryPoolSlot(pool, slot); + + return address(uint160(value)); + } + + /** + * @return The debt ceiling for collateral with index `ilkIndex`. + */ + function debtCeiling(IIonPool pool, uint8 ilkIndex) external view returns (uint256) { + IonPoolStorage storage $ = _getIonPoolStorage(); + StorageSlot.Uint256Slot storage ptr = $.ilks[ilkIndex].debtCeiling; + + uint256 slot; + assembly { + slot := ptr.slot + } + + uint256 value = queryPoolSlot(pool, slot); + + return value; + } + + /** + * @return The dust value for collateral with index `ilkIndex`. + */ + function dust(IIonPool pool, uint8 ilkIndex) external view returns (uint256) { + IonPoolStorage storage $ = _getIonPoolStorage(); + StorageSlot.Uint256Slot storage ptr = $.ilks[ilkIndex].dust; + + uint256 slot; + assembly { + slot := ptr.slot + } + + uint256 value = queryPoolSlot(pool, slot); + + return value; + } + + /** + * @return Amount of `gem` that `user` has for collateral with index `ilkIndex`. + */ + function gem(IIonPool pool, uint8 ilkIndex, address user) external view returns (uint256) { + IonPoolStorage storage $ = _getIonPoolStorage(); + StorageSlot.Uint256Slot storage ptr = $.gem[ilkIndex][user]; + + uint256 slot; + assembly { + slot := ptr.slot + } + + uint256 value = queryPoolSlot(pool, slot); + return value; + } + + /** + * @return The amount of unbacked debt `user` has. + */ + function unbackedDebt(IIonPool pool, address unbackedDebtor) external view returns (uint256) { + IonPoolStorage storage $ = _getIonPoolStorage(); + StorageSlot.Uint256Slot storage ptr = $.unbackedDebt[unbackedDebtor]; + + uint256 slot; + assembly { + slot := ptr.slot + } + + uint256 value = queryPoolSlot(pool, slot); + return value; + } + + /** + * @return Whether or not `operator` is an `operator` on `user`'s positions. + */ + function isOperator(IIonPool pool, address user, address operator) external view returns (bool) { + IonPoolStorage storage $ = _getIonPoolStorage(); + StorageSlot.Uint256Slot storage ptr = $.isOperator[user][operator]; + + uint256 slot; + assembly { + slot := ptr.slot + } + + uint256 value = queryPoolSlot(pool, slot); + return value != 0; + } + + function debtUnaccrued(IIonPool pool) public view returns (uint256) { + IonPoolStorage storage $ = _getIonPoolStorage(); + StorageSlot.Uint256Slot storage ptr = $.debt; + + uint256 slot; + assembly { + slot := ptr.slot + } + + uint256 value = queryPoolSlot(pool, slot); + return value; + } + + /** + * @dev This includes unbacked debt. + * @return The total amount of debt. + */ + function debt(IIonPool pool) external view returns (uint256) { + (,,, uint256 totalDebtIncrease,) = pool.calculateRewardAndDebtDistribution(); + + return debtUnaccrued(pool) + totalDebtIncrease; + } + + /** + * @return The total amount of ETH liquidity in the pool. + */ + function liquidity(IIonPool pool) external view returns (uint256) { + IonPoolStorage storage $ = _getIonPoolStorage(); + StorageSlot.Uint256Slot storage ptr = $.liquidity; + + uint256 slot; + assembly { + slot := ptr.slot + } + + uint256 value = queryPoolSlot(pool, slot); + return value; + } + + /** + * @return The supply cap + */ + function supplyCap(IIonPool pool) external view returns (uint256) { + IonPoolStorage storage $ = _getIonPoolStorage(); + StorageSlot.Uint256Slot storage ptr = $.supplyCap; + + uint256 slot; + assembly { + slot := ptr.slot + } + + uint256 value = queryPoolSlot(pool, slot); + return value; + } + + /** + * @return The total amount of unbacked debt. + */ + function totalUnbackedDebt(IIonPool pool) external view returns (uint256) { + IonPoolStorage storage $ = _getIonPoolStorage(); + StorageSlot.Uint256Slot storage ptr = $.totalUnbackedDebt; + + uint256 slot; + assembly { + slot := ptr.slot + } + + uint256 value = queryPoolSlot(pool, slot); + return value; + } + + /** + * @return The address of the interest rate module. + */ + function interestRateModule(IIonPool pool) external view returns (address) { + IonPoolStorage storage $ = _getIonPoolStorage(); + StorageSlot.AddressSlot storage ptr = $.interestRateModule; + + uint256 slot; + assembly { + slot := ptr.slot + } + + uint256 value = queryPoolSlot(pool, slot); + return address(uint160(value)); + } + + function whitelist(IIonPool pool) external view returns (address) { + IonPoolStorage storage $ = _getIonPoolStorage(); + StorageSlot.AddressSlot storage ptr = $.whitelist; + + uint256 slot; + assembly { + slot := ptr.slot + } + + uint256 value = queryPoolSlot(pool, slot); + return address(uint160(value)); + } +} diff --git a/src/token/IERC20Errors.sol b/src/token/IERC20Errors.sol new file mode 100644 index 00000000..e0b8011f --- /dev/null +++ b/src/token/IERC20Errors.sol @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.21; + +/** + * @dev Standard ERC20 Errors + * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens. + */ +interface IERC20Errors { + /** + * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + * @param balance Current balance for the interacting account. + * @param needed Minimum amount required to perform a transfer. + */ + error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); + + /** + * @dev Indicates a failure with the token `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + */ + error ERC20InvalidSender(address sender); + + /** + * @dev Indicates a failure with the token `receiver`. Used in transfers. + * @param receiver Address to which tokens are being transferred. + */ + error ERC20InvalidReceiver(address receiver); + + /** + * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. + * @param spender Address that may be allowed to operate on tokens without being their owner. + * @param allowance Amount of tokens a `spender` is allowed to operate with. + * @param needed Minimum amount required to perform a transfer. + */ + error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); + + /** + * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. + * @param approver Address initiating an approval operation. + */ + error ERC20InvalidApprover(address approver); + + /** + * @dev Indicates a failure with the `spender` to be approved. Used in approvals. + * @param spender Address that may be allowed to operate on tokens without being their owner. + */ + error ERC20InvalidSpender(address spender); +} diff --git a/src/reward/RewardModule.sol b/src/token/RewardToken.sol similarity index 52% rename from src/reward/RewardModule.sol rename to src/token/RewardToken.sol index 949c2656..393795f3 100644 --- a/src/reward/RewardModule.sol +++ b/src/token/RewardToken.sol @@ -3,14 +3,18 @@ pragma solidity 0.8.21; import { WadRayMath, RAY } from "../libraries/math/WadRayMath.sol"; +import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; +import { IERC20Errors } from "./IERC20Errors.sol"; import { ContextUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; import { AccessControlDefaultAdminRulesUpgradeable } from "@openzeppelin/contracts-upgradeable/access/extensions/AccessControlDefaultAdminRulesUpgradeable.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import { MessageHashUtils } from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; +import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; /** - * @title RewardModule + * @title RewardToken * @notice The supply-side reward accounting portion of the protocol. A lender's * balance is measured in two parts: a static balance and a dynamic "supply * factor". Their true balance is the product of the two values. The dynamic @@ -18,7 +22,12 @@ import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.s * * @custom:security-contact security@molecularlabs.io */ -abstract contract RewardModule is ContextUpgradeable, AccessControlDefaultAdminRulesUpgradeable { +abstract contract RewardToken is + ContextUpgradeable, + AccessControlDefaultAdminRulesUpgradeable, + IERC20Errors, + IERC20Metadata +{ using WadRayMath for uint256; using SafeERC20 for IERC20; @@ -47,6 +56,22 @@ abstract contract RewardModule is ContextUpgradeable, AccessControlDefaultAdminR */ error InvalidReceiver(address receiver); + /** + * @dev Cannot transfer the token to address `self` + */ + error SelfTransfer(address self); + + /** + * @dev Signature cannot be submitted after `deadline` has passed. Designed to + * mitigate replay attacks. + */ + error ERC2612ExpiredSignature(uint256 deadline); + + /** + * @dev `signer` does not match the `owner` of the tokens. `owner` did not approve. + */ + error ERC2612InvalidSigner(address signer, address owner); + /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param account Address whose token balance is insufficient. @@ -55,20 +80,12 @@ abstract contract RewardModule is ContextUpgradeable, AccessControlDefaultAdminR */ error InsufficientBalance(address account, uint256 balance, uint256 needed); - /** - * @dev Emitted when `value` tokens are moved from one account (`from`) to - * another (`to`). - * - * Note that `value` may be zero. - */ - event Transfer(address indexed from, address indexed to, uint256 value); - event MintToTreasury(address indexed treasury, uint256 amount, uint256 supplyFactor); event TreasuryUpdate(address treasury); - /// @custom:storage-location erc7201:ion.storage.RewardModule - struct RewardModuleStorage { + /// @custom:storage-location erc7201:ion.storage.RewardToken + struct RewardTokenStorage { IERC20 underlying; uint8 decimals; // A user's true balance at any point will be the value in this mapping times the supplyFactor @@ -78,18 +95,26 @@ abstract contract RewardModule is ContextUpgradeable, AccessControlDefaultAdminR uint256 normalizedTotalSupply; // [WAD] uint256 supplyFactor; // [RAY] mapping(address account => uint256) _normalizedBalances; // [WAD] + mapping(address account => mapping(address spender => uint256)) _allowances; + mapping(address account => uint256) nonces; } bytes32 public constant ION = keccak256("ION"); // keccak256(abi.encode(uint256(keccak256("ion.storage.RewardModule")) - 1)) & ~bytes32(uint256(0xff)) // solhint-disable-next-line - bytes32 private constant RewardModuleStorageLocation = + bytes32 private constant RewardTokenStorageLocation = 0xdb3a0d63a7808d7d0422c40bb62354f42bff7602a547c329c1453dbcbeef4900; - function _getRewardModuleStorage() private pure returns (RewardModuleStorage storage $) { + bytes private constant EIP712_REVISION = bytes("1"); + bytes32 private constant EIP712_DOMAIN = + keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); + bytes32 public constant PERMIT_TYPEHASH = + keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); + + function _getRewardTokenStorage() private pure returns (RewardTokenStorage storage $) { assembly { - $.slot := RewardModuleStorageLocation + $.slot := RewardTokenStorageLocation } } @@ -106,7 +131,7 @@ abstract contract RewardModule is ContextUpgradeable, AccessControlDefaultAdminR if (_underlying == address(0)) revert InvalidUnderlyingAddress(); if (_treasury == address(0)) revert InvalidTreasuryAddress(); - RewardModuleStorage storage $ = _getRewardModuleStorage(); + RewardTokenStorage storage $ = _getRewardTokenStorage(); $.underlying = IERC20(_underlying); $.treasury = _treasury; @@ -125,7 +150,7 @@ abstract contract RewardModule is ContextUpgradeable, AccessControlDefaultAdminR * @param amount to burn */ function _burn(address user, address receiverOfUnderlying, uint256 amount) internal returns (uint256) { - RewardModuleStorage storage $ = _getRewardModuleStorage(); + RewardTokenStorage storage $ = _getRewardTokenStorage(); uint256 _supplyFactor = $.supplyFactor; uint256 amountScaled = amount.rayDivUp(_supplyFactor); @@ -146,7 +171,7 @@ abstract contract RewardModule is ContextUpgradeable, AccessControlDefaultAdminR * @param amount of normalized tokens to burn */ function _burnNormalized(address account, uint256 amount) private { - RewardModuleStorage storage $ = _getRewardModuleStorage(); + RewardTokenStorage storage $ = _getRewardTokenStorage(); if (account == address(0)) revert InvalidSender(address(0)); @@ -167,7 +192,7 @@ abstract contract RewardModule is ContextUpgradeable, AccessControlDefaultAdminR * @param amount of reward tokens to mint */ function _mint(address user, address senderOfUnderlying, uint256 amount) internal returns (uint256) { - RewardModuleStorage storage $ = _getRewardModuleStorage(); + RewardTokenStorage storage $ = _getRewardTokenStorage(); uint256 _supplyFactor = $.supplyFactor; uint256 amountScaled = amount.rayDivDown(_supplyFactor); // [WAD] * [RAY] / [RAY] = [WAD] @@ -189,7 +214,7 @@ abstract contract RewardModule is ContextUpgradeable, AccessControlDefaultAdminR function _mintNormalized(address account, uint256 amount) private { if (account == address(0)) revert InvalidReceiver(address(0)); - RewardModuleStorage storage $ = _getRewardModuleStorage(); + RewardTokenStorage storage $ = _getRewardTokenStorage(); $.normalizedTotalSupply += amount; @@ -203,7 +228,7 @@ abstract contract RewardModule is ContextUpgradeable, AccessControlDefaultAdminR function _mintToTreasury(uint256 amount) internal { if (amount == 0) return; - RewardModuleStorage storage $ = _getRewardModuleStorage(); + RewardTokenStorage storage $ = _getRewardTokenStorage(); uint256 _supplyFactor = $.supplyFactor; address _treasury = $.treasury; @@ -219,8 +244,175 @@ abstract contract RewardModule is ContextUpgradeable, AccessControlDefaultAdminR emit MintToTreasury(_treasury, amount, _supplyFactor); } + /** + * + * @param spender to approve + * @param amount to approve + */ + function approve(address spender, uint256 amount) external returns (bool) { + _approve(_msgSender(), spender, amount); + return true; + } + + /** + * + * @param owner of tokens + * @param spender of tokens + * @param amount to approve + */ + function _approve(address owner, address spender, uint256 amount) internal { + if (owner == address(0)) revert ERC20InvalidApprover(address(0)); + if (spender == address(0)) revert ERC20InvalidSpender(address(0)); + + RewardTokenStorage storage $ = _getRewardTokenStorage(); + + $._allowances[owner][spender] = amount; + emit Approval(owner, spender, amount); + } + + /** + * @dev Spends allowance + */ + function _spendAllowance(address owner, address spender, uint256 amount) private { + uint256 currentAllowance = allowance(owner, spender); + if (currentAllowance < amount) { + revert ERC20InsufficientAllowance(spender, currentAllowance, amount); + } + uint256 newAllowance; + // Underflow impossible + unchecked { + newAllowance = currentAllowance - amount; + } + + RewardTokenStorage storage $ = _getRewardTokenStorage(); + + $._allowances[owner][spender] = newAllowance; + } + + /** + * @dev Can only be called by owner of the tokens + * @param to transfer to + * @param amount to transfer + */ + function transfer(address to, uint256 amount) public returns (bool) { + _transfer(_msgSender(), to, amount); + emit Transfer(_msgSender(), to, amount); + return true; + } + + /** + * @dev For use with `approve()` + * @param from to transfer from + * @param to to transfer to + * @param amount to transfer + */ + function transferFrom(address from, address to, uint256 amount) public returns (bool) { + _spendAllowance(from, _msgSender(), amount); + _transfer(from, to, amount); + + emit Transfer(from, to, amount); + return true; + } + + function _transfer(address from, address to, uint256 amount) private { + if (from == address(0)) revert ERC20InvalidSender(address(0)); + if (to == address(0)) revert ERC20InvalidReceiver(address(0)); + if (from == to) revert SelfTransfer(from); + + RewardTokenStorage storage $ = _getRewardTokenStorage(); + + uint256 _supplyFactor = $.supplyFactor; + uint256 amountNormalized = amount.rayDivDown(_supplyFactor); + + uint256 oldSenderBalance = $._normalizedBalances[from]; + if (oldSenderBalance < amountNormalized) { + revert ERC20InsufficientBalance(from, oldSenderBalance, amountNormalized); + } + // Underflow impossible + unchecked { + $._normalizedBalances[from] = oldSenderBalance - amountNormalized; + } + $._normalizedBalances[to] += amountNormalized; + } + + /** + * @dev implements the permit function as for + * https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md + * @param owner The owner of the funds + * @param spender The spender + * @param value The amount + * @param deadline The deadline timestamp, type(uint256).max for max deadline + * @param v Signature param + * @param s Signature param + * @param r Signature param + */ + function permit( + address owner, + address spender, + uint256 value, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) + public + virtual + { + if (block.timestamp > deadline) { + revert ERC2612ExpiredSignature(deadline); + } + + bytes32 structHash = keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline)); + + bytes32 domainSeparator = keccak256( + abi.encode( + EIP712_DOMAIN, keccak256(bytes(name())), keccak256(EIP712_REVISION), block.chainid, address(this) + ) + ); + + bytes32 hash = MessageHashUtils.toTypedDataHash(domainSeparator, structHash); + + address signer = ECDSA.recover(hash, v, r, s); + if (signer != owner) { + revert ERC2612InvalidSigner(signer, owner); + } + + _approve(owner, spender, value); + } + + /** + * @dev Returns current allowance + * @param owner of tokens + * @param spender of tokens + */ + function allowance(address owner, address spender) public view returns (uint256) { + RewardTokenStorage storage $ = _getRewardTokenStorage(); + return $._allowances[owner][spender]; + } + + function nonces(address owner) public view returns (uint256) { + RewardTokenStorage storage $ = _getRewardTokenStorage(); + return $.nonces[owner]; + } + + /** + * @dev Consumes a nonce. + * + * Returns the current value and increments nonce. + */ + function _useNonce(address owner) internal virtual returns (uint256) { + // For each account, the nonce has an initial value of 0, can only be incremented by one, and cannot be + // decremented or reset. This guarantees that the nonce never overflows. + RewardTokenStorage storage $ = _getRewardTokenStorage(); + + unchecked { + // It is important to do x++ and not ++x here. + return $.nonces[owner]++; + } + } + function _setSupplyFactor(uint256 newSupplyFactor) internal { - RewardModuleStorage storage $ = _getRewardModuleStorage(); + RewardTokenStorage storage $ = _getRewardTokenStorage(); $.supplyFactor = newSupplyFactor; } @@ -231,7 +423,7 @@ abstract contract RewardModule is ContextUpgradeable, AccessControlDefaultAdminR function updateTreasury(address newTreasury) external onlyRole(ION) { if (newTreasury == address(0)) revert InvalidTreasuryAddress(); - RewardModuleStorage storage $ = _getRewardModuleStorage(); + RewardTokenStorage storage $ = _getRewardTokenStorage(); $.treasury = newTreasury; emit TreasuryUpdate(newTreasury); @@ -243,7 +435,7 @@ abstract contract RewardModule is ContextUpgradeable, AccessControlDefaultAdminR * @dev Address of underlying asset */ function underlying() public view returns (IERC20) { - RewardModuleStorage storage $ = _getRewardModuleStorage(); + RewardTokenStorage storage $ = _getRewardTokenStorage(); return $.underlying; } @@ -251,28 +443,36 @@ abstract contract RewardModule is ContextUpgradeable, AccessControlDefaultAdminR * @dev Decimals of the position asset */ function decimals() public view returns (uint8) { - RewardModuleStorage storage $ = _getRewardModuleStorage(); + RewardTokenStorage storage $ = _getRewardTokenStorage(); return $.decimals; } /** - * @dev Current token balance + * @dev Current claim of the underlying token inclusive of interest to be accrued. * @param user to get balance of */ function balanceOf(address user) public view returns (uint256) { - RewardModuleStorage storage $ = _getRewardModuleStorage(); + RewardTokenStorage storage $ = _getRewardTokenStorage(); (uint256 totalSupplyFactorIncrease,,,,) = calculateRewardAndDebtDistribution(); return $._normalizedBalances[user].rayMulDown($.supplyFactor + totalSupplyFactorIncrease); } + /** + * @dev Current claim of the underlying token without accounting for interest to be accrued. + */ + function balanceOfUnaccrued(address user) public view returns (uint256) { + RewardTokenStorage storage $ = _getRewardTokenStorage(); + return $._normalizedBalances[user].rayMulDown($.supplyFactor); + } + /** * @dev Accounting is done in normalized balances * @param user to get normalized balance of */ function normalizedBalanceOf(address user) external view returns (uint256) { - RewardModuleStorage storage $ = _getRewardModuleStorage(); + RewardTokenStorage storage $ = _getRewardTokenStorage(); return $._normalizedBalances[user]; } @@ -280,7 +480,7 @@ abstract contract RewardModule is ContextUpgradeable, AccessControlDefaultAdminR * @dev Name of the position asset */ function name() public view returns (string memory) { - RewardModuleStorage storage $ = _getRewardModuleStorage(); + RewardTokenStorage storage $ = _getRewardTokenStorage(); return $.name; } @@ -288,7 +488,7 @@ abstract contract RewardModule is ContextUpgradeable, AccessControlDefaultAdminR * @dev Symbol of the position asset */ function symbol() public view returns (string memory) { - RewardModuleStorage storage $ = _getRewardModuleStorage(); + RewardTokenStorage storage $ = _getRewardTokenStorage(); return $.symbol; } @@ -296,12 +496,15 @@ abstract contract RewardModule is ContextUpgradeable, AccessControlDefaultAdminR * @dev Current treasury address */ function treasury() public view returns (address) { - RewardModuleStorage storage $ = _getRewardModuleStorage(); + RewardTokenStorage storage $ = _getRewardTokenStorage(); return $.treasury; } + /** + * @dev Total claim of the underlying asset belonging to lenders not inclusive of the new interest to be accrued. + */ function totalSupplyUnaccrued() public view returns (uint256) { - RewardModuleStorage storage $ = _getRewardModuleStorage(); + RewardTokenStorage storage $ = _getRewardTokenStorage(); uint256 _normalizedTotalSupply = $.normalizedTotalSupply; @@ -313,10 +516,10 @@ abstract contract RewardModule is ContextUpgradeable, AccessControlDefaultAdminR } /** - * @dev Current total supply + * @dev Total claim of the underlying asset belonging to lender inclusive of the new interest to be accrued. */ function totalSupply() public view returns (uint256) { - RewardModuleStorage storage $ = _getRewardModuleStorage(); + RewardTokenStorage storage $ = _getRewardTokenStorage(); uint256 _normalizedTotalSupply = $.normalizedTotalSupply; @@ -324,21 +527,21 @@ abstract contract RewardModule is ContextUpgradeable, AccessControlDefaultAdminR return 0; } - (uint256 totalSupplyFactorIncrease,,,,) = calculateRewardAndDebtDistribution(); + (uint256 totalSupplyFactorIncrease, uint256 totalTreasuryMintAmount,,,) = calculateRewardAndDebtDistribution(); - return _normalizedTotalSupply.rayMulDown($.supplyFactor + totalSupplyFactorIncrease); + return _normalizedTotalSupply.rayMulDown($.supplyFactor + totalSupplyFactorIncrease) + totalTreasuryMintAmount; } function normalizedTotalSupplyUnaccrued() public view returns (uint256) { - RewardModuleStorage storage $ = _getRewardModuleStorage(); + RewardTokenStorage storage $ = _getRewardTokenStorage(); return $.normalizedTotalSupply; } /** - * @dev Current normalized total supply + * @dev Normalized total supply. */ function normalizedTotalSupply() public view returns (uint256) { - RewardModuleStorage storage $ = _getRewardModuleStorage(); + RewardTokenStorage storage $ = _getRewardTokenStorage(); (uint256 totalSupplyFactorIncrease, uint256 totalTreasuryMintAmount,,,) = calculateRewardAndDebtDistribution(); @@ -349,7 +552,7 @@ abstract contract RewardModule is ContextUpgradeable, AccessControlDefaultAdminR } function supplyFactorUnaccrued() public view returns (uint256) { - RewardModuleStorage storage $ = _getRewardModuleStorage(); + RewardTokenStorage storage $ = _getRewardTokenStorage(); return $.supplyFactor; } @@ -357,7 +560,7 @@ abstract contract RewardModule is ContextUpgradeable, AccessControlDefaultAdminR * @dev Current supply factor */ function supplyFactor() public view returns (uint256) { - RewardModuleStorage storage $ = _getRewardModuleStorage(); + RewardTokenStorage storage $ = _getRewardTokenStorage(); (uint256 totalSupplyFactorIncrease,,,,) = calculateRewardAndDebtDistribution(); diff --git a/src/vault/Vault.sol b/src/vault/Vault.sol new file mode 100644 index 00000000..b4854dd8 --- /dev/null +++ b/src/vault/Vault.sol @@ -0,0 +1,1042 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity 0.8.21; + +import { IIonPool } from "./../interfaces/IIonPool.sol"; +import { IIonPool } from "./../interfaces/IIonPool.sol"; +import { RAY } from "./../libraries/math/WadRayMath.sol"; + +import { IERC20Metadata } from "@openzeppelin/contracts/interfaces/IERC20Metadata.sol"; +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { ERC4626 } from "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol"; +import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import { Math } from "@openzeppelin/contracts/utils/math/Math.sol"; +import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import { Multicall } from "@openzeppelin/contracts/utils/Multicall.sol"; +import { ReentrancyGuard } from "openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol"; +import { AccessControlDefaultAdminRules } from + "@openzeppelin/contracts/access/extensions/AccessControlDefaultAdminRules.sol"; + +// solhint-disable-next-line no-unused-import +import { IERC4626 } from "@openzeppelin/contracts/interfaces/IERC4626.sol"; + +/** + * @title Ion Lending Vault + * @author Molecular Labs + * @notice Vault contract that can allocate a single lender asset over various + * isolated lending pairs on Ion Protocol. This contract is a fork of the + * Metamorpho contract licnesed under GPL-2.0 with changes to administrative + * logic, underlying data structures, and lending interactions to be made + * compatible with Ion Protocol. + * + * @custom:security-contact security@molecularlabs.io + */ +contract Vault is ERC4626, Multicall, AccessControlDefaultAdminRules, ReentrancyGuard { + using EnumerableSet for EnumerableSet.AddressSet; + using Math for uint256; + + error InvalidQueueLength(uint256 queueLength, uint256 supportedMarketsLength); + error AllocationCapExceeded(uint256 resultingSupplied, uint256 allocationCap); + error InvalidReallocation(uint256 totalSupplied, uint256 totalWithdrawn); + error InvalidMarketRemovalNonZeroSupply(IIonPool pool); + error InvalidUnderlyingAsset(IIonPool pool); + error MarketAlreadySupported(IIonPool pool); + error MarketNotSupported(IIonPool pool); + error AllSupplyCapsReached(); + error NotEnoughLiquidityToWithdraw(); + error InvalidIdleMarketRemovalNonZeroBalance(); + error InvalidQueueContainsDuplicates(); + error MarketsAndAllocationCapLengthMustBeEqual(); + error IonPoolsArrayAndNewCapsArrayMustBeOfEqualLength(); + error InvalidFeePercentage(); + error MaxSupportedMarketsReached(); + + event UpdateSupplyQueue(address indexed caller, IIonPool[] newSupplyQueue); + event UpdateWithdrawQueue(address indexed caller, IIonPool[] newWithdrawQueue); + + event ReallocateWithdraw(IIonPool indexed pool, uint256 assets); + event ReallocateSupply(IIonPool indexed pool, uint256 assets); + event FeeAccrued(uint256 feeShares, uint256 newTotalAssets); + event UpdateLastTotalAssets(uint256 lastTotalAssets, uint256 newLastTotalAssets); + + bytes32 public constant OWNER_ROLE = keccak256("OWNER_ROLE"); + bytes32 public constant ALLOCATOR_ROLE = keccak256("ALLOCATOR_ROLE"); + + IIonPool public constant IDLE = IIonPool(address(uint160(uint256(keccak256("IDLE_ASSET_HOLDINGS"))))); + + uint8 public immutable DECIMALS_OFFSET; + + bytes32 public immutable ION_POOL_SUPPLY_CAP_SLOT = + 0xceba3d526b4d5afd91d1b752bf1fd37917c20a6daf576bcb41dd1c57c1f67e09; + bytes32 public immutable ION_POOL_LIQUIDITY_SLOT = + 0xceba3d526b4d5afd91d1b752bf1fd37917c20a6daf576bcb41dd1c57c1f67e08; + + IERC20 public immutable BASE_ASSET; + + uint8 public constant MAX_SUPPORTED_MARKETS = 32; + + EnumerableSet.AddressSet supportedMarkets; + + IIonPool[] public supplyQueue; + IIonPool[] public withdrawQueue; + + address public feeRecipient; + uint256 public feePercentage; // [RAY] + + uint256 public lastTotalAssets; + + mapping(IIonPool => uint256) public caps; + + struct MarketAllocation { + IIonPool pool; + int256 assets; + } + + struct MarketsArgs { + IIonPool[] marketsToAdd; + uint256[] allocationCaps; + IIonPool[] newSupplyQueue; + IIonPool[] newWithdrawQueue; + } + + constructor( + IERC20 _baseAsset, + address _feeRecipient, + uint256 _feePercentage, + string memory _name, + string memory _symbol, + uint48 initialDelay, + address initialDefaultAdmin, + MarketsArgs memory marketsArgs + ) + ERC4626(_baseAsset) + ERC20(_name, _symbol) + AccessControlDefaultAdminRules(initialDelay, initialDefaultAdmin) + { + BASE_ASSET = _baseAsset; + + feePercentage = _feePercentage; + feeRecipient = _feeRecipient; + + DECIMALS_OFFSET = uint8(_zeroFloorSub(uint256(18), IERC20Metadata(address(_baseAsset)).decimals())); + + _addSupportedMarkets( + marketsArgs.marketsToAdd, + marketsArgs.allocationCaps, + marketsArgs.newSupplyQueue, + marketsArgs.newWithdrawQueue + ); + } + + /** + * @notice Updates the fee percentage. + * @dev Input must be in [RAY]. Ex) 2% would be 0.02e27. + * @param _feePercentage The percentage of the interest accrued to take as a + * management fee. + */ + function updateFeePercentage(uint256 _feePercentage) external onlyRole(OWNER_ROLE) { + if (_feePercentage > RAY) revert InvalidFeePercentage(); + _accrueFee(); + feePercentage = _feePercentage; + } + + /** + * @notice Updates the fee recipient. + * @param _feeRecipient The recipient address of the shares minted as fees. + */ + function updateFeeRecipient(address _feeRecipient) external onlyRole(OWNER_ROLE) { + feeRecipient = _feeRecipient; + } + + /** + * @notice Add markets that can be supplied and withdrawn from. + * @dev Elements in `supportedMarkets` must be a valid IonPool or an IDLE + * address. Valid IonPools require the base asset to be the same. Duplicate + * addition to the EnumerableSet will revert. The allocationCaps of the + * new markets being introduced must be set. + * @param marketsToAdd Array of new markets to be added. + * @param allocationCaps Array of allocation caps for only the markets to be added. + * @param newSupplyQueue Desired supply queue of IonPools for all resulting supported markets. + * @param newWithdrawQueue Desired withdraw queue of IonPools for all resulting supported markets. + */ + function addSupportedMarkets( + IIonPool[] memory marketsToAdd, + uint256[] memory allocationCaps, + IIonPool[] memory newSupplyQueue, + IIonPool[] memory newWithdrawQueue + ) + external + onlyRole(OWNER_ROLE) + { + _addSupportedMarkets(marketsToAdd, allocationCaps, newSupplyQueue, newWithdrawQueue); + } + + function _addSupportedMarkets( + IIonPool[] memory marketsToAdd, + uint256[] memory allocationCaps, + IIonPool[] memory newSupplyQueue, + IIonPool[] memory newWithdrawQueue + ) + internal + { + if (marketsToAdd.length != allocationCaps.length) revert MarketsAndAllocationCapLengthMustBeEqual(); + + for (uint256 i; i != marketsToAdd.length;) { + IIonPool pool = marketsToAdd[i]; + + if (pool != IDLE) { + if (address(pool.underlying()) != address(BASE_ASSET)) { + revert InvalidUnderlyingAsset(pool); + } + BASE_ASSET.approve(address(pool), type(uint256).max); + } + + if (!supportedMarkets.add(address(pool))) revert MarketAlreadySupported(pool); + + caps[pool] = allocationCaps[i]; + + unchecked { + ++i; + } + } + + if (supportedMarkets.length() > MAX_SUPPORTED_MARKETS) revert MaxSupportedMarketsReached(); + + _updateSupplyQueue(newSupplyQueue); + _updateWithdrawQueue(newWithdrawQueue); + } + + /** + * @notice Removes a supported market and updates the supply and withdraw + * queues without the removed market. + * @dev The allocationCap values of the markets being removed are + * automatically deleted. Whenever a market is removed, the queues must be + * updated without the removed market. + * @param marketsToRemove Markets being removed. + * @param newSupplyQueue Desired supply queue of all supported markets after + * the removal. + * @param newWithdrawQueue Desired withdraw queue of all supported markets + * after the removal. + */ + function removeSupportedMarkets( + IIonPool[] calldata marketsToRemove, + IIonPool[] calldata newSupplyQueue, + IIonPool[] calldata newWithdrawQueue + ) + external + onlyRole(OWNER_ROLE) + { + for (uint256 i; i != marketsToRemove.length;) { + IIonPool pool = marketsToRemove[i]; + + if (pool == IDLE) { + if (BASE_ASSET.balanceOf(address(this)) != 0) revert InvalidIdleMarketRemovalNonZeroBalance(); + } else { + // Checks `normalizedBalanceOf` as it may be possible that + // `balanceOf` returns zero even though the + // `normalizedBalance` is zero. + if (pool.normalizedBalanceOf(address(this)) != 0) revert InvalidMarketRemovalNonZeroSupply(pool); + BASE_ASSET.approve(address(pool), 0); + } + + if (!supportedMarkets.remove(address(pool))) revert MarketNotSupported(pool); + delete caps[pool]; + + unchecked { + ++i; + } + } + _updateSupplyQueue(newSupplyQueue); + _updateWithdrawQueue(newWithdrawQueue); + } + + /** + * @notice Update the order of the markets in which user deposits are supplied. + * @dev Each IonPool in the queue must be part of the `supportedMarkets` set. + * @param newSupplyQueue The new supply queue ordering. + */ + function updateSupplyQueue(IIonPool[] memory newSupplyQueue) external onlyRole(ALLOCATOR_ROLE) { + _updateSupplyQueue(newSupplyQueue); + } + + function _updateSupplyQueue(IIonPool[] memory newSupplyQueue) internal { + _validateQueueInput(newSupplyQueue); + + supplyQueue = newSupplyQueue; + + emit UpdateSupplyQueue(_msgSender(), newSupplyQueue); + } + + /** + * @notice Update the order of the markets in which the deposits are withdrawn. + * @dev The IonPool in the queue must be part of the `supportedMarkets` set. + * @param newWithdrawQueue The new withdraw queue ordering. + */ + function updateWithdrawQueue(IIonPool[] memory newWithdrawQueue) external onlyRole(ALLOCATOR_ROLE) { + _updateWithdrawQueue(newWithdrawQueue); + } + + function _updateWithdrawQueue(IIonPool[] memory newWithdrawQueue) internal { + _validateQueueInput(newWithdrawQueue); + + withdrawQueue = newWithdrawQueue; + + emit UpdateWithdrawQueue(_msgSender(), newWithdrawQueue); + } + + /** + * @dev The input array contains ordered IonPools. + * - Must not contain duplicates. + * - Must be the same length as the `supportedMarkets` array. + * - Must not contain indices that are out of bounds of the `supportedMarkets` EnumerableSet's underlying array. + * The above rule enforces that the queue must have all and only the elements in the `supportedMarkets` set. + * @param queue The queue being validated. + */ + function _validateQueueInput(IIonPool[] memory queue) internal view { + uint256 _supportedMarketsLength = supportedMarkets.length(); + uint256 queueLength = queue.length; + + if (queueLength != _supportedMarketsLength) revert InvalidQueueLength(queueLength, _supportedMarketsLength); + + bool[] memory seen = new bool[](queueLength); + + for (uint256 i; i != queueLength;) { + // If the pool is not supported, this query reverts. + uint256 index = _supportedMarketsIndexOf(address(queue[i])); + + if (seen[index] == true) revert InvalidQueueContainsDuplicates(); + + seen[index] = true; + + unchecked { + ++i; + } + } + } + + /** + * @notice Update allocation caps for specified IonPools or the IDLE pool. + * @dev The allocation caps are applied to pools in the order of the array + * within `supportedMarkets`. The elements inside `ionPools` must exist in + * `supportedMarkets`. To update the `IDLE` pool, use the `IDLE` constant + * address. + * @param ionPools The array of IonPools whose caps will be updated. + * @param newCaps The array of new allocation caps to be applied. + */ + function updateAllocationCaps( + IIonPool[] calldata ionPools, + uint256[] calldata newCaps + ) + external + onlyRole(OWNER_ROLE) + { + if (ionPools.length != newCaps.length) revert IonPoolsArrayAndNewCapsArrayMustBeOfEqualLength(); + + for (uint256 i; i != ionPools.length;) { + IIonPool pool = ionPools[i]; + if (!supportedMarkets.contains(address(pool))) revert MarketNotSupported(pool); + caps[pool] = newCaps[i]; + + unchecked { + ++i; + } + } + } + + /** + * @notice Reallocates the base asset supply position across the specified + * IonPools. This call will revert if the resulting allocation in an IonPool + * violates the pool's supply cap. + * @dev Depending on the order of deposits and withdrawals to and from + * markets, the function could revert if there is not enough assets + * withdrawn to deposit later in the loop. A key invariant is that the total + * assets withdrawn should be equal to the total assets supplied. Otherwise, + * revert. + * - Negative value indicates a withdrawal. + * - Positive value indicates a supply. + * @param allocations Array that indicates how much to deposit or withdraw + * from each market. + */ + function reallocate(MarketAllocation[] calldata allocations) external onlyRole(ALLOCATOR_ROLE) nonReentrant { + uint256 totalSupplied; + uint256 totalWithdrawn; + + uint256 currentIdleDeposits = BASE_ASSET.balanceOf(address(this)); + for (uint256 i; i != allocations.length;) { + MarketAllocation calldata allocation = allocations[i]; + IIonPool pool = allocation.pool; + + uint256 currentSupplied = pool == IDLE ? currentIdleDeposits : pool.balanceOf(address(this)); + int256 assets = allocation.assets; // to deposit or withdraw + + // if `assets` is `type(int256).min`, this means fully withdraw from the market. + // This prevents frontrunning in case the market needs to be fully withdrawn + // from in order to remove the market. + uint256 transferAmt; + if (assets < 0) { + if (assets == type(int256).min) { + // The resulting shares from full withdraw must be zero. + transferAmt = currentSupplied; + } else { + transferAmt = uint256(-assets); + } + + // If `IDLE`, the asset is already held by this contract, no + // need to withdraw from a pool. The asset will be transferred + // to the user from the previous function scope. + if (pool != IDLE) { + pool.withdraw(address(this), transferAmt); + } else { + currentIdleDeposits -= transferAmt; + } + + totalWithdrawn += transferAmt; + + emit ReallocateWithdraw(pool, transferAmt); + } else if (assets > 0) { + // It is not possible to predict the exact amount of assets that + // will be withdrawn when using the `type(int256).min` indicator + // in previous iterations of the loop due to the per-second + // interest rate accrual. Therefore, the `max` indicator is + // necessary to be able to fully deposit the total withdrawn + // amount. + if (assets == type(int256).max) { + transferAmt = totalWithdrawn; + } else { + transferAmt = uint256(assets); + } + + uint256 resultingSupplied = currentSupplied + transferAmt; + uint256 allocationCap = caps[pool]; + if (resultingSupplied > allocationCap) { + revert AllocationCapExceeded(resultingSupplied, allocationCap); + } + + // If the assets are being deposited to IDLE, then no need for + // additional transfers as the balance is already in this + // contract. + if (pool != IDLE) { + pool.supply(address(this), transferAmt, new bytes32[](0)); + } else { + currentIdleDeposits += transferAmt; + } + + totalSupplied += transferAmt; + + emit ReallocateSupply(pool, transferAmt); + } + + unchecked { + ++i; + } + } + + if (totalSupplied != totalWithdrawn) revert InvalidReallocation(totalSupplied, totalWithdrawn); + } + + /** + * @notice Manually accrues fees and mints shares to the fee recipient. + */ + function accrueFee() external onlyRole(OWNER_ROLE) returns (uint256 newTotalAssets) { + return _accrueFee(); + } + + // --- IonPool Interactions --- + + /** + * @notice Iterates through the supply queue to deposit the desired amount + * of assets. Reverts if the deposit amount cannot be filled due to the + * allocation cap or the supply cap. + * @dev External functions calling this must be non-reentrant in case the + * underlying IonPool implements callback logic. + * @param assets The amount of assets that will attempt to be supplied. + */ + function _supplyToIonPool(uint256 assets) internal { + // This function is called after the `BASE_ASSET` is transferred to the + // contract for the supply iterations. The `assets` is subtracted to + // retrieve the `BASE_ASSET` balance before this transaction began. + uint256 currentIdleDeposits = BASE_ASSET.balanceOf(address(this)) - assets; + uint256 supplyQueueLength = supplyQueue.length; + + for (uint256 i; i != supplyQueueLength;) { + IIonPool pool = supplyQueue[i]; + + uint256 depositable = pool == IDLE ? _zeroFloorSub(caps[pool], currentIdleDeposits) : _depositable(pool); + + if (depositable != 0) { + uint256 toSupply = Math.min(depositable, assets); + + // For the IDLE pool, decrement the accumulator at the end of this + // loop, but no external interactions need to be made as the assets + // are already on this contract' balance. If the pool supply + // reverts, simply skip to the next iteration. + if (pool != IDLE) { + try pool.supply(address(this), toSupply, new bytes32[](0)) { + assets -= toSupply; + // solhint-disable-next-line no-empty-blocks + } catch { } + } else { + assets -= toSupply; + } + + if (assets == 0) return; + } + + unchecked { + ++i; + } + } + if (assets != 0) revert AllSupplyCapsReached(); + } + + /** + * @notice Iterates through the withdraw queue to withdraw the desired + * amount of assets. Will revert if there is not enough liquidity or if + * trying to withdraw more than the caller owns. + * @dev External functions calling this must be non-reentrant in case the + * underlying IonPool implements callback logic. + * @param assets The desired amount of assets to be withdrawn. + */ + function _withdrawFromIonPool(uint256 assets) internal { + uint256 currentIdleDeposits = BASE_ASSET.balanceOf(address(this)); + uint256 withdrawQueueLength = withdrawQueue.length; + + for (uint256 i; i != withdrawQueueLength;) { + IIonPool pool = withdrawQueue[i]; + + uint256 withdrawable = pool == IDLE ? currentIdleDeposits : _withdrawable(pool); + + if (withdrawable != 0) { + uint256 toWithdraw = Math.min(withdrawable, assets); + + // For the `IDLE` pool, they are already on this contract's + // balance. Update `assets` accumulator but don't actually + // transfer. If the pool withdraw reverts, simply skip to the + // next iteration. + if (pool != IDLE) { + try pool.withdraw(address(this), toWithdraw) { + assets -= toWithdraw; + // solhint-disable-next-line no-empty-blocks + } catch { } + } else { + assets -= toWithdraw; + } + + if (assets == 0) return; + } + + unchecked { + ++i; + } + } + + if (assets != 0) revert NotEnoughLiquidityToWithdraw(); + } + + // --- ERC4626 External Functions --- + + /** + * @inheritdoc IERC4626 + * @notice Transfers the specified amount of assets from the sender, + * supplies into the underlying + * IonPool markets, and mints a corresponding amount of shares. + * @dev All incoming deposits are deposited in the order specified in the deposit queue. + * @param assets Amount of tokens to be deposited. + * @param receiver The address to receive the minted shares. + */ + function deposit(uint256 assets, address receiver) public override nonReentrant returns (uint256 shares) { + uint256 newTotalAssets = _accrueFee(); + + shares = _convertToSharesWithTotals(assets, totalSupply(), newTotalAssets, Math.Rounding.Floor); + _deposit(_msgSender(), receiver, assets, shares); + } + + /** + * @inheritdoc IERC4626 + * @notice Mints the specified amount of shares and deposits a corresponding + * amount of assets. + * @dev Converts the shares to assets and iterates through the deposit queue + * to allocate the deposit across the supported markets. + * @param shares The exact amount of shares to be minted. + * @param receiver The address to receive the minted shares. + */ + function mint(uint256 shares, address receiver) public override nonReentrant returns (uint256 assets) { + uint256 newTotalAssets = _accrueFee(); + + // This is updated again with the deposited assets amount in `_deposit`. + lastTotalAssets = newTotalAssets; + + assets = _convertToAssetsWithTotals(shares, totalSupply(), newTotalAssets, Math.Rounding.Ceil); + + _deposit(_msgSender(), receiver, assets, shares); + } + + /** + * @notice Withdraws specified amount of assets from IonPools and sends them + * to the receiver in exchange for burning the owner's vault shares. + * @dev All withdraws are withdrawn in the order specified in the withdraw + * queue. The owner needs to approve the caller to spend their shares. + * @param assets The exact amount of assets to be transferred out. + * @param receiver The receiver of the assets transferred. + * @param owner The owner of the vault shares. + */ + function withdraw( + uint256 assets, + address receiver, + address owner + ) + public + override + nonReentrant + returns (uint256 shares) + { + uint256 newTotalAssets = _accrueFee(); + shares = _convertToSharesWithTotals(assets, totalSupply(), newTotalAssets, Math.Rounding.Ceil); + _updateLastTotalAssets(_zeroFloorSub(newTotalAssets, assets)); + + _withdraw(_msgSender(), receiver, owner, assets, shares); + } + + /** + * @inheritdoc IERC4626 + * @notice Redeems the exact amount of shares and receives a corresponding + * amount of assets. + * @dev After withdrawing `assets`, the user gets exact `assets` out. But in + * the IonPool, the resulting total underlying claim may have decreased + * by a bit above the `assets` amount due to rounding in the pool's favor. + * + * In that case, the resulting `totalAssets()` will be smaller than just + * the `newTotalAssets - assets`. Predicting the exact resulting + * totalAssets() requires knowing how much liquidity is being withdrawn + * from each pool, which is not possible to know until the actual + * iteration on the withdraw queue. So we acknowledge the dust + * difference here. + * + * If the `lastTotalAssets` is slightly greater than the actual `totalAssets`, + * the impact will be that the calculated interest accrued during fee distribution will be slightly less than the + * true value. + * @param shares The exact amount of shares to be burned and redeemed. + * @param receiver The address that receives the transferred assets. + * @param owner The address that holds the shares to be redeemed. + */ + function redeem( + uint256 shares, + address receiver, + address owner + ) + public + override + nonReentrant + returns (uint256 assets) + { + uint256 newTotalAssets = _accrueFee(); + + assets = _convertToAssetsWithTotals(shares, totalSupply(), newTotalAssets, Math.Rounding.Floor); + + _updateLastTotalAssets(newTotalAssets - assets); + + _withdraw(_msgSender(), receiver, owner, assets, shares); + } + + /** + * @inheritdoc IERC20Metadata + */ + function decimals() public view override(ERC4626) returns (uint8) { + return ERC4626.decimals(); + } + + /** + * @inheritdoc IERC4626 + * @notice Returns the maximum amount of assets that the vault can supply on + * Ion. + * @dev The max deposit amount is limited by the vault's allocation cap and + * the underlying IonPools' supply caps. + * @return The max amount of assets that can be supplied. + */ + function maxDeposit(address) public view override returns (uint256) { + return _maxDeposit(); + } + + /** + * @inheritdoc IERC4626 + * @notice Returns the maximum amount of vault shares that can be minted. + * @dev Max mint is limited by the max deposit based on the Vault's + * allocation caps and the IonPools' supply caps. The conversion from max + * suppliable assets to shares preempts the shares minted from fee accrual. + * @return The max amount of shares that can be minted. + */ + function maxMint(address) public view override returns (uint256) { + uint256 suppliable = _maxDeposit(); + + return _convertToSharesWithFees(suppliable, Math.Rounding.Floor); + } + + /** + * @inheritdoc IERC4626 + * @notice Returns the maximum amount of assets that can be withdrawn. + * @dev Max withdraw is limited by the owner's shares and the liquidity + * available to be withdrawn from the underlying IonPools. The max + * withdrawable claim is inclusive of accrued interest and the extra shares + * minted to the fee recipient. + * @param owner The address that holds the assets. + * @return assets The max amount of assets that can be withdrawn. + */ + function maxWithdraw(address owner) public view override returns (uint256 assets) { + (assets,,) = _maxWithdraw(owner); + } + + /** + * @inheritdoc IERC4626 + * @notice Calculates the total withdrawable amount based on the available + * liquidity in the underlying pools and converts it to redeemable shares. + * @dev Max redeem is derived from çonverting the `_maxWithdraw` to shares. + * The conversion takes into account the total supply and total assets + * inclusive of accrued interest and the extra shares minted to the fee + * recipient. + * @param owner The address that holds the shares. + * @return The max amount of shares that can be withdrawn. + */ + function maxRedeem(address owner) public view override returns (uint256) { + (uint256 assets, uint256 newTotalSupply, uint256 newTotalAssets) = _maxWithdraw(owner); + return _convertToSharesWithTotals(assets, newTotalSupply, newTotalAssets, Math.Rounding.Floor); + } + + /** + * @notice Returns the total claim that the vault has across all supported IonPools. + * @dev `IonPool.balanceOf` returns the rebasing balance of the + * lender receipt token that is pegged 1:1 to the underlying supplied asset. + * @return assets The total assets held on the contract and inside the underlying + * pools by this vault. + */ + function totalAssets() public view override returns (uint256 assets) { + uint256 _supportedMarketsLength = supportedMarkets.length(); + for (uint256 i; i != _supportedMarketsLength;) { + IIonPool pool = IIonPool(supportedMarkets.at(i)); + + uint256 assetsInPool = pool == IDLE ? BASE_ASSET.balanceOf(address(this)) : pool.balanceOf(address(this)); + + assets += assetsInPool; + + unchecked { + ++i; + } + } + } + + /** + * @inheritdoc IERC4626 + * @dev Inclusive of manager fee. + */ + function previewDeposit(uint256 assets) public view override returns (uint256) { + return _convertToSharesWithFees(assets, Math.Rounding.Floor); + } + + /** + * @inheritdoc IERC4626 + * @dev Inclusive of manager fee. + */ + function previewMint(uint256 shares) public view override returns (uint256) { + return _convertToAssetsWithFees(shares, Math.Rounding.Ceil); + } + + /** + * @inheritdoc IERC4626 + * @dev Inclusive of manager fee. + */ + function previewWithdraw(uint256 assets) public view override returns (uint256) { + return _convertToSharesWithFees(assets, Math.Rounding.Ceil); + } + + /** + * @inheritdoc IERC4626 + * @dev Inclusive of manager fee. + */ + function previewRedeem(uint256 shares) public view override returns (uint256) { + return _convertToAssetsWithFees(shares, Math.Rounding.Floor); + } + + // --- ERC4626 Internal Functions --- + + function _decimalsOffset() internal view override returns (uint8) { + return DECIMALS_OFFSET; + } + + function _deposit(address caller, address receiver, uint256 assets, uint256 shares) internal override { + super._deposit(caller, receiver, assets, shares); + _supplyToIonPool(assets); + _updateLastTotalAssets(lastTotalAssets + assets); + } + + function _withdraw( + address caller, + address receiver, + address owner, + uint256 assets, + uint256 shares + ) + internal + override + { + _withdrawFromIonPool(assets); + + super._withdraw(caller, receiver, owner, assets, shares); + } + + function _maxDeposit() internal view returns (uint256 maxDepositable) { + for (uint256 i; i != supportedMarkets.length();) { + IIonPool pool = IIonPool(supportedMarkets.at(i)); + + uint256 depositable = + pool == IDLE ? _zeroFloorSub(caps[pool], BASE_ASSET.balanceOf(address(this))) : _depositable(pool); + + maxDepositable += depositable; + + unchecked { + ++i; + } + } + } + + function _maxWithdraw(address owner) + internal + view + returns (uint256 assets, uint256 newTotalSupply, uint256 newTotalAssets) + { + uint256 feeShares; + (feeShares, newTotalAssets) = _accruedFeeShares(); + newTotalSupply = totalSupply() + feeShares; + + uint256 shareBalances = balanceOf(owner); + if (owner == feeRecipient) { + shareBalances += feeShares; + } + + assets = _convertToAssetsWithTotals(shareBalances, newTotalSupply, newTotalAssets, Math.Rounding.Floor); + + assets -= _simulateWithdrawIon(assets); + } + + // --- Internal --- + + function _accrueFee() internal returns (uint256 newTotalAssets) { + uint256 feeShares; + (feeShares, newTotalAssets) = _accruedFeeShares(); + if (feeShares != 0) _mint(feeRecipient, feeShares); + + lastTotalAssets = newTotalAssets; + + emit FeeAccrued(feeShares, newTotalAssets); + } + + /** + * @dev The total accrued vault revenue is the difference in the total + * iToken holdings from the last accrued timestamp and now. + */ + function _accruedFeeShares() internal view returns (uint256 feeShares, uint256 newTotalAssets) { + newTotalAssets = totalAssets(); + uint256 totalInterest = _zeroFloorSub(newTotalAssets, lastTotalAssets); + + // The new amount of new iTokens that were created for this vault. A + // portion of this should be claimable by depositors and some portion of + // this should be claimable by the fee recipient. + if (totalInterest != 0 && feePercentage != 0) { + uint256 feeAssets = totalInterest.mulDiv(feePercentage, RAY); + + feeShares = + _convertToSharesWithTotals(feeAssets, totalSupply(), newTotalAssets - feeAssets, Math.Rounding.Floor); + } + } + + /** + * @dev NOTE The IERC4626 natspec recommends that the `_convertToAssets` and `_convertToShares` "MUST NOT be + * inclusive of any fees that are charged against assets in the Vault." + * However, all deposit/mint/withdraw/redeem flow will accrue fees before + * processing user requests, so manager fee must be accounted for to accurately reflect the resulting state. + * All preview functions will rely on this `WithFees` version of the `_convertTo` function. + */ + function _convertToSharesWithFees(uint256 assets, Math.Rounding rounding) internal view returns (uint256) { + (uint256 feeShares, uint256 newTotalAssets) = _accruedFeeShares(); + + return _convertToSharesWithTotals(assets, totalSupply() + feeShares, newTotalAssets, rounding); + } + + /** + * @dev NOTE The IERC4626 natspec recommends that the `_convertToAssets` and `_convertToShares` "MUST NOT be + * inclusive of any fees that are charged against assets in the Vault." + * However, all deposit/mint/withdraw/redeem flow will accrue fees before + * processing user requests, so manager fee must be accounted for to accurately reflect the resulting state. + * All preview functions will rely on this `WithFees` version of the `_convertTo` function. + */ + function _convertToAssetsWithFees(uint256 shares, Math.Rounding rounding) internal view returns (uint256) { + (uint256 feeShares, uint256 newTotalAssets) = _accruedFeeShares(); + + return _convertToAssetsWithTotals(shares, totalSupply() + feeShares, newTotalAssets, rounding); + } + + /** + * @dev Returns the amount of shares that the vault would exchange for the + * amount of `assets` provided. This function is used to calculate the + * conversion between shares and assets with parameterizable total supply + * and total assets variables. + */ + function _convertToSharesWithTotals( + uint256 assets, + uint256 newTotalSupply, + uint256 newTotalAssets, + Math.Rounding rounding + ) + internal + view + returns (uint256) + { + return assets.mulDiv(newTotalSupply + 10 ** _decimalsOffset(), newTotalAssets + 1, rounding); + } + + /** + * @dev Returns the amount of assets that the vault would exchange for the + * amount of `shares` provided. This function is used to calculate the + * conversion between shares and assets with parameterizable total supply + * and total assets variables. + */ + function _convertToAssetsWithTotals( + uint256 shares, + uint256 newTotalSupply, + uint256 newTotalAssets, + Math.Rounding rounding + ) + internal + view + returns (uint256) + { + return shares.mulDiv(newTotalAssets + 1, newTotalSupply + 10 ** _decimalsOffset(), rounding); + } + + function _updateLastTotalAssets(uint256 newLastTotalAssets) internal { + lastTotalAssets = newLastTotalAssets; + emit UpdateLastTotalAssets(lastTotalAssets, newLastTotalAssets); + } + + function _zeroFloorSub(uint256 x, uint256 y) internal pure returns (uint256 z) { + assembly { + z := mul(gt(x, y), sub(x, y)) + } + } + + /** + * @dev Emulates the actual `_withdrawFromIonPool` accounting to predict + * accurately how much of the input assets will be left after withdrawing as much as it can. The + * difference between this return value and the input `assets` is the exact + * amount that will be withdrawn. + * @return The remaining assets to be withdrawn. NOT the amount of assets that were withdrawn. + */ + function _simulateWithdrawIon(uint256 assets) internal view returns (uint256) { + uint256 withdrawQueueLength = withdrawQueue.length; + for (uint256 i; i != withdrawQueueLength;) { + IIonPool pool = withdrawQueue[i]; + + uint256 withdrawable = pool == IDLE ? BASE_ASSET.balanceOf(address(this)) : _withdrawable(pool); + + uint256 toWithdraw = Math.min(withdrawable, assets); + assets -= toWithdraw; + + if (assets == 0) break; + + unchecked { + ++i; + } + } + + return assets; // the remaining assets after withdraw + } + + /** + * @dev The max amount of assets withdrawable from a given IonPool + * considering the vault's claim and the available liquidity. A minimum of + * this contract's total claim on the underlying and the available liquidity + * in the pool. + * @return The max amount of assets withdrawable from this IonPool. + */ + function _withdrawable(IIonPool pool) internal view returns (uint256) { + if (pool.paused()) return 0; + + uint256 currentSupplied = pool.balanceOf(address(this)); + + uint256 availableLiquidity = uint256(pool.extsload(ION_POOL_LIQUIDITY_SLOT)); + return Math.min(currentSupplied, availableLiquidity); + } + + /** + * @dev The max amount of assets depositable to a given IonPool. Depositing + * the minimum between the two diffs ensures that the deposit will not + * violate the allocation cap or the supply cap. + * @return The max amount of assets depositable to this IonPool. + */ + function _depositable(IIonPool pool) internal view returns (uint256) { + if (pool.paused()) return 0; + + uint256 allocationCapDiff = _zeroFloorSub(caps[pool], pool.balanceOf(address(this))); + uint256 supplyCapDiff = _zeroFloorSub(uint256(pool.extsload(ION_POOL_SUPPLY_CAP_SLOT)), pool.totalSupply()); + + return Math.min(allocationCapDiff, supplyCapDiff); + } + + // --- EnumerableSet.Address Getters --- + + /** + * @notice Returns the array representation of the `supportedMarkets` set. + * @return Array of supported IonPools. + */ + function getSupportedMarkets() external view returns (address[] memory) { + return supportedMarkets.values(); + } + + /** + * @notice Returns whether the market is part of the `supportedMarkets` set. + * @param pool The address of the IonPool to be checked. + * @return The pool is supported if true. If not, false. + */ + function containsSupportedMarket(address pool) external view returns (bool) { + return supportedMarkets.contains(pool); + } + + /** + * @notice Returns the element in the array representation of + * `supportedMarkets`. `index` must be strictly less than the length of the + * array. + * @param index The index to be queried on the `supportedMarkets` array. + * @return Address at the index of `supportedMarkets`. + */ + function supportedMarketsAt(uint256 index) external view returns (address) { + return supportedMarkets.at(index); + } + + /** + * @notice Returns the index of the specified market in the array representation of `supportedMarkets`. + * @dev The `_positions` mapping inside the `EnumerableSet.Set` returns the + * index of the element in the `_values` array plus 1. The `_positions` + * value of 0 means that the value is not in the set. If the value is not in + * the set, this call will revert. Otherwise, it will return the `position - + * 1` value to return the index of the element in the array. + * @param pool The address of the IonPool to be queried. + * @return The index of the pool's location in the array. The return value + * will always be greater than zero as this function would revert if the + * market is not part of the set. + */ + function supportedMarketsIndexOf(address pool) external view returns (uint256) { + return _supportedMarketsIndexOf(pool); + } + + /** + * @notice Length of the array representation of `supportedMarkets`. + * @return The length of the `supportedMarkets` array. + */ + function supportedMarketsLength() external view returns (uint256) { + return supportedMarkets.length(); + } + + function _supportedMarketsIndexOf(address pool) internal view returns (uint256) { + bytes32 key = bytes32(uint256(uint160(pool))); + uint256 position = supportedMarkets._inner._positions[key]; + if (position == 0) revert MarketNotSupported(IIonPool(pool)); + return --position; + } +} diff --git a/src/vault/VaultFactory.sol b/src/vault/VaultFactory.sol new file mode 100644 index 00000000..b2915058 --- /dev/null +++ b/src/vault/VaultFactory.sol @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity 0.8.21; + +import { Vault } from "./Vault.sol"; +import { IERC20 } from "openzeppelin-contracts/contracts/interfaces/IERC20.sol"; +import { SafeERC20 } from "openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol"; + +/** + * @title Ion Lending Vault Factory + * @author Molecular Labs + * @notice Factory contract for deploying Ion Lending Vaults. + */ +contract VaultFactory { + using SafeERC20 for IERC20; + + // --- Events --- + + event CreateVault( + address vault, + IERC20 indexed baseAsset, + address feeRecipient, + uint256 feePercentage, + string name, + string symbol, + address indexed initialDefaultAdmin + ); + + // --- External --- + + /** + * @notice Deploys a new Ion Lending Vault. Transfers the `initialDeposit` + * amount of the base asset from the caller initiate the first deposit to + * the vault. The minimum `initialDeposit` is 1e3. If less, this call would + * underflow as it will always burn 1e3 shares of the total shares minted to + * defend against inflation attacks. + * @dev The 1e3 initial deposit amount was chosen to defend against + * inflation attacks, referencing the UniV2 LP token implementation. + * @param baseAsset The asset that is being lent out to IonPools. + * @param feeRecipient Address that receives the accrued manager fees. + * @param feePercentage Fee percentage to be set. + * @param name Name of the vault token. + * @param symbol Symbol of the vault token. + * @param initialDelay The initial delay for default admin transfers. + * @param initialDefaultAdmin The initial default admin for the vault. + * @param salt The salt used for CREATE2 deployment. + * @param marketsArgs Arguments for the markets to be added to the vault. + * @param initialDeposit The initial deposit to be made to the vault. + */ + function createVault( + IERC20 baseAsset, + address feeRecipient, + uint256 feePercentage, + string memory name, + string memory symbol, + uint48 initialDelay, + address initialDefaultAdmin, + bytes32 salt, + Vault.MarketsArgs memory marketsArgs, + uint256 initialDeposit + ) + external + returns (Vault vault) + { + vault = new Vault{ salt: salt }( + baseAsset, feeRecipient, feePercentage, name, symbol, initialDelay, initialDefaultAdmin, marketsArgs + ); + + baseAsset.safeTransferFrom(msg.sender, address(this), initialDeposit); + baseAsset.approve(address(vault), initialDeposit); + uint256 sharesMinted = vault.deposit(initialDeposit, address(this)); + + // The factory keeps 1e3 shares to reduce inflation attack vector. + // Effectively burns this amount of shares by locking it in the factory. + vault.transfer(msg.sender, sharesMinted - 1e3); + + emit CreateVault(address(vault), baseAsset, feeRecipient, feePercentage, name, symbol, initialDefaultAdmin); + } +} diff --git a/test/fork/concrete/IonLens.t.sol b/test/fork/concrete/IonLens.t.sol new file mode 100644 index 00000000..cb54d37c --- /dev/null +++ b/test/fork/concrete/IonLens.t.sol @@ -0,0 +1,261 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.21; + +import { IonLens } from "../../../src/periphery/IonLens.sol"; +import { IIonPool } from "../../../src/interfaces/IIonPool.sol"; +import { IGemJoin } from "../../../src/interfaces/IGemJoin.sol"; +import { IWhitelist } from "../../../src/interfaces/IWhitelist.sol"; +import { IonPool } from "../../../src/IonPool.sol"; +import { WEETH_ADDRESS } from "../../../src/Constants.sol"; +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + +import { Test } from "forge-std/Test.sol"; + +contract IonLensTest is Test { + IonLens public ionLens; + IIonPool public ionPool = IIonPool(0x0000000000eaEbd95dAfcA37A39fd09745739b78); + IGemJoin public gemJoin = IGemJoin(0x3f6119B0328C27190bE39597213ea1729f061876); + IWhitelist public whitelist = IWhitelist(0x7E317f99aA313669AaCDd8dB3927ff3aCB562dAD); + IonPool public updatedImpl; + + function setUp() public { + // Pre-upgrade block + vm.createSelectFork(vm.envString("MAINNET_RPC_URL"), 19_494_278); + ionLens = new IonLens(); + updatedImpl = new IonPool(); + } + + function test_IlkCount() public { + uint256 ilkCountBefore = ionPool.ilkCount(); + + _updateImpl(); + + uint256 ilkCountAfter = ionLens.ilkCount(ionPool); + + assertEq(ilkCountBefore, ilkCountAfter, "ilk count"); + } + + function test_getIlkIndex() public { + uint256 ilkIndexBefore = ionPool.getIlkIndex(address(WEETH_ADDRESS)); + + _updateImpl(); + + uint256 ilkIndexAfter = ionLens.getIlkIndex(ionPool, address(WEETH_ADDRESS)); + + assertEq(ilkIndexBefore, ilkIndexAfter, "ilk index"); + } + + function test_totalNormalizedDebt() public { + uint8 ilkIndex = 0; + uint256 totalNormalizedDebtBefore = ionPool.totalNormalizedDebt(ilkIndex); + + _updateImpl(); + + uint256 totalNormalizedDebtAfter = ionLens.totalNormalizedDebt(ionPool, ilkIndex); + + assertEq(totalNormalizedDebtBefore, totalNormalizedDebtAfter, "total normalized debt"); + } + + function test_rateUnaccrued() public { + uint8 ilkIndex = 0; + uint256 rateUnaccruedBefore = ionPool.rateUnaccrued(ilkIndex); + + _updateImpl(); + + uint256 rateUnaccruedAfter = ionLens.rateUnaccrued(ionPool, ilkIndex); + + assertEq(rateUnaccruedBefore, rateUnaccruedAfter, "rate unaccrued"); + } + + function test_lastRateUpdate() public { + uint8 ilkIndex = 0; + uint256 lastRateUpdateBefore = ionPool.lastRateUpdate(ilkIndex); + + _updateImpl(); + + uint256 lastRateUpdateAfter = ionLens.lastRateUpdate(ionPool, ilkIndex); + + assertEq(lastRateUpdateBefore, lastRateUpdateAfter, "last rate update"); + } + + function test_spot() public { + uint8 ilkIndex = 0; + address spotBefore = ionPool.spot(ilkIndex); + + _updateImpl(); + + address spotAfter = ionLens.spot(ionPool, ilkIndex); + + assertEq(spotBefore, spotAfter, "spot"); + } + + function test_debtCeiling() public { + uint8 ilkIndex = 0; + uint256 debtCeilingBefore = ionPool.debtCeiling(ilkIndex); + + _updateImpl(); + + uint256 debtCeilingAfter = ionLens.debtCeiling(ionPool, ilkIndex); + + assertEq(debtCeilingBefore, debtCeilingAfter, "debt ceiling"); + } + + function test_dust() public { + uint8 ilkIndex = 0; + uint256 dustBefore = ionPool.dust(ilkIndex); + + _updateImpl(); + + uint256 dustAfter = ionLens.dust(ionPool, ilkIndex); + + assertEq(dustBefore, dustAfter, "dust"); + } + + function test_gem() public { + uint8 ilkIndex = 0; + + address gem = gemJoin.GEM(); + + deal(gem, address(this), 1e18); + IERC20(gem).approve(address(gemJoin), type(uint256).max); + gemJoin.join(address(this), 1e18); + + uint256 gemBefore = ionPool.gem(ilkIndex, address(this)); + + _updateImpl(); + + uint256 gemAfter = ionLens.gem(ionPool, ilkIndex, address(this)); + + assertEq(gemBefore, gemAfter, "gem"); + } + + function test_unbackedDebt() public { + uint8 ilkIndex = 0; + + vm.startPrank(whitelist.owner()); + whitelist.updateBorrowersRoot(0, bytes32(0)); + whitelist.updateLendersRoot(bytes32(0)); + vm.stopPrank(); + + address base = ionPool.underlying(); + deal(base, address(this), 10e18); + IERC20(base).approve(address(ionPool), type(uint256).max); + ionPool.supply(address(this), 10e18, new bytes32[](0)); + + address gem = gemJoin.GEM(); + + deal(gem, address(this), 10e18); + IERC20(gem).approve(address(gemJoin), type(uint256).max); + gemJoin.join(address(this), 10e18); + + ionPool.depositCollateral(ilkIndex, address(this), address(this), 10e18, new bytes32[](0)); + ionPool.borrow(ilkIndex, address(this), address(this), 5e18, new bytes32[](0)); + + vm.startPrank(ionPool.defaultAdmin()); + ionPool.grantRole(ionPool.LIQUIDATOR_ROLE(), address(this)); + vm.stopPrank(); + ionPool.confiscateVault(0, address(this), address(this), address(this), 0, -int256(1e14)); + + uint256 unbackedDebtBefore = ionPool.unbackedDebt(address(this)); + + _updateImpl(); + + uint256 unbackedDebtAfter = ionLens.unbackedDebt(ionPool, address(this)); + + assertEq(unbackedDebtBefore, unbackedDebtAfter, "unbacked debt"); + } + + function test_isOperator() public { + address operator = address(2); + + ionPool.addOperator(operator); + + bool isOperatorBefore = ionPool.isOperator(address(this), operator); + + _updateImpl(); + + bool isOperatorAfter = ionLens.isOperator(ionPool, address(this), operator); + + assertTrue(isOperatorBefore, "is operator"); + assertEq(isOperatorBefore, isOperatorAfter, "is operator"); + } + + function test_debtUnaccrued() public { + uint256 debtUnaccruedBefore = ionPool.debtUnaccrued(); + + _updateImpl(); + + uint256 debtUnaccruedAfter = ionLens.debtUnaccrued(ionPool); + + assertEq(debtUnaccruedBefore, debtUnaccruedAfter, "debt unaccrued"); + } + + function test_debt() public { + uint256 debtBefore = ionPool.debt(); + + _updateImpl(); + + uint256 debtAfter = ionLens.debt(ionPool); + + assertEq(debtBefore, debtAfter, "debt"); + } + + function test_weth() public { + uint256 wethBefore = ionPool.weth(); + + _updateImpl(); + + uint256 wethAfter = ionLens.liquidity(ionPool); + + assertEq(wethBefore, wethAfter, "weth"); + } + + function test_supplyCap() public { + uint256 supplyCapBefore = + uint256(vm.load(address(ionPool), 0xceba3d526b4d5afd91d1b752bf1fd37917c20a6daf576bcb41dd1c57c1f67e09)); + + _updateImpl(); + + uint256 supplyCapAfter = ionLens.supplyCap(ionPool); + + assertEq(supplyCapBefore, supplyCapAfter, "weth supply cap"); + } + + function test_totalUnbackedDebt() public { + uint256 totalUnbackedDebtBefore = ionPool.totalUnbackedDebt(); + + _updateImpl(); + + uint256 totalUnbackedDebtAfter = ionLens.totalUnbackedDebt(ionPool); + + assertEq(totalUnbackedDebtBefore, totalUnbackedDebtAfter, "total unbacked debt"); + } + + function test_interestRateModule() public { + address interestRateModuleBefore = ionPool.interestRateModule(); + + _updateImpl(); + + address interestRateModuleAfter = ionLens.interestRateModule(ionPool); + + assertEq(interestRateModuleBefore, interestRateModuleAfter, "interest rate module"); + } + + function test_whitelist() public { + address whitelistBefore = ionPool.whitelist(); + + _updateImpl(); + + address whitelistAfter = ionLens.whitelist(ionPool); + + assertEq(whitelistBefore, whitelistAfter, "whitelist"); + } + + function _updateImpl() public { + vm.store( + address(ionPool), + 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc, + bytes32(uint256(uint160(address(updatedImpl)))) + ); + } +} diff --git a/test/fork/concrete/lrt/EzEthHandler.t.sol b/test/fork/concrete/lrt/EzEthHandler.t.sol index ee04c95c..d965e26e 100644 --- a/test/fork/concrete/lrt/EzEthHandler.t.sol +++ b/test/fork/concrete/lrt/EzEthHandler.t.sol @@ -6,6 +6,7 @@ import { LrtHandler_ForkBase } from "../../../helpers/handlers/LrtHandlerForkBas import { EzEthHandler } from "./../../../../src/flash/lrt/EzEthHandler.sol"; import { Whitelist } from "../../../../src/Whitelist.sol"; import { RENZO_RESTAKE_MANAGER, EZETH } from "../../../../src/Constants.sol"; +import { IIonPool } from "./../../../../src/interfaces/IIonPool.sol"; import { IProviderLibraryExposed } from "../../../helpers/IProviderLibraryExposed.sol"; import { UniswapFlashswapDirectMintHandlerWithDust_Test } from @@ -35,7 +36,7 @@ abstract contract EzEthHandler_ForkBase is LrtHandler_ForkBase { EZETH.approve(address(ezEthHandler), type(uint256).max); // Remove debt ceiling for this test - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(IIonPool(address(ionPool))); i++) { ionPool.updateIlkDebtCeiling(i, type(uint256).max); } diff --git a/test/fork/concrete/lrt/RsEthHandler.t.sol b/test/fork/concrete/lrt/RsEthHandler.t.sol index b45dae32..fb73f2e0 100644 --- a/test/fork/concrete/lrt/RsEthHandler.t.sol +++ b/test/fork/concrete/lrt/RsEthHandler.t.sol @@ -43,7 +43,7 @@ abstract contract RsEthHandler_ForkBase is LrtHandler_ForkBase { RSETH.approve(address(rsEthHandler), type(uint256).max); // Remove debt ceiling for this test - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { ionPool.updateIlkDebtCeiling(i, type(uint256).max); } diff --git a/test/fork/concrete/lrt/RswEthHandler.t.sol b/test/fork/concrete/lrt/RswEthHandler.t.sol index a5b15b0d..99359c8e 100644 --- a/test/fork/concrete/lrt/RswEthHandler.t.sol +++ b/test/fork/concrete/lrt/RswEthHandler.t.sol @@ -7,6 +7,7 @@ import { RswEthHandler } from "../../../../src/flash/lrt/RswEthHandler.sol"; import { Whitelist } from "../../../../src/Whitelist.sol"; import { RSWETH } from "../../../../src/Constants.sol"; import { LrtHandler_ForkBase } from "../../../helpers/handlers/LrtHandlerForkBase.sol"; +import { IIonPool } from "./../../../../src/interfaces/IIonPool.sol"; import { IProviderLibraryExposed } from "../../../helpers/IProviderLibraryExposed.sol"; import { UniswapFlashswapDirectMintHandler_Test } from "../handlers-base/UniswapFlashswapDirectMintHandler.t.sol"; @@ -43,7 +44,7 @@ abstract contract RswEthHandler_ForkBase is LrtHandler_ForkBase { RSWETH.approve(address(rswEthHandler), type(uint256).max); // Remove debt ceiling for this test - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(IIonPool(address(ionPool))); i++) { ionPool.updateIlkDebtCeiling(i, type(uint256).max); } diff --git a/test/fork/concrete/lrt/SpotOracle.t.sol b/test/fork/concrete/lrt/SpotOracle.t.sol index c5b12061..35745794 100644 --- a/test/fork/concrete/lrt/SpotOracle.t.sol +++ b/test/fork/concrete/lrt/SpotOracle.t.sol @@ -14,6 +14,8 @@ import { EzEthWstEthReserveOracle } from "./../../../../src/oracles/reserve/lrt/ import { EzEthWstEthSpotOracle } from "./../../../../src/oracles/spot/lrt/EzEthWstEthSpotOracle.sol"; import { WadRayMath } from "../../../../src/libraries/math/WadRayMath.sol"; +import { Math } from "openzeppelin-contracts/contracts/utils/math/Math.sol"; + import { ReserveOracleSharedSetup } from "../../../helpers/ReserveOracleSharedSetup.sol"; abstract contract SpotOracle_ForkTest is ReserveOracleSharedSetup { @@ -30,13 +32,14 @@ abstract contract SpotOracle_ForkTest is ReserveOracleSharedSetup { } function testFork_ViewSpot() public { + uint256 ltv = spotOracle.LTV(); + uint256 price = spotOracle.getPrice(); - uint256 exchangeRate = reserveOracle.currentExchangeRate(); - uint256 value = price <= exchangeRate ? price : exchangeRate; + uint256 currentExchangeRate = reserveOracle.currentExchangeRate(); - uint256 ltv = spotOracle.LTV(); - uint256 expectedSpot = ltv.wadMulDown(value); + uint256 min = Math.min(price, currentExchangeRate); + uint256 expectedSpot = ltv.wadMulDown(min); uint256 spot = spotOracle.getSpot(); assertEq(spot, expectedSpot, "spot"); diff --git a/test/fork/concrete/lrt/WeEthHandler.t.sol b/test/fork/concrete/lrt/WeEthHandler.t.sol index f541df0e..66ffe3bd 100644 --- a/test/fork/concrete/lrt/WeEthHandler.t.sol +++ b/test/fork/concrete/lrt/WeEthHandler.t.sol @@ -43,7 +43,7 @@ abstract contract WeEthHandler_ForkBase is LrtHandler_ForkBase { WEETH_ADDRESS.approve(address(weEthHandler), type(uint256).max); // Remove debt ceiling for this test - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { ionPool.updateIlkDebtCeiling(i, type(uint256).max); } diff --git a/test/fork/concrete/lst/EthXHandler.t.sol b/test/fork/concrete/lst/EthXHandler.t.sol index 1b5d0c0b..247a9880 100644 --- a/test/fork/concrete/lst/EthXHandler.t.sol +++ b/test/fork/concrete/lst/EthXHandler.t.sol @@ -57,7 +57,7 @@ abstract contract EthXHandler_ForkBase is LstHandler_ForkBase { IERC20(address(MAINNET_ETHX)).approve(address(ethXHandler), type(uint256).max); // Remove debt ceiling for this test - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { ionPool.updateIlkDebtCeiling(i, type(uint256).max); } diff --git a/test/fork/concrete/lst/SwEthHandler.t.sol b/test/fork/concrete/lst/SwEthHandler.t.sol index 6f7be9c3..9f8c778c 100644 --- a/test/fork/concrete/lst/SwEthHandler.t.sol +++ b/test/fork/concrete/lst/SwEthHandler.t.sol @@ -44,7 +44,7 @@ abstract contract SwEthHandler_ForkBase is LstHandler_ForkBase { IERC20(address(MAINNET_SWELL)).approve(address(swEthHandler), type(uint256).max); // Remove debt ceiling for this test - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { ionPool.updateIlkDebtCeiling(i, type(uint256).max); } diff --git a/test/fork/concrete/lst/WstEthHandler.t.sol b/test/fork/concrete/lst/WstEthHandler.t.sol index 507f97f0..b2bde8d3 100644 --- a/test/fork/concrete/lst/WstEthHandler.t.sol +++ b/test/fork/concrete/lst/WstEthHandler.t.sol @@ -48,7 +48,7 @@ abstract contract WstEthHandler_ForkBase is LstHandler_ForkBase { IERC20(address(MAINNET_WSTETH)).approve(address(wstEthHandler), type(uint256).max); // Remove debt ceiling for this test - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { ionPool.updateIlkDebtCeiling(i, type(uint256).max); } @@ -463,7 +463,7 @@ contract WstEthHandlerWhitelist_ForkTest is WstEthHandler_ForkTest, WstEthHandle borrowerRoots[0] = borrowerWhitelistRoot; // update current whitelist with a new borrower root - Whitelist _whitelist = Whitelist(ionPool.whitelist()); + Whitelist _whitelist = Whitelist(lens.whitelist(iIonPool)); _whitelist.updateBorrowersRoot(ilkIndex, borrowerWhitelistRoot); _whitelist.approveProtocolWhitelist(address(wstEthHandler)); diff --git a/test/fork/concrete/pendle/PtWeEthHandler.t.sol b/test/fork/concrete/pendle/PtWeEthHandler.t.sol index 161921d9..8e23bf0f 100644 --- a/test/fork/concrete/pendle/PtWeEthHandler.t.sol +++ b/test/fork/concrete/pendle/PtWeEthHandler.t.sol @@ -6,6 +6,7 @@ import { PtHandler } from "../../../../src/flash/PtHandler.sol"; import { Whitelist } from "../../../../src/Whitelist.sol"; import { IWeEth } from "../../../../src/interfaces/ProviderInterfaces.sol"; import { EtherFiLibrary } from "../../../../src/libraries/lrt/EtherFiLibrary.sol"; +import { IIonPool } from "./../../../../src/interfaces/IIonPool.sol"; import { IProviderLibraryExposed } from "../../../helpers/IProviderLibraryExposed.sol"; import { PtHandler_ForkBase } from "../../../helpers/handlers/PtHandlerBase.sol"; @@ -34,7 +35,7 @@ abstract contract PtWeEthHandler_ForkBase is PtHandler_ForkBase { _pt.approve(address(ptHandler), type(uint256).max); // Remove debt ceiling for this test - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(IIonPool(address(ionPool))); i++) { ionPool.updateIlkDebtCeiling(i, type(uint256).max); } diff --git a/test/fork/concrete/vault/Vault.t.sol b/test/fork/concrete/vault/Vault.t.sol new file mode 100644 index 00000000..c2dd2fa6 --- /dev/null +++ b/test/fork/concrete/vault/Vault.t.sol @@ -0,0 +1,168 @@ +// // SPDX-License-Identifier: MIT +// pragma solidity 0.8.21; + +// import { Vault } from "./../../../../src/vault/Vault.sol"; +// import { IonPool } from "./../../../../src/IonPool.sol"; +// import { Whitelist } from "./../../../../src/Whitelist.sol"; +// import { IIonPool } from "./../../../../src/interfaces/IIonPool.sol"; +// import { IonLens } from "./../../../../src/periphery/IonLens.sol"; +// import { WSTETH_ADDRESS } from "./../../../../src/Constants.sol"; +// import { IERC20 } from "openzeppelin-contracts/contracts/interfaces/IERC20.sol"; +// import { EnumerableSet } from "openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol"; +// // import { StdStorage, stdStorage } from "../../../../lib/forge-safe/lib/forge-std/src/StdStorage.sol"; + +// import "forge-std/Test.sol"; +// import { console2 } from "forge-std/console2.sol"; + +// using EnumerableSet for EnumerableSet.AddressSet; + +// IIonPool constant WEETH_IONPOOL = IIonPool(0x0000000000eaEbd95dAfcA37A39fd09745739b78); +// IIonPool constant RSETH_IONPOOL = IIonPool(0x0000000000E33e35EE6052fae87bfcFac61b1da9); +// IIonPool constant RSWETH_IONPOOL = IIonPool(0x00000000007C8105548f9d0eE081987378a6bE93); +// Whitelist constant WHITELIST = Whitelist(0x7E317f99aA313669AaCDd8dB3927ff3aCB562dAD); +// bytes32 constant ION_ROLE = 0x5ab1a5ffb29c47d95dec8c5f9ad49a551754822b51a3359ed1c21e2be24beefa; + +// address constant VAULT_OWNER = address(1); +// address constant FEE_RECIPIENT = address(2); +// IERC20 constant BASE_ASSET = WSTETH_ADDRESS; + +// contract VaultForkBase is Test { +// using stdStorage for StdStorage; + +// StdStorage stdstore1; +// IonLens public ionLens; +// Vault vault; + +// uint256 internal forkBlock = 0; +// address internal poolAdmin; + +// IIonPool[] markets; + +// function setERC20Balance(address token, address usr, uint256 amt) public { +// stdstore1.target(token).sig(IERC20(token).balanceOf.selector).with_key(usr).checked_write(amt); +// require(IERC20(token).balanceOf(usr) == amt, "balance not set"); +// } + +// function updateSupplyCap(IIonPool pool, uint256 cap) internal { +// vm.startPrank(poolAdmin); +// pool.updateSupplyCap(cap); +// vm.stopPrank(); +// assertEq(ionLens.wethSupplyCap(pool), cap, "supply cap update"); +// } + +// function _updateImpl(IIonPool proxy, IIonPool impl) internal { +// vm.store( +// address(proxy), +// 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc, +// bytes32(uint256(uint160(address(impl)))) +// ); +// } + +// function setUp() public virtual { +// if (forkBlock == 0) vm.createSelectFork(vm.envString("MAINNET_ARCHIVE_RPC_URL")); +// else vm.createSelectFork(vm.envString("MAINNET_ARCHIVE_RPC_URL"), forkBlock); + +// poolAdmin = WEETH_IONPOOL.defaultAdmin(); +// // update fork contract to the latest implementation with +// // transferradbility + non-rebasing + removed getters +// ionLens = new IonLens(); + +// IonPool updatedImpl = new IonPool(); + +// _updateImpl(WEETH_IONPOOL, IIonPool(address(updatedImpl))); +// _updateImpl(RSETH_IONPOOL, IIonPool(address(updatedImpl))); +// _updateImpl(RSWETH_IONPOOL, IIonPool(address(updatedImpl))); + +// vault = new Vault(VAULT_OWNER, FEE_RECIPIENT, BASE_ASSET, ionLens, "Ion Vault Token", "IVT"); + +// markets = new IIonPool[](3); +// markets[0] = WEETH_IONPOOL; +// markets[1] = RSETH_IONPOOL; +// markets[2] = RSWETH_IONPOOL; + +// vm.startPrank(vault.owner()); + +// vault.addSupportedMarkets(markets); +// vault.updateSupplyQueue(markets); +// vault.updateWithdrawQueue(markets); + +// vm.stopPrank(); + +// BASE_ASSET.approve(address(vault), type(uint256).max); + +// vm.prank(poolAdmin); +// WHITELIST.updateLendersRoot(bytes32(0)); +// } +// } + +// /** +// * Vault state that needs to be checked +// * - Vault's shares total supply +// * - Vault's total iToken balance +// * - User's vault shares balance +// */ +// contract Vault_ForkTest is VaultForkBase { +// function setUp() public override { +// super.setUp(); + +// uint256[] memory newCaps = new uint256[](3); +// newCaps[0] = 100e18; +// newCaps[1] = 100e18; +// newCaps[2] = 100e18; +// vm.prank(vault.owner()); +// vault.updateAllocationCaps(markets, newCaps); +// } + +// /** +// * Because the first market's allocation cap and supply cap is high enough, +// * all deposits go into the first market. +// */ +// function test_DepositFirstMarketOnly() public { +// setERC20Balance(address(BASE_ASSET), address(this), 100e18); +// console2.log("BASE_ASSET.balanceOf(address(this)): ", BASE_ASSET.balanceOf(address(this))); + +// IIonPool pool1 = vault.supplyQueue(0); +// IIonPool pool2 = vault.supplyQueue(1); +// IIonPool pool3 = vault.supplyQueue(2); + +// console2.log("pool1: ", address(pool1)); +// updateSupplyCap(pool1, type(uint256).max); + +// vault.deposit(100e18, address(this)); + +// // vault shares +// // vault iToken balance +// } + +// function test_Withdraw() public { } +// } + +// contract Vault_ForkTest_WithRateAccrual is VaultForkBase { } + +// contract Vault_ForkFuzzTest is VaultForkBase { +// function setUp() public override { +// super.setUp(); +// } + +// /** +// * Start each pool at a random total supply amount and a supply cap. +// * The total supply amount must be less than or equal to the supply cap. +// * Deposit random amount of assets into the vault. +// * The deposit amount must be equal to the change in deposits across all lending pools. +// * It should only revert if the total available supply amount is less than the deposit amount. +// */ +// function testForkFuzz_DepositAllMarkets(uint256 assets) public { } + +// function testFuzz_Withdraw(uint256 assets) public { } + +// /** +// * The totalAssets should return the total rebased claim across all markets at a given time. +// */ +// function testFuzz_totalAssets() public { } + +// /** +// * The total amount of fees collected at a random time in the futuer should be split +// * between the vault depositors and the fee recipient. +// */ +// function testFuzz_Fees() public { } +// } diff --git a/test/fork/concrete/vault/VaultFactory.t.sol b/test/fork/concrete/vault/VaultFactory.t.sol new file mode 100644 index 00000000..b7201181 --- /dev/null +++ b/test/fork/concrete/vault/VaultFactory.t.sol @@ -0,0 +1,351 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity 0.8.21; + +import { Vault } from "./../../../../src/vault/Vault.sol"; +import { VaultFactory } from "./../../../../src/vault/VaultFactory.sol"; +import { VaultSharedSetup } from "../../../helpers/VaultSharedSetup.sol"; +import { ERC20PresetMinterPauser } from "../../../helpers/ERC20PresetMinterPauser.sol"; +import { IERC20 } from "@openzeppelin/contracts/interfaces/IERC20.sol"; +import { IIonPool } from "./../../../../src/interfaces/IIonPool.sol"; + +import { console2 } from "forge-std/console2.sol"; + +contract VaultFactoryTest is VaultSharedSetup { + VaultFactory factory; + + address internal feeRecipient = address(2); + uint256 internal feePercentage = 0.02e27; + IERC20 internal baseAsset = BASE_ASSET; + string internal name = "Vault Token"; + string internal symbol = "VT"; + + IIonPool[] internal marketsToAdd; + uint256[] internal allocationCaps; + IIonPool[] internal newSupplyQueue; + IIonPool[] internal newWithdrawQueue; + + function setUp() public override { + super.setUp(); + + factory = new VaultFactory(); + + marketsToAdd.push(weEthIonPool); + marketsToAdd.push(rsEthIonPool); + marketsToAdd.push(rswEthIonPool); + + allocationCaps.push(1e18); + allocationCaps.push(2e18); + allocationCaps.push(3e18); + + newSupplyQueue.push(weEthIonPool); + newSupplyQueue.push(rswEthIonPool); + newSupplyQueue.push(rsEthIonPool); + + newWithdrawQueue.push(rswEthIonPool); + newWithdrawQueue.push(rsEthIonPool); + newWithdrawQueue.push(weEthIonPool); + + marketsArgs.marketsToAdd = marketsToAdd; + marketsArgs.allocationCaps = allocationCaps; + marketsArgs.newSupplyQueue = newSupplyQueue; + marketsArgs.newWithdrawQueue = newWithdrawQueue; + + setERC20Balance(address(BASE_ASSET), address(this), MIN_INITIAL_DEPOSIT); + BASE_ASSET.approve(address(factory), MIN_INITIAL_DEPOSIT); + } + + function test_CreateVault() public { + bytes32 salt = keccak256("random salt"); + Vault vault = factory.createVault( + baseAsset, + feeRecipient, + feePercentage, + name, + symbol, + INITIAL_DELAY, + VAULT_ADMIN, + salt, + marketsArgs, + MIN_INITIAL_DEPOSIT + ); + + address[] memory supportedMarkets = vault.getSupportedMarkets(); + + IIonPool firstInSupplyQueue = vault.supplyQueue(0); + IIonPool secondInSupplyQueue = vault.supplyQueue(1); + IIonPool thirdInSupplyQueue = vault.supplyQueue(2); + + IIonPool firstInWithdrawQueue = vault.withdrawQueue(0); + IIonPool secondInWithdrawQueue = vault.withdrawQueue(1); + IIonPool thirdInWithdrawQueue = vault.withdrawQueue(2); + + assertEq(vault.defaultAdmin(), VAULT_ADMIN, "default admin"); + assertEq(vault.feeRecipient(), feeRecipient, "fee recipient"); + assertEq(vault.feePercentage(), feePercentage, "fee percentage"); + assertEq(address(vault.BASE_ASSET()), address(baseAsset), "base asset"); + + assertEq(supportedMarkets.length, 3, "supported markets length"); + + for (uint256 i = 0; i != supportedMarkets.length; ++i) { + assertEq(address(supportedMarkets[i]), address(marketsToAdd[i]), "supported markets"); + assertEq(address(vault.supplyQueue(i)), address(newSupplyQueue[i]), "supply queue"); + assertEq(address(vault.withdrawQueue(i)), address(newWithdrawQueue[i]), "withdraw queue"); + } + + // initial deposits + assertEq(BASE_ASSET.balanceOf(address(this)), 0, "initial deposit spent"); + assertEq(vault.totalAssets(), MIN_INITIAL_DEPOSIT, "total assets"); + assertEq(vault.totalSupply(), MIN_INITIAL_DEPOSIT, "total supply"); + + assertEq(vault.balanceOf(address(factory)), 1e3, "factory gets 1e3 shares"); + assertEq(vault.balanceOf(address(this)), MIN_INITIAL_DEPOSIT - 1e3, "deployer gets 1e3 less shares"); + } + + function test_CreateVault_Twice() public { + bytes32 salt = keccak256("first random salt"); + Vault vault = factory.createVault( + baseAsset, + feeRecipient, + feePercentage, + name, + symbol, + INITIAL_DELAY, + VAULT_ADMIN, + salt, + marketsArgs, + MIN_INITIAL_DEPOSIT + ); + + setERC20Balance(address(BASE_ASSET), address(this), MIN_INITIAL_DEPOSIT); + BASE_ASSET.approve(address(factory), MIN_INITIAL_DEPOSIT); + + bytes32 salt2 = keccak256("second random salt"); + Vault vault2 = factory.createVault( + baseAsset, + feeRecipient, + feePercentage, + name, + symbol, + INITIAL_DELAY, + VAULT_ADMIN, + salt2, + marketsArgs, + MIN_INITIAL_DEPOSIT + ); + + assertEq(VAULT_ADMIN, vault.defaultAdmin(), "default admin"); + assertEq(feeRecipient, vault.feeRecipient(), "fee recipient"); + assertEq(address(baseAsset), address(vault.BASE_ASSET()), "base asset"); + + assertEq(VAULT_ADMIN, vault2.defaultAdmin(), "default admin"); + assertEq(feeRecipient, vault2.feeRecipient(), "fee recipient"); + assertEq(address(baseAsset), address(vault2.BASE_ASSET()), "base asset"); + } + + function test_Revert_CreateVault_SameSaltTwice() public { + bytes32 salt = keccak256("random salt"); + Vault vault = factory.createVault( + baseAsset, + feeRecipient, + feePercentage, + name, + symbol, + INITIAL_DELAY, + VAULT_ADMIN, + salt, + marketsArgs, + MIN_INITIAL_DEPOSIT + ); + + vm.expectRevert(); + Vault vault2 = factory.createVault( + baseAsset, + feeRecipient, + feePercentage, + name, + symbol, + INITIAL_DELAY, + VAULT_ADMIN, + salt, + marketsArgs, + MIN_INITIAL_DEPOSIT + ); + } + + function test_CreateVault_SameSaltDifferentBytecode() public { + bytes32 salt = keccak256("random salt"); + + Vault vault = factory.createVault( + BASE_ASSET, + feeRecipient, + feePercentage, + name, + symbol, + INITIAL_DELAY, + VAULT_ADMIN, + salt, + marketsArgs, + MIN_INITIAL_DEPOSIT + ); + + // Deploy a vault with different base assets + IERC20 diffBaseAsset = IERC20(address(new ERC20PresetMinterPauser("Another Wrapped Staked ETH", "wstETH2"))); + + IIonPool[] memory markets = new IIonPool[](3); + markets[0] = deployIonPool(diffBaseAsset, WEETH, address(this)); + markets[1] = deployIonPool(diffBaseAsset, RSETH, address(this)); + markets[2] = deployIonPool(diffBaseAsset, RSWETH, address(this)); + + marketsArgs.marketsToAdd = markets; + marketsArgs.allocationCaps = allocationCaps; + marketsArgs.newSupplyQueue = markets; + marketsArgs.newWithdrawQueue = markets; + + setERC20Balance(address(diffBaseAsset), address(this), MIN_INITIAL_DEPOSIT); + diffBaseAsset.approve(address(factory), MIN_INITIAL_DEPOSIT); + + Vault vault2 = factory.createVault( + diffBaseAsset, + feeRecipient, + feePercentage, + name, + symbol, + INITIAL_DELAY, + VAULT_ADMIN, + salt, + marketsArgs, + MIN_INITIAL_DEPOSIT + ); + + require(address(vault) != address(vault2), "different deployment address"); + } + + /** + * The amount of funds that the attacker can cause the user to lose should + * cost the attacker a significant amount of funds. + */ + function test_InflationAttackCostToGriefShouldBeHigh_DeployerIsNotTheAttacker() public { + uint256[] memory alloCaps = new uint256[](4); + alloCaps[0] = type(uint256).max; + alloCaps[1] = type(uint256).max; + alloCaps[2] = type(uint256).max; + alloCaps[3] = type(uint256).max; + + IIonPool[] memory markets = new IIonPool[](4); + markets[0] = IDLE; + markets[1] = weEthIonPool; + markets[2] = rsEthIonPool; + markets[3] = rswEthIonPool; + + marketsArgs.marketsToAdd = markets; + marketsArgs.allocationCaps = alloCaps; + marketsArgs.newSupplyQueue = markets; + marketsArgs.newWithdrawQueue = markets; + + address deployer = newAddress("DEPLOYER"); + // deploy using the factory which enforces minimum deposit of 1e9 assets + // and the 1e3 shares burn. + bytes32 salt = keccak256("random salt"); + + setERC20Balance(address(BASE_ASSET), deployer, MIN_INITIAL_DEPOSIT); + + vm.startPrank(deployer); + BASE_ASSET.approve(address(factory), MIN_INITIAL_DEPOSIT); + + Vault vault = factory.createVault( + BASE_ASSET, + feeRecipient, + feePercentage, + name, + symbol, + INITIAL_DELAY, + VAULT_ADMIN, + salt, + marketsArgs, + MIN_INITIAL_DEPOSIT + ); + vm.stopPrank(); + + vm.startPrank(VAULT_ADMIN); + vault.grantRole(vault.OWNER_ROLE(), OWNER); + vm.stopPrank(); + + updateAllocationCaps(vault, type(uint256).max, type(uint256).max, type(uint256).max); + + uint256 donationAmt = 10e18; + uint256 mintAmt = 10; + + // fund attacker + setERC20Balance(address(BASE_ASSET), address(this), donationAmt + mintAmt); + BASE_ASSET.approve(address(vault), type(uint256).max); + + uint256 initialAssetBalance = BASE_ASSET.balanceOf(address(this)); + console2.log("attacker balance before :"); + console2.log("%e", initialAssetBalance); + + vault.mint(mintAmt, address(this)); + uint256 attackerClaimAfterMint = vault.previewRedeem(vault.balanceOf(address(this))); + + console2.log("attackerClaimAfterMint: "); + console2.log("%e", attackerClaimAfterMint); + + console2.log("donationAmt: "); + console2.log("%e", donationAmt); + + // donate to inflate exchange rate by increasing `totalAssets` + IERC20(address(BASE_ASSET)).transfer(address(vault), donationAmt); + + assertEq(donationAmt + mintAmt + 1e3, vault.totalAssets(), "total assets"); + assertEq(mintAmt + 1e3, vault.totalSupply(), "minted shares"); + + // how much of this donation was captured by the virtual shares on the vault? + uint256 attackerClaimAfterDonation = vault.previewRedeem(vault.balanceOf(address(this))); + + console2.log("attackerClaimAfterDonation: "); + console2.log("%e", attackerClaimAfterDonation); + + uint256 lossFromDonation = attackerClaimAfterMint + donationAmt - attackerClaimAfterDonation; + + console2.log("loss from donation: "); + console2.log("%e", lossFromDonation); + + address alice = address(0xabcd); + setERC20Balance(address(BASE_ASSET), alice, 10e18 + 10); + + vm.startPrank(alice); + IERC20(address(BASE_ASSET)).approve(address(vault), 1e18); + vault.deposit(1e18, alice); + vm.stopPrank(); + + // Alice gained zero shares due to exchange rate inflation + uint256 aliceShares = vault.balanceOf(alice); + console2.log("alice resulting shares : "); + console2.log("%e", aliceShares); + + uint256 aliceClaim = vault.maxWithdraw(alice); + console2.log("alice resulting claim: "); + console2.log("%e", aliceClaim); + + console2.log("alice resulting assets lost: "); + console2.log("%e", 1e18 - aliceClaim); + + // How much of alice's deposits were captured by the attacker's shares? + uint256 attackerClaimAfterAlice = vault.previewRedeem(vault.balanceOf(address(this))); + uint256 attackerGainFromAlice = attackerClaimAfterAlice - attackerClaimAfterDonation; + console2.log("attackerGainFromAlice: "); + console2.log("%e", attackerGainFromAlice); + + vault.redeem(vault.balanceOf(address(this)) - 3, address(this), address(this)); + uint256 afterAssetBalance = BASE_ASSET.balanceOf(address(this)); + + console2.log("attacker balance after : "); + console2.log("%e", afterAssetBalance); + + console2.log("attacker loss in balance"); + console2.log("%e", initialAssetBalance - afterAssetBalance); + + assertLe(attackerGainFromAlice, lossFromDonation, "attack must not be profitable"); + assertLe(afterAssetBalance, initialAssetBalance, "attacker must not be profitable"); + assertLe(1e18, initialAssetBalance - afterAssetBalance, "attacker loss greater than amount griefed"); + } +} diff --git a/test/fork/fuzz/handlers-base/BalancerFlashloanDirectMintHandler.t.sol b/test/fork/fuzz/handlers-base/BalancerFlashloanDirectMintHandler.t.sol index 1575782c..92479273 100644 --- a/test/fork/fuzz/handlers-base/BalancerFlashloanDirectMintHandler.t.sol +++ b/test/fork/fuzz/handlers-base/BalancerFlashloanDirectMintHandler.t.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.21; import { LstHandler_ForkBase } from "../../../helpers/handlers/LstHandlerForkBase.sol"; import { WadRayMath, RAY } from "../../../../src/libraries/math/WadRayMath.sol"; import { BalancerFlashloanDirectMintHandler } from "../../../../src/flash/BalancerFlashloanDirectMintHandler.sol"; +import { ISpotOracle } from "../../../../src/interfaces/ISpotOracle.sol"; import { IERC20 } from "@openzeppelin/contracts/interfaces/IERC20.sol"; @@ -23,7 +24,7 @@ abstract contract BalancerFlashloanDirectMintHandler_FuzzTest is LstHandler_Fork _getProviderLibrary().getEthAmountInForLstAmountOut(resultingCollateral - initialDeposit); uint256 ilkRate = ionPool.rate(_getIlkIndex()); - uint256 ilkSpot = ionPool.spot(_getIlkIndex()).getSpot(); + uint256 ilkSpot = ISpotOracle(lens.spot(iIonPool, _getIlkIndex())).getSpot(); // Calculating this way emulates the newTotalDebt value in IonPool uint256 newTotalDebt = resultingDebt.rayDivUp(ilkRate) * ilkRate; @@ -56,7 +57,7 @@ abstract contract BalancerFlashloanDirectMintHandler_FuzzTest is LstHandler_Fork _getProviderLibrary().getEthAmountInForLstAmountOut(resultingCollateral - initialDeposit); uint256 ilkRate = ionPool.rate(_getIlkIndex()); - uint256 ilkSpot = ionPool.spot(_getIlkIndex()).getSpot(); + uint256 ilkSpot = ISpotOracle(lens.spot(iIonPool, _getIlkIndex())).getSpot(); uint256 newTotalDebt = resultingDebt.rayDivUp(ilkRate) * ilkRate; bool unsafePositionChange = newTotalDebt > resultingCollateral * ilkSpot; diff --git a/test/fork/fuzz/handlers-base/PtHandler.t.sol b/test/fork/fuzz/handlers-base/PtHandler.t.sol index 5d85da23..3604e004 100644 --- a/test/fork/fuzz/handlers-base/PtHandler.t.sol +++ b/test/fork/fuzz/handlers-base/PtHandler.t.sol @@ -1,7 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.21; +import { SpotOracle } from "./../../../../src/oracles/spot/SpotOracle.sol"; import { WadRayMath, RAY } from "../../../../src/libraries/math/WadRayMath.sol"; +import { IIonPool } from "./../../../../src/interfaces/IIonPool.sol"; import { PtHandler_ForkBase } from "../../../helpers/handlers/PtHandlerBase.sol"; @@ -31,7 +33,7 @@ abstract contract PtHandler_FuzzTest is PtHandler_ForkBase { uint256 additionalDebt = quote; uint256 ilkRate = ionPool.rate(_getIlkIndex()); - uint256 ilkSpot = ionPool.spot(_getIlkIndex()).getSpot(); + uint256 ilkSpot = SpotOracle(lens.spot(IIonPool(address(ionPool)), _getIlkIndex())).getSpot(); // Calculating this way emulates the newTotalDebt value in IonPool uint256 newTotalDebt = additionalDebt.rayDivUp(ilkRate) * ilkRate; diff --git a/test/fork/fuzz/handlers-base/UniswapFlashswapDirectMintHandler.t.sol b/test/fork/fuzz/handlers-base/UniswapFlashswapDirectMintHandler.t.sol index e19b7d65..6ed5323e 100644 --- a/test/fork/fuzz/handlers-base/UniswapFlashswapDirectMintHandler.t.sol +++ b/test/fork/fuzz/handlers-base/UniswapFlashswapDirectMintHandler.t.sol @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.21; +import { ISpotOracle } from "../../../../src/interfaces/ISpotOracle.sol"; import { LrtHandler_ForkBase } from "../../../helpers/handlers/LrtHandlerForkBase.sol"; import { UniswapFlashswapDirectMintHandler } from "../../../../src/flash/UniswapFlashswapDirectMintHandler.sol"; import { WadRayMath, RAY } from "../../../../src/libraries/math/WadRayMath.sol"; @@ -41,7 +42,7 @@ abstract contract UniswapFlashswapDirectMintHandler_FuzzTest is LrtHandler_ForkB ionPool.addOperator(address(_getTypedUFDMHandler())); uint256 ilkRate = ionPool.rate(_getIlkIndex()); - uint256 ilkSpot = ionPool.spot(_getIlkIndex()).getSpot(); + uint256 ilkSpot = ISpotOracle(lens.spot(iIonPool, _getIlkIndex())).getSpot(); uint256 maxResultingDebt = resultingCollateral * ilkSpot / 1e27; // Calculating this way emulates the newTotalDebt value in IonPool diff --git a/test/fork/fuzz/handlers-base/UniswapFlashswapDirectMintHandlerWithDust.t.sol b/test/fork/fuzz/handlers-base/UniswapFlashswapDirectMintHandlerWithDust.t.sol index 05f7ff45..16cbb7f3 100644 --- a/test/fork/fuzz/handlers-base/UniswapFlashswapDirectMintHandlerWithDust.t.sol +++ b/test/fork/fuzz/handlers-base/UniswapFlashswapDirectMintHandlerWithDust.t.sol @@ -1,10 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.21; -import { LrtHandler_ForkBase } from "../../../helpers/handlers/LrtHandlerForkBase.sol"; +import { SpotOracle } from "./../../../../src/oracles/spot/SpotOracle.sol"; import { UniswapFlashswapDirectMintHandlerWithDust } from "../../../../src/flash/UniswapFlashswapDirectMintHandlerWithDust.sol"; import { WadRayMath, RAY } from "../../../../src/libraries/math/WadRayMath.sol"; +import { IIonPool } from "./../../../../src/interfaces/IIonPool.sol"; + +import { LrtHandler_ForkBase } from "../../../helpers/handlers/LrtHandlerForkBase.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; @@ -25,7 +28,7 @@ abstract contract UniswapFlashswapDirectMintHandlerWithDust_FuzzTest is LrtHandl ionPool.addOperator(address(_getTypedUFDMHandler())); uint256 ilkRate = ionPool.rate(_getIlkIndex()); - uint256 ilkSpot = ionPool.spot(_getIlkIndex()).getSpot(); + uint256 ilkSpot = SpotOracle(lens.spot(IIonPool(address(ionPool)), _getIlkIndex())).getSpot(); // uint256 maxResultingDebt = resultingCollateral * ilkSpot / 1e27; uint256 maxResultingDebt = diff --git a/test/fork/fuzz/lrt/EtherFiLibrary.t.sol b/test/fork/fuzz/lrt/EtherFiLibrary.t.sol index ce74d121..1152a078 100644 --- a/test/fork/fuzz/lrt/EtherFiLibrary.t.sol +++ b/test/fork/fuzz/lrt/EtherFiLibrary.t.sol @@ -31,7 +31,7 @@ contract EtherFiLibrary_FuzzTest is Test { function testForkFuzz_GetLstAmountOutForEthAmountIn(uint256 ethAmount) external { vm.assume(ethAmount != 0); - vm.assume(ethAmount < type(uint128).max); + vm.assume(ethAmount < type(uint96).max); uint256 lrtAmountOut = EtherFiLibrary.getLstAmountOutForEthAmountIn(WEETH_ADDRESS, ethAmount); diff --git a/test/fork/fuzz/lrt/RenzoLibrary.t.sol b/test/fork/fuzz/lrt/RenzoLibrary.t.sol index 32608412..e15697e2 100644 --- a/test/fork/fuzz/lrt/RenzoLibrary.t.sol +++ b/test/fork/fuzz/lrt/RenzoLibrary.t.sol @@ -238,7 +238,7 @@ contract RenzoLibrary_Comparison_FuzzTest is RenzoLibraryHelper, Test { "old method mint amount out is greater than or equal to new method mint amount out" ); - assertApproxEqAbs(oldMethodEthAmountIn, newMethodEthAmountIn, 1e8, "eth amount in approx eq"); + assertApproxEqAbs(oldMethodEthAmountIn, newMethodEthAmountIn, 1e10, "eth amount in approx eq"); uint256 oldMethodDust = oldMethodActualMintAmountOut - minMintAmount; uint256 newMethodDust = newMethodActualMintAmountOut - minMintAmount; diff --git a/test/fork/fuzz/lst/WstEthHandler.t.sol b/test/fork/fuzz/lst/WstEthHandler.t.sol index d69022f6..d4972d87 100644 --- a/test/fork/fuzz/lst/WstEthHandler.t.sol +++ b/test/fork/fuzz/lst/WstEthHandler.t.sol @@ -17,6 +17,7 @@ import { UniswapFlashswapHandler_FuzzTest, UniswapFlashswapHandler_WithRateChange_FuzzTest } from "../handlers-base/UniswapFlashswapHandler.t.sol"; +import { ISpotOracle } from "../../../../src/interfaces/ISpotOracle.sol"; using LidoLibrary for IWstEth; @@ -41,7 +42,7 @@ contract WstEthHandler_ZapForkFuzzTest is WstEthHandler_ForkBase { uint256 wstEthDepositAmount = MAINNET_WSTETH.getWstETHByStETH(stEthDepositAmount); uint256 ilkRate = ionPool.rate(ilkIndex); - uint256 ilkSpot = ionPool.spot(ilkIndex).getSpot(); + uint256 ilkSpot = ISpotOracle(lens.spot(iIonPool, ilkIndex)).getSpot(); uint256 newTotalDebt = borrowAmount.rayDivDown(ilkRate) * ilkRate; // AmountToBorrow.IS_MAX for depositAndBorrow bool unsafePositionChange = newTotalDebt > wstEthDepositAmount * ilkSpot; @@ -80,7 +81,7 @@ contract WstEthHandler_ZapForkFuzzTest is WstEthHandler_ForkBase { MAINNET_WSTETH.getEthAmountInForLstAmountOut(expectedResultingWstEthDeposit - expectedInitialWstEthDeposit); uint256 ilkRate = ionPool.rate(ilkIndex); - uint256 ilkSpot = ionPool.spot(ilkIndex).getSpot(); + uint256 ilkSpot = ISpotOracle(lens.spot(iIonPool, ilkIndex)).getSpot(); // Calculating this way emulates the newTotalDebt value in IonPool uint256 newTotalDebt = resultingDebt.rayDivUp(ilkRate) * ilkRate; @@ -123,7 +124,7 @@ contract WstEthHandler_ZapForkFuzzTest is WstEthHandler_ForkBase { MAINNET_WSTETH.getEthAmountInForLstAmountOut(expectedResultingWstEthDeposit - expectedInitialWstEthDeposit); uint256 ilkRate = ionPool.rate(ilkIndex); - uint256 ilkSpot = ionPool.spot(ilkIndex).getSpot(); + uint256 ilkSpot = ISpotOracle(lens.spot(iIonPool, ilkIndex)).getSpot(); uint256 newTotalDebt = resultingDebt.rayDivUp(ilkRate) * ilkRate; bool unsafePositionChange = newTotalDebt > expectedResultingWstEthDeposit * ilkSpot; diff --git a/test/helpers/InvariantHelpers.sol b/test/helpers/InvariantHelpers.sol index 4333393e..b06f3896 100644 --- a/test/helpers/InvariantHelpers.sol +++ b/test/helpers/InvariantHelpers.sol @@ -1,6 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.21; +import { IIonLens } from "../../src/interfaces/IIonLens.sol"; +import { IIonPool } from "../../src/interfaces/IIonPool.sol"; import { IonPool } from "../../src/IonPool.sol"; import { WadRayMath } from "../../src/libraries/math/WadRayMath.sol"; @@ -10,8 +12,9 @@ library InvariantHelpers { /** * @return utilizationRate in RAD */ - function getUtilizationRate(IonPool ionPool) internal view returns (uint256 utilizationRate) { - utilizationRate = ionPool.debt().radDivDown(ionPool.normalizedTotalSupply() * ionPool.supplyFactor()); + function getUtilizationRate(IonPool ionPool, IIonLens lens) internal view returns (uint256 utilizationRate) { + IIonPool iIonPool = IIonPool(address(ionPool)); + utilizationRate = lens.debt(iIonPool).radDivDown(ionPool.totalSupply() * ionPool.supplyFactor()); } /** @@ -19,6 +22,7 @@ library InvariantHelpers { */ function getIlkSpecificUtilizationRate( IonPool ionPool, + IIonLens lens, uint16[] memory distributionFactors, uint8 ilkIndex ) @@ -26,11 +30,12 @@ library InvariantHelpers { view returns (uint256 utilizationRate) { + IIonPool iIonPool = IIonPool(address(ionPool)); utilizationRate = // Prevent division by 0 ionPool.totalSupply() == 0 ? 0 - : (ionPool.totalNormalizedDebt(ilkIndex) * ionPool.rate(ilkIndex)) + : (lens.totalNormalizedDebt(iIonPool, ilkIndex) * ionPool.rate(ilkIndex)) / (ionPool.totalSupply().wadMulDown(distributionFactors[ilkIndex].scaleUpToWad(4))); } } diff --git a/test/helpers/IonPoolSharedSetup.sol b/test/helpers/IonPoolSharedSetup.sol index fdea6826..572201c2 100644 --- a/test/helpers/IonPoolSharedSetup.sol +++ b/test/helpers/IonPoolSharedSetup.sol @@ -2,9 +2,11 @@ pragma solidity 0.8.21; import { IonPool } from "../../src/IonPool.sol"; +import { IonLens } from "../../src/periphery/IonLens.sol"; import { IonRegistry } from "../../src/periphery/IonRegistry.sol"; import { InterestRate, IlkData, SECONDS_IN_A_YEAR } from "../../src/InterestRate.sol"; import { IYieldOracle } from "../../src/interfaces/IYieldOracle.sol"; +import { IIonPool } from "../../src/interfaces/IIonPool.sol"; import { GemJoin } from "../../src/join/GemJoin.sol"; import { WadRayMath, WAD } from "../../src/libraries/math/WadRayMath.sol"; import { Whitelist } from "../../src/Whitelist.sol"; @@ -66,7 +68,7 @@ contract IonPoolExposed is IonPool { function addLiquidity(uint256 amount) external { IonPoolStorage storage $ = _getIonPoolStorage(); - $.weth += amount; + $.liquidity += amount; } } @@ -113,6 +115,7 @@ struct Config { abstract contract IonPoolSharedSetup is BaseTestSetup, YieldOracleSharedSetup { Config config; + IIonPool iIonPool; IonPoolExposed ionPool; IonPoolExposed ionPoolImpl; IonRegistry ionRegistry; @@ -180,7 +183,12 @@ abstract contract IonPoolSharedSetup is BaseTestSetup, YieldOracleSharedSetup { GemJoin[] internal gemJoins; MockSpotOracle[] internal spotOracles; + IonLens lens; + constructor() { + lens = new IonLens(); + vm.makePersistent(address(lens)); + config.minimumProfitMargins = Solarray.uint128s(wstEthMinimumProfitMargin, ethXMinimumProfitMargin, swEthMinimumProfitMargin); config.minimumKinkRates = Solarray.uint16s(0, 0, 0); @@ -262,6 +270,7 @@ abstract contract IonPoolSharedSetup is BaseTestSetup, YieldOracleSharedSetup { ionPool = IonPoolExposed( address(new TransparentUpgradeableProxy(address(ionPoolImpl), address(ionProxyAdmin), initializeBytes)) ); + iIonPool = IIonPool(address(ionPool)); ionPool.grantRole(ionPool.ION(), address(this)); ionPool.grantRole(ionPool.PAUSE_ROLE(), address(this)); @@ -307,21 +316,20 @@ abstract contract IonPoolSharedSetup is BaseTestSetup, YieldOracleSharedSetup { assertEq(ionPool.symbol(), SYMBOL, "symbol"); assertEq(ionPool.defaultAdmin(), address(this), "default admin"); - assertEq(ionPool.ilkCount(), collaterals.length, "ilk count"); + assertEq(lens.ilkCount(iIonPool), collaterals.length, "ilk count"); assertEq(ionPool.paused(), false, "pause"); for (uint8 i = 0; i < collaterals.length; i++) { address collateralAddress = address(collaterals[i]); - assertEq(ionPool.addressContains(collateralAddress), true, "address contains"); assertEq(ionPool.getIlkAddress(i), collateralAddress, "ilk address"); - assertEq(ionPool.getIlkIndex(collateralAddress), ilkIndexes[collateralAddress], "ilk index"); + assertEq(lens.getIlkIndex(iIonPool, collateralAddress), ilkIndexes[collateralAddress], "ilk index"); // assertEq(ionPool.totalNormalizedDebt(i), 0); // assertEq(ionPool.rate(i), 1e27); - assertEq(address(ionPool.spot(i)), address(spotOracles[i]), "spot oracle"); + assertEq(address(lens.spot(iIonPool, i)), address(spotOracles[i]), "spot oracle"); - assertEq(ionPool.debtCeiling(i), _getDebtCeiling(i), "debt ceiling"); + assertEq(lens.debtCeiling(iIonPool, i), _getDebtCeiling(i), "debt ceiling"); assertEq(ionPool.dust(i), DUST, "dust"); // (uint256 borrowRate, uint256 reserveFactor) = ionPool.getCurrentBorrowRate(i); diff --git a/test/helpers/RewardModuleSharedSetup.sol b/test/helpers/RewardTokenSharedSetup.sol similarity index 76% rename from test/helpers/RewardModuleSharedSetup.sol rename to test/helpers/RewardTokenSharedSetup.sol index 31d6fbc2..f44cac34 100644 --- a/test/helpers/RewardModuleSharedSetup.sol +++ b/test/helpers/RewardTokenSharedSetup.sol @@ -1,14 +1,14 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.21; -import { RewardModule } from "../../src/reward/RewardModule.sol"; +import { RewardToken } from "../../src/token/RewardToken.sol"; import { WadRayMath } from "../../src/libraries/math/WadRayMath.sol"; import { TransparentUpgradeableProxy } from "../../src/admin/TransparentUpgradeableProxy.sol"; import { ProxyAdmin } from "../../src/admin/ProxyAdmin.sol"; import { BaseTestSetup } from "./BaseTestSetup.sol"; -contract RewardModuleExposed is RewardModule { +contract RewardTokenExposed is RewardToken { function init( address _underlying, address _treasury, @@ -19,7 +19,7 @@ contract RewardModuleExposed is RewardModule { external initializer { - RewardModule._initialize(_underlying, _treasury, decimals_, name_, symbol_); + RewardToken._initialize(_underlying, _treasury, decimals_, name_, symbol_); } // --- Cheats --- @@ -33,7 +33,7 @@ contract RewardModuleExposed is RewardModule { } function mint(address user, uint256 amount) external { - _mint(user, user, amount); + _mint(user, msg.sender, amount); } function mintToTreasury(uint256 amount) external { @@ -54,7 +54,7 @@ contract RewardModuleExposed is RewardModule { { } } -abstract contract RewardModuleSharedSetup is BaseTestSetup { +abstract contract RewardTokenSharedSetup is BaseTestSetup { using WadRayMath for uint256; event Approval(address indexed owner, address indexed spender, uint256 value); @@ -63,7 +63,7 @@ abstract contract RewardModuleSharedSetup is BaseTestSetup { event Mint(address indexed user, uint256 amount, uint256 supplyFactor); event Transfer(address indexed from, address indexed to, uint256 value); - RewardModuleExposed rewardModule; + RewardTokenExposed rewardModule; ProxyAdmin ionProxyAdmin; uint256 sendingUserPrivateKey = 16; @@ -76,43 +76,43 @@ abstract contract RewardModuleSharedSetup is BaseTestSetup { function setUp() public virtual override { super.setUp(); ionProxyAdmin = new ProxyAdmin(address(this)); - RewardModuleExposed rewardModuleImpl = new RewardModuleExposed(); + RewardTokenExposed rewardModuleImpl = new RewardTokenExposed(); bytes memory initializeBytes = abi.encodeWithSelector( - RewardModuleExposed.init.selector, address(underlying), address(TREASURY), DECIMALS, NAME, SYMBOL + RewardTokenExposed.init.selector, address(underlying), address(TREASURY), DECIMALS, NAME, SYMBOL ); - rewardModule = RewardModuleExposed( + rewardModule = RewardTokenExposed( address(new TransparentUpgradeableProxy(address(rewardModuleImpl), address(ionProxyAdmin), initializeBytes)) ); } function test_Initialize() external { ProxyAdmin _admin = new ProxyAdmin(address(this)); - RewardModuleExposed _rewardModuleImpl = new RewardModuleExposed(); + RewardTokenExposed _rewardModuleImpl = new RewardTokenExposed(); bytes memory initializeBytes = abi.encodeWithSelector( - RewardModuleExposed.init.selector, address(0), address(TREASURY), DECIMALS, NAME, SYMBOL + RewardTokenExposed.init.selector, address(0), address(TREASURY), DECIMALS, NAME, SYMBOL ); - vm.expectRevert(RewardModule.InvalidUnderlyingAddress.selector); - rewardModule = RewardModuleExposed( + vm.expectRevert(RewardToken.InvalidUnderlyingAddress.selector); + rewardModule = RewardTokenExposed( address(new TransparentUpgradeableProxy(address(_rewardModuleImpl), address(_admin), initializeBytes)) ); initializeBytes = abi.encodeWithSelector( - RewardModuleExposed.init.selector, address(underlying), address(0), DECIMALS, NAME, SYMBOL + RewardTokenExposed.init.selector, address(underlying), address(0), DECIMALS, NAME, SYMBOL ); - vm.expectRevert(RewardModule.InvalidTreasuryAddress.selector); - rewardModule = RewardModuleExposed( + vm.expectRevert(RewardToken.InvalidTreasuryAddress.selector); + rewardModule = RewardTokenExposed( address(new TransparentUpgradeableProxy(address(_rewardModuleImpl), address(_admin), initializeBytes)) ); initializeBytes = abi.encodeWithSelector( - RewardModuleExposed.init.selector, address(underlying), address(TREASURY), DECIMALS, NAME, SYMBOL + RewardTokenExposed.init.selector, address(underlying), address(TREASURY), DECIMALS, NAME, SYMBOL ); - rewardModule = RewardModuleExposed( + rewardModule = RewardTokenExposed( address(new TransparentUpgradeableProxy(address(_rewardModuleImpl), address(_admin), initializeBytes)) ); } diff --git a/test/helpers/VaultSharedSetup.sol b/test/helpers/VaultSharedSetup.sol new file mode 100644 index 00000000..1fead9b9 --- /dev/null +++ b/test/helpers/VaultSharedSetup.sol @@ -0,0 +1,298 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.21; + +import { WadRayMath, RAY } from "./../../src/libraries/math/WadRayMath.sol"; +import { Vault } from "./../../src/vault/Vault.sol"; +import { IonPool } from "./../../src/IonPool.sol"; +import { IIonPool } from "./../../src/interfaces/IIonPool.sol"; +import { GemJoin } from "./../../src/join/GemJoin.sol"; +import { YieldOracle } from "./../../src/YieldOracle.sol"; +import { IYieldOracle } from "./../../src/interfaces/IYieldOracle.sol"; +import { InterestRate } from "./../../src/InterestRate.sol"; +import { Whitelist } from "./../../src/Whitelist.sol"; +import { ProxyAdmin } from "./../../src/admin/ProxyAdmin.sol"; +import { TransparentUpgradeableProxy } from "./../../src/admin/TransparentUpgradeableProxy.sol"; +import { ERC20PresetMinterPauser } from "./ERC20PresetMinterPauser.sol"; +import { IERC20 } from "openzeppelin-contracts/contracts/interfaces/IERC20.sol"; +import { EnumerableSet } from "openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol"; +import { Math } from "openzeppelin-contracts/contracts/utils/math/Math.sol"; + +import { IonPoolSharedSetup, IonPoolExposed } from "./IonPoolSharedSetup.sol"; + +import "forge-std/Test.sol"; +import { console2 } from "forge-std/console2.sol"; + +using EnumerableSet for EnumerableSet.AddressSet; +using WadRayMath for uint256; +using Math for uint256; + +contract VaultSharedSetup is IonPoolSharedSetup { + using stdStorage for StdStorage; + + StdStorage stdstore1; + + Vault vault; + Vault.MarketsArgs marketsArgs; + Vault.MarketsArgs emptyMarketsArgs; + + // roles + address constant VAULT_ADMIN = address(uint160(uint256(keccak256("VAULT_ADMIN")))); + address constant OWNER = address(uint160(uint256(keccak256("OWNER")))); + address constant ALLOCATOR = address(uint160(uint256(keccak256("ALLOCATOR")))); + + uint48 constant INITIAL_DELAY = 0; + address constant FEE_RECIPIENT = address(uint160(uint256(keccak256("FEE_RECIPIENT")))); + uint256 constant ZERO_FEES = 0; + + uint256 constant MIN_INITIAL_DEPOSIT = 1e3; + + bytes32 constant SALT = keccak256("SALT"); + + IERC20 immutable BASE_ASSET = IERC20(address(new ERC20PresetMinterPauser("Lido Wrapped Staked ETH", "wstETH"))); + IERC20 immutable WEETH = IERC20(address(new ERC20PresetMinterPauser("EtherFi Restaked ETH", "weETH"))); + IERC20 immutable RSETH = IERC20(address(new ERC20PresetMinterPauser("KelpDAO Restaked ETH", "rsETH"))); + IERC20 immutable RSWETH = IERC20(address(new ERC20PresetMinterPauser("Swell Restaked ETH", "rswETH"))); + + IIonPool constant IDLE = IIonPool(address(uint160(uint256(keccak256("IDLE_ASSET_HOLDINGS"))))); + IIonPool weEthIonPool; + IIonPool rsEthIonPool; + IIonPool rswEthIonPool; + + GemJoin weEthGemJoin; + GemJoin rsEthGemJoin; + GemJoin rswEthGemJoin; + + IIonPool[] markets; + + uint256[] ZERO_ALLO_CAPS = new uint256[](3); + + address constant NULL = address(0); + + function setUp() public virtual override { + super.setUp(); + + weEthIonPool = deployIonPool(BASE_ASSET, WEETH, address(this)); + rsEthIonPool = deployIonPool(BASE_ASSET, RSETH, address(this)); + rswEthIonPool = deployIonPool(BASE_ASSET, RSWETH, address(this)); + + markets = new IIonPool[](3); + markets[0] = weEthIonPool; + markets[1] = rsEthIonPool; + markets[2] = rswEthIonPool; + + marketsArgs.marketsToAdd = markets; + marketsArgs.allocationCaps = ZERO_ALLO_CAPS; + marketsArgs.newSupplyQueue = markets; + marketsArgs.newWithdrawQueue = markets; + + vault = new Vault{ salt: SALT }( + BASE_ASSET, FEE_RECIPIENT, ZERO_FEES, "Ion Vault Token", "IVT", INITIAL_DELAY, VAULT_ADMIN, marketsArgs + ); + + BASE_ASSET.approve(address(vault), type(uint256).max); + + vm.startPrank(vault.defaultAdmin()); + + vault.grantRole(vault.OWNER_ROLE(), OWNER); + vault.grantRole(vault.ALLOCATOR_ROLE(), OWNER); // OWNER also needs to be ALLOCATOR in order to update queues + // inside `addSupportedMarkets`. + vault.grantRole(vault.ALLOCATOR_ROLE(), ALLOCATOR); + + vm.stopPrank(); + + weEthGemJoin = + new GemJoin(IonPool(address(weEthIonPool)), IERC20(weEthIonPool.getIlkAddress(0)), 0, address(this)); + rsEthGemJoin = + new GemJoin(IonPool(address(rsEthIonPool)), IERC20(rsEthIonPool.getIlkAddress(0)), 0, address(this)); + rswEthGemJoin = + new GemJoin(IonPool(address(rswEthIonPool)), IERC20(rswEthIonPool.getIlkAddress(0)), 0, address(this)); + + weEthIonPool.grantRole(weEthIonPool.GEM_JOIN_ROLE(), address(weEthGemJoin)); + rsEthIonPool.grantRole(rsEthIonPool.GEM_JOIN_ROLE(), address(rsEthGemJoin)); + rswEthIonPool.grantRole(rswEthIonPool.GEM_JOIN_ROLE(), address(rswEthGemJoin)); + } + + function setERC20Balance(address token, address usr, uint256 amt) public { + stdstore1.target(token).sig(IERC20(token).balanceOf.selector).with_key(usr).checked_write(amt); + require(IERC20(token).balanceOf(usr) == amt, "balance not set"); + } + + // deploys a single IonPool with default configs + function deployIonPool( + IERC20 underlying, + IERC20 collateral, + address initialDefaultAdmin + ) + internal + returns (IIonPool ionPool) + { + IYieldOracle yieldOracle = _getYieldOracle(); + interestRateModule = new InterestRate(ilkConfigs, yieldOracle); + + Whitelist whitelist = _getWhitelist(); + + bytes memory initializeBytes = abi.encodeWithSelector( + IonPool.initialize.selector, + underlying, + address(this), + DECIMALS, + NAME, + SYMBOL, + initialDefaultAdmin, + interestRateModule, + whitelist + ); + + IonPoolExposed ionPoolImpl = new IonPoolExposed(); + ProxyAdmin ionProxyAdmin = new ProxyAdmin(address(this)); + + IonPoolExposed ionPoolProxy = IonPoolExposed( + address(new TransparentUpgradeableProxy(address(ionPoolImpl), address(ionProxyAdmin), initializeBytes)) + ); + + ionPool = IIonPool(address(ionPoolProxy)); + + ionPool.grantRole(ionPool.ION(), address(this)); + ionPool.grantRole(ionPool.PAUSE_ROLE(), address(this)); + ionPool.updateSupplyCap(type(uint256).max); + + ionPool.initializeIlk(address(collateral)); + ionPool.updateIlkSpot(0, address(_getSpotOracle())); + ionPool.updateIlkDebtCeiling(0, _getDebtCeiling(0)); + + GemJoin gemJoin = new GemJoin(IonPool(address(ionPool)), collateral, 0, address(this)); + ionPool.grantRole(ionPool.GEM_JOIN_ROLE(), address(gemJoin)); + } + + function claimAfterDeposit(uint256 currShares, uint256 amount, uint256 supplyFactor) internal returns (uint256) { + uint256 sharesMinted = amount.rayDivDown(supplyFactor); + uint256 resultingShares = currShares + sharesMinted; + return resultingShares.rayMulDown(supplyFactor); + } + + function claimAfterWithdraw(uint256 currShares, uint256 amount, uint256 supplyFactor) internal returns (uint256) { + uint256 sharesBurned = amount.rayDivUp(supplyFactor); + uint256 resultingShares = currShares - sharesBurned; + return resultingShares.rayMulDown(supplyFactor); + } + + // --- Privileged Helper Functions --- + + // Updates in the order of supply queue + function updateSupplyCaps(Vault _vault, uint256 cap1, uint256 cap2, uint256 cap3) internal { + _vault.supplyQueue(0).updateSupplyCap(cap1); + _vault.supplyQueue(1).updateSupplyCap(cap2); + _vault.supplyQueue(2).updateSupplyCap(cap3); + } + + // Updates in the order of the supplyQueue array + function updateAllocationCaps(Vault _vault, uint256 cap1, uint256 cap2, uint256 cap3) internal { + uint256[] memory caps = new uint256[](3); + caps[0] = cap1; + caps[1] = cap2; + caps[2] = cap3; + + IIonPool[] memory ionPools = new IIonPool[](3); + ionPools[0] = _vault.supplyQueue(0); + ionPools[1] = _vault.supplyQueue(1); + ionPools[2] = _vault.supplyQueue(2); + + vm.prank(OWNER); + _vault.updateAllocationCaps(ionPools, caps); + } + + function updateSupplyQueue(Vault _vault, IIonPool pool1, IIonPool pool2, IIonPool pool3) internal { + IIonPool[] memory supplyQueue = new IIonPool[](3); + supplyQueue[0] = pool1; + supplyQueue[1] = pool2; + supplyQueue[2] = pool3; + vm.prank(ALLOCATOR); + _vault.updateSupplyQueue(supplyQueue); + } + + function updateWithdrawQueue(Vault _vault, IIonPool pool1, IIonPool pool2, IIonPool pool3) internal { + IIonPool[] memory queue = new IIonPool[](3); + queue[0] = pool1; + queue[1] = pool2; + queue[2] = pool3; + vm.prank(ALLOCATOR); + _vault.updateWithdrawQueue(queue); + } + + // -- Exact Rounding Error Equations --- + + function postDepositClaimRE(uint256 depositAmount, uint256 supplyFactor) internal returns (uint256) { + return (supplyFactor + 2) / RAY + 1; + } + + // The difference between the expected total assets after withdrawal and the + // actual total assets after withdrawal. + // expected = prev total assets - withdraw amount + // actual = resulting total assets on contract + // rounding error = expected - actual + // This equation is max bounded to supplyFactor / RAY. + function totalAssetsREAfterWithdraw(uint256 withdrawAmount, uint256 supplyFactor) internal returns (uint256) { + return (supplyFactor - withdrawAmount * RAY % supplyFactor) / RAY; + } + + function maxWithdrawREAfterWithdraw( + uint256 withdrawAmount, + uint256 totalAssets, + uint256 totalSupply + ) + internal + returns (uint256) + { + totalAssets += 1; + return (totalAssets - withdrawAmount * totalSupply % totalAssets) / totalSupply; + } + + // --- IonPool Interactions --- + + function borrow(address borrower, IIonPool pool, GemJoin gemJoin, uint256 depositAmt, uint256 borrowAmt) internal { + IERC20 collateralAsset = IERC20(address(pool.getIlkAddress(0))); + + setERC20Balance(address(collateralAsset), borrower, depositAmt); + + vm.startPrank(borrower); + collateralAsset.approve(address(gemJoin), depositAmt); + gemJoin.join(borrower, depositAmt); + // move collateral to vault + pool.depositCollateral(0, borrower, borrower, depositAmt, emptyProof); + pool.borrow(0, borrower, borrower, borrowAmt, emptyProof); + vm.stopPrank(); + } + + function supply(address lender, IIonPool pool, uint256 supplyAmt) internal { + IERC20 underlying = IERC20(pool.underlying()); + + setERC20Balance(address(underlying), lender, supplyAmt); + + vm.startPrank(lender); + underlying.approve(address(pool), type(uint256).max); + pool.supply(lender, supplyAmt, emptyProof); + vm.stopPrank(); + } + + function newAddress(bytes memory str) internal returns (address) { + return address(uint160(uint256(keccak256(str)))); + } + + function withSupplyFactor() internal { + IonPoolExposed(address(weEthIonPool)).setSupplyFactor(1.13131323e27); + IonPoolExposed(address(rsEthIonPool)).setSupplyFactor(1.1585678e27); + IonPoolExposed(address(rswEthIonPool)).setSupplyFactor(1.838194e27); + } + + function withInflatedSupplyFactor() internal { + IonPoolExposed(address(weEthIonPool)).setSupplyFactor(5.1336673e27); + IonPoolExposed(address(rsEthIonPool)).setSupplyFactor(7.1336673e27); + IonPoolExposed(address(rswEthIonPool)).setSupplyFactor(10.1336673e27); + } + + function _zeroFloorSub(uint256 x, uint256 y) internal pure returns (uint256 z) { + assembly { + z := mul(gt(x, y), sub(x, y)) + } + } +} diff --git a/test/integration/concrete/WeEthIonPool.t.sol b/test/integration/concrete/WeEthIonPool.t.sol index f99f1c66..ab566eb9 100644 --- a/test/integration/concrete/WeEthIonPool.t.sol +++ b/test/integration/concrete/WeEthIonPool.t.sol @@ -126,7 +126,7 @@ contract WeEthIonPool_IntegrationTest is WeEthIonPoolSharedSetup { vm.stopPrank(); assertEq(ionPool.balanceOf(lenderA), lenderAFirstSupplyAmount, "lender balance after 1st supply"); - assertEq(ionPool.weth(), lenderAFirstSupplyAmount, "liquidity after 1st supply"); + assertEq(lens.liquidity(iIonPool), lenderAFirstSupplyAmount, "liquidity after 1st supply"); /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* ACTION 2 */ @@ -232,40 +232,40 @@ contract WeEthIonPool_IntegrationTest is WeEthIonPoolSharedSetup { /* ACTION 6 */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - vm.warp(block.timestamp + 812); + // vm.warp(block.timestamp + 812); - uint256 borrowerBRepayAmount1 = 100e18; + // uint256 borrowerBRepayAmount1 = 100e18; - uint256 normalizedDebtBeforeRepay = ionPool.normalizedDebt(0, borrowerB); + // uint256 normalizedDebtBeforeRepay = ionPool.normalizedDebt(0, borrowerB); - vm.startPrank(borrowerB); - WSTETH_ADDRESS.approve(address(ionPool), type(uint256).max); - ionPool.repay(0, borrowerB, borrowerB, borrowerBRepayAmount1); + // vm.startPrank(borrowerB); + // WSTETH_ADDRESS.approve(address(ionPool), type(uint256).max); + // ionPool.repay(0, borrowerB, borrowerB, borrowerBRepayAmount1); - assertEq( - ionPool.normalizedDebt(0, borrowerB), - normalizedDebtBeforeRepay - borrowerBRepayAmount1, - "borrowerB normalized debt after 1st repayment" - ); + // assertEq( + // ionPool.normalizedDebt(0, borrowerB), + // normalizedDebtBeforeRepay - borrowerBRepayAmount1, + // "borrowerB normalized debt after 1st repayment" + // ); - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ACTION 7 */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ + // /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ + // /* ACTION 7 */ + // /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - vm.warp(block.timestamp + 329); + // vm.warp(block.timestamp + 329); - uint256 borrowerBRepayOnBehalfOfAAmount = 30e18; + // uint256 borrowerBRepayOnBehalfOfAAmount = 30e18; - uint256 normalizedDebtABefore = ionPool.normalizedDebt(0, borrowerA); + // uint256 normalizedDebtABefore = ionPool.normalizedDebt(0, borrowerA); - ionPool.repay(0, borrowerA, borrowerB, borrowerBRepayOnBehalfOfAAmount); - vm.stopPrank(); + // ionPool.repay(0, borrowerA, borrowerB, borrowerBRepayOnBehalfOfAAmount); + // vm.stopPrank(); - assertEq( - ionPool.normalizedDebt(0, borrowerA), - normalizedDebtABefore - borrowerBRepayOnBehalfOfAAmount, - "borrowerA normalized debt after repayment from B on behalf of borrowerA" - ); + // assertEq( + // ionPool.normalizedDebt(0, borrowerA), + // normalizedDebtABefore - borrowerBRepayOnBehalfOfAAmount, + // "borrowerA normalized debt after repayment from B on behalf of borrowerA" + // ); } function _getYieldOracle() internal virtual override returns (IYieldOracle) { diff --git a/test/invariant/IonPool/ActorManager.t.sol b/test/invariant/IonPool/ActorManager.t.sol index 91faabb7..ea0f94fd 100644 --- a/test/invariant/IonPool/ActorManager.t.sol +++ b/test/invariant/IonPool/ActorManager.t.sol @@ -4,6 +4,8 @@ pragma solidity 0.8.21; import { GemJoin } from "../../../src/join/GemJoin.sol"; import { IonPool } from "../../../src/IonPool.sol"; import { WadRayMath } from "../../../src/libraries/math/WadRayMath.sol"; +import { IIonLens } from "../../../src/interfaces/IIonLens.sol"; +import { IIonPool } from "../../../src/interfaces/IIonPool.sol"; import { IonPoolSharedSetup } from "../../helpers/IonPoolSharedSetup.sol"; import { InvariantHelpers } from "../../helpers/InvariantHelpers.sol"; @@ -18,17 +20,22 @@ using WadRayMath for uint256; contract ActorManager is CommonBase, StdCheats, StdUtils { IonPool ionPool; + IIonPool iIonPool; + IIonLens lens; LenderHandler[] internal lenders; BorrowerHandler[] internal borrowers; LiquidatorHandler[] internal liquidators; constructor( IonPool _ionPool, + IIonLens _lens, LenderHandler[] memory _lenders, BorrowerHandler[] memory _borrowers, LiquidatorHandler[] memory _liquidators ) { ionPool = _ionPool; + iIonPool = IIonPool(address(_ionPool)); + lens = _lens; lenders = _lenders; borrowers = _borrowers; liquidators = _liquidators; @@ -44,7 +51,7 @@ contract ActorManager is CommonBase, StdCheats, StdUtils { ) public { - uint256 globalUtilizationRate = InvariantHelpers.getUtilizationRate(ionPool); + uint256 globalUtilizationRate = InvariantHelpers.getUtilizationRate(ionPool, lens); if (globalUtilizationRate < 0.5e45) { functionIndex = bound(functionIndex, 0, 4); @@ -105,14 +112,14 @@ contract ActorManager is CommonBase, StdCheats, StdUtils { function borrow(uint128 borrowerIndex, uint128 ilkIndex, uint128 amount, uint128 warpTimeAmount) internal { borrowerIndex = uint128(bound(borrowerIndex, 0, borrowers.length - 1)); - ilkIndex = uint128(bound(ilkIndex, 0, ionPool.ilkCount() - 1)); + ilkIndex = uint128(bound(ilkIndex, 0, lens.ilkCount(iIonPool) - 1)); borrowers[borrowerIndex].borrow(uint8(ilkIndex), amount, warpTimeAmount); } function repay(uint128 borrowerIndex, uint128 ilkIndex, uint128 amount, uint128 warpTimeAmount) internal { borrowerIndex = uint128(bound(borrowerIndex, 0, borrowers.length - 1)); - ilkIndex = uint128(bound(ilkIndex, 0, ionPool.ilkCount() - 1)); + ilkIndex = uint128(bound(ilkIndex, 0, lens.ilkCount(iIonPool) - 1)); borrowers[borrowerIndex].repay(uint8(ilkIndex), amount, warpTimeAmount); } @@ -126,7 +133,7 @@ contract ActorManager is CommonBase, StdCheats, StdUtils { internal { borrowerIndex = uint128(bound(borrowerIndex, 0, borrowers.length - 1)); - ilkIndex = uint128(bound(ilkIndex, 0, ionPool.ilkCount() - 1)); + ilkIndex = uint128(bound(ilkIndex, 0, lens.ilkCount(iIonPool) - 1)); borrowers[borrowerIndex].depositCollateral(uint8(ilkIndex), amount, warpTimeAmount); } @@ -140,21 +147,21 @@ contract ActorManager is CommonBase, StdCheats, StdUtils { internal { borrowerIndex = uint128(bound(borrowerIndex, 0, borrowers.length - 1)); - ilkIndex = uint128(bound(ilkIndex, 0, ionPool.ilkCount() - 1)); + ilkIndex = uint128(bound(ilkIndex, 0, lens.ilkCount(iIonPool) - 1)); borrowers[borrowerIndex].withdrawCollateral(uint8(ilkIndex), amount, warpTimeAmount); } function gemJoin(uint128 borrowerIndex, uint128 ilkIndex, uint128 amount, uint128 warpTimeAmount) internal { borrowerIndex = uint128(bound(borrowerIndex, 0, borrowers.length - 1)); - ilkIndex = uint128(bound(ilkIndex, 0, ionPool.ilkCount() - 1)); + ilkIndex = uint128(bound(ilkIndex, 0, lens.ilkCount(iIonPool) - 1)); borrowers[borrowerIndex].gemJoin(uint8(ilkIndex), amount, warpTimeAmount); } function gemExit(uint128 borrowerIndex, uint128 ilkIndex, uint128 amount, uint128 warpTimeAmount) internal { borrowerIndex = uint128(bound(borrowerIndex, 0, borrowers.length - 1)); - ilkIndex = uint128(bound(ilkIndex, 0, ionPool.ilkCount() - 1)); + ilkIndex = uint128(bound(ilkIndex, 0, lens.ilkCount(iIonPool) - 1)); borrowers[borrowerIndex].gemExit(uint8(ilkIndex), amount, warpTimeAmount); } @@ -185,13 +192,13 @@ contract IonPool_InvariantTest is IonPoolSharedSetup { super.setUp(); // Disable debt ceiling - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { ionPool.updateIlkDebtCeiling(i, _getDebtCeiling(i)); } for (uint256 i = 0; i < AMOUNT_LENDERS; i++) { LenderHandler lender = - new LenderHandler(ionPool, ionRegistry, underlying, config.distributionFactors, log, report); + new LenderHandler(ionPool, lens, ionRegistry, underlying, config.distributionFactors, log, report); lenders.push(lender); underlying.grantRole(underlying.MINTER_ROLE(), address(lender)); @@ -201,7 +208,7 @@ contract IonPool_InvariantTest is IonPoolSharedSetup { for (uint256 i = 0; i < AMOUNT_BORROWERS; i++) { BorrowerHandler borrower = new BorrowerHandler( - ionPool, ionRegistry, underlying, mintableCollaterals, config.distributionFactors, log, report + ionPool, lens, ionRegistry, underlying, mintableCollaterals, config.distributionFactors, log, report ); borrowers.push(borrower); for (uint8 j = 0; j < collaterals.length; j++) { @@ -213,7 +220,7 @@ contract IonPool_InvariantTest is IonPoolSharedSetup { borrower.borrow(j, INITIAL_BORROWER_BORROW_AMOUNT, 0); } } - actorManager = new ActorManager(ionPool, lenders, borrowers, liquidators); + actorManager = new ActorManager(ionPool, lens, lenders, borrowers, liquidators); targetContract(address(actorManager)); } @@ -241,17 +248,17 @@ contract IonPool_InvariantTest is IonPoolSharedSetup { function invariant_LiquidityInPoolPlusDebtToPoolStrictlyGreaterThanOrEqualToTotalSupply() external returns (bool) { uint256 totalDebt; - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { uint256 totalNormalizedDebts; for (uint256 j = 0; j < borrowers.length; j++) { totalNormalizedDebts += ionPool.normalizedDebt(i, address(borrowers[j])); } - uint256 ilkRate = ionPool.rateUnaccrued(i); + uint256 ilkRate = lens.rateUnaccrued(iIonPool, i); totalDebt += totalNormalizedDebts.rayMulDown(ilkRate); } - assertGe(ionPool.weth() + totalDebt, ionPool.totalSupplyUnaccrued()); + assertGe(lens.liquidity(iIonPool) + totalDebt, ionPool.totalSupplyUnaccrued()); assertGe( - ionPool.weth().scaleUpToRad(18) + ionPool.debtUnaccrued(), + lens.liquidity(iIonPool).scaleUpToRad(18) + lens.debtUnaccrued(iIonPool), ionPool.normalizedTotalSupplyUnaccrued() * ionPool.supplyFactorUnaccrued() ); @@ -259,22 +266,22 @@ contract IonPool_InvariantTest is IonPoolSharedSetup { } function invariant_BorrowerNormalizedDebtsSumToTotalNormalizedDebt() external returns (bool) { - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { uint256 sumBorrowerNormalizedDebts; for (uint256 j = 0; j < borrowers.length; j++) { sumBorrowerNormalizedDebts += ionPool.normalizedDebt(i, address(borrowers[j])); } - assertEq(sumBorrowerNormalizedDebts, ionPool.totalNormalizedDebt(i)); + assertEq(sumBorrowerNormalizedDebts, lens.totalNormalizedDebt(iIonPool, i)); } return !failed(); } function invariant_SumOfAllGemAndCollateralEqualsTotalGemInGemJoin() external returns (bool) { - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { uint256 gemAndCollateralSum; for (uint256 j = 0; j < borrowers.length; j++) { - gemAndCollateralSum += ionPool.gem(i, address(borrowers[j])); + gemAndCollateralSum += lens.gem(iIonPool, i, address(borrowers[j])); } for (uint256 j = 0; j < borrowers.length; j++) { gemAndCollateralSum += ionPool.collateral(i, address(borrowers[j])); @@ -291,12 +298,12 @@ contract IonPool_InvariantTest is IonPoolSharedSetup { returns (bool) { uint256 totalDebt; - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { - uint256 totalNormalizedDebt = ionPool.totalNormalizedDebt(i); - uint256 ilkRate = ionPool.rateUnaccrued(i); + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { + uint256 totalNormalizedDebt = lens.totalNormalizedDebt(iIonPool, i); + uint256 ilkRate = lens.rateUnaccrued(iIonPool, i); totalDebt += totalNormalizedDebt * ilkRate; } - assertEq(totalDebt + ionPool.totalUnbackedDebt(), ionPool.debtUnaccrued()); + assertEq(totalDebt + lens.totalUnbackedDebt(iIonPool), lens.debtUnaccrued(iIonPool)); return !failed(); } diff --git a/test/invariant/IonPool/Handlers.t.sol b/test/invariant/IonPool/Handlers.t.sol index 5bb32413..8aa28b5d 100644 --- a/test/invariant/IonPool/Handlers.t.sol +++ b/test/invariant/IonPool/Handlers.t.sol @@ -5,6 +5,9 @@ import { WadRayMath, RAY } from "../../../src/libraries/math/WadRayMath.sol"; import { IonRegistry } from "../../../src/periphery/IonRegistry.sol"; import { GemJoin } from "../../../src/join/GemJoin.sol"; import { SECONDS_IN_A_YEAR } from "../../../src/InterestRate.sol"; +import { IIonLens } from "../../../src/interfaces/IIonLens.sol"; +import { IIonPool } from "../../../src/interfaces/IIonPool.sol"; +import { ISpotOracle } from "../../../src/interfaces/ISpotOracle.sol"; import { IonPoolExposed } from "../../helpers/IonPoolSharedSetup.sol"; import { ERC20PresetMinterPauser } from "../../helpers/ERC20PresetMinterPauser.sol"; @@ -61,6 +64,8 @@ abstract contract Handler is CommonBase, StdCheats, StdUtils { using DecimalToFixedPoint for uint256; IonPoolExposed internal immutable ionPool; + IIonPool internal immutable iIonPool; + IIonLens internal immutable lens; ERC20PresetMinterPauser internal immutable underlying; IonRegistry internal immutable registry; @@ -77,6 +82,7 @@ abstract contract Handler is CommonBase, StdCheats, StdUtils { constructor( IonPoolExposed _ionPool, + IIonLens _lens, ERC20PresetMinterPauser _underlying, IonRegistry _registry, uint16[] memory _distributionFactors, @@ -84,6 +90,8 @@ abstract contract Handler is CommonBase, StdCheats, StdUtils { bool _report ) { ionPool = _ionPool; + iIonPool = IIonPool(address(_ionPool)); + lens = _lens; underlying = _underlying; registry = _registry; distributionFactors = _distributionFactors; @@ -149,21 +157,23 @@ abstract contract Handler is CommonBase, StdCheats, StdUtils { globalState.supplyFactor = ionPool.supplyFactor(); globalState.totalSupply = ionPool.totalSupply(); - globalState.totalDebt = ionPool.debt(); - globalState.wethLiquidity = ionPool.weth(); - globalState.utilizationRate = InvariantHelpers.getUtilizationRate(ionPool); + globalState.totalDebt = lens.debt(iIonPool); + globalState.wethLiquidity = lens.liquidity(iIonPool); + globalState.utilizationRate = InvariantHelpers.getUtilizationRate(ionPool, lens); - require(ilkIndexedState.length == ionPool.ilkCount(), "invariant/IonPool/Handlers.t.sol: Ilk count mismatch"); + require( + ilkIndexedState.length == lens.ilkCount(iIonPool), "invariant/IonPool/Handlers.t.sol: Ilk count mismatch" + ); for (uint256 i = 0; i < ilkIndexedState.length; ++i) { uint8 _ilkIndex = uint8(i); - ilkIndexedState[i].totalNormalizedDebt = ionPool.totalNormalizedDebt(_ilkIndex); + ilkIndexedState[i].totalNormalizedDebt = lens.totalNormalizedDebt(iIonPool, _ilkIndex); ilkIndexedState[i].rate = ionPool.rate(_ilkIndex); ilkIndexedState[i].totalGem = registry.gemJoins(_ilkIndex).totalGem(); (uint256 currentBorrowRate,) = ionPool.getCurrentBorrowRate(_ilkIndex); ilkIndexedState[i].newInterestRatePerSecond = currentBorrowRate; ilkIndexedState[i].newInterestRatePerYear = ((currentBorrowRate - RAY) * SECONDS_IN_A_YEAR) + RAY; ilkIndexedState[i].utilizationRate = - InvariantHelpers.getIlkSpecificUtilizationRate(ionPool, distributionFactors, _ilkIndex); + InvariantHelpers.getIlkSpecificUtilizationRate(ionPool, lens, distributionFactors, _ilkIndex); } vm.writeLine(REPORT_FILE, ""); @@ -220,13 +230,14 @@ contract LenderHandler is Handler { constructor( IonPoolExposed _ionPool, + IIonLens _lens, IonRegistry _registry, ERC20PresetMinterPauser _underlying, uint16[] memory _distributionFactors, bool _log, bool _report ) - Handler(_ionPool, _underlying, _registry, _distributionFactors, _log, _report) + Handler(_ionPool, _lens, _underlying, _registry, _distributionFactors, _log, _report) { underlying.approve(address(ionPool), type(uint256).max); } @@ -251,7 +262,7 @@ contract LenderHandler is Handler { function withdraw(uint256 amount, uint256 warpTimeAmount) public { // To prevent reverts, limit withdraw amounts to the available liquidity in the pool - uint256 balance = Math.min(ionPool.weth(), ionPool.balanceOf(address(this))); + uint256 balance = Math.min(lens.liquidity(iIonPool), ionPool.balanceOf(address(this))); amount = bound(amount, 0, balance); _warpTime(warpTimeAmount); @@ -274,6 +285,7 @@ contract BorrowerHandler is Handler { constructor( IonPoolExposed _ionPool, + IIonLens _lens, IonRegistry _registry, ERC20PresetMinterPauser _underlying, ERC20PresetMinterPauser[] memory _collaterals, @@ -281,7 +293,7 @@ contract BorrowerHandler is Handler { bool _log, bool _report ) - Handler(_ionPool, _underlying, _registry, _distributionFactors, _log, _report) + Handler(_ionPool, _lens, _underlying, _registry, _distributionFactors, _log, _report) { underlying.approve(address(_ionPool), type(uint256).max); ionPool.addOperator(address(_ionPool)); @@ -289,7 +301,7 @@ contract BorrowerHandler is Handler { } function borrow(uint8 ilkIndex, uint256 normalizedAmount, uint256 warpTimeAmount) public { - uint8 _ilkIndex = uint8(bound(ilkIndex, 0, ionPool.ilkCount())); + uint8 _ilkIndex = uint8(bound(ilkIndex, 0, lens.ilkCount(iIonPool))); _warpTime(warpTimeAmount); @@ -297,7 +309,7 @@ contract BorrowerHandler is Handler { uint256 maxAdditionalNormalizedDebt; { uint256 vaultCollateral = ionPool.collateral(_ilkIndex, address(this)); - uint256 ilkSpot = ionPool.spot(_ilkIndex).getSpot(); + uint256 ilkSpot = ISpotOracle(lens.spot(iIonPool, _ilkIndex)).getSpot(); uint256 vaultNormalizedDebt = ionPool.normalizedDebt(_ilkIndex, address(this)); uint256 currentDebt = vaultNormalizedDebt * ilkRate; @@ -309,7 +321,7 @@ contract BorrowerHandler is Handler { maxAdditionalNormalizedDebt = _min(maxAdditionalDebt / ilkRate, type(uint64).max); } - uint256 poolLiquidity = ionPool.weth(); + uint256 poolLiquidity = lens.liquidity(iIonPool); uint256 normalizedPoolLiquidity = poolLiquidity.rayDivDown(ilkRate); normalizedAmount = _min(bound(normalizedAmount, 0, maxAdditionalNormalizedDebt), normalizedPoolLiquidity); @@ -322,7 +334,7 @@ contract BorrowerHandler is Handler { } function repay(uint8 ilkIndex, uint256 normalizedAmount, uint256 warpTimeAmount) public { - uint8 _ilkIndex = uint8(bound(ilkIndex, 0, ionPool.ilkCount())); + uint8 _ilkIndex = uint8(bound(ilkIndex, 0, lens.ilkCount(iIonPool))); uint256 currentNormalizedDebt = ionPool.normalizedDebt(_ilkIndex, address(this)); normalizedAmount = bound(normalizedAmount, 0, currentNormalizedDebt); @@ -336,9 +348,9 @@ contract BorrowerHandler is Handler { } function depositCollateral(uint8 ilkIndex, uint256 amount, uint256 warpTimeAmount) public { - uint8 _ilkIndex = uint8(bound(ilkIndex, 0, ionPool.ilkCount())); + uint8 _ilkIndex = uint8(bound(ilkIndex, 0, lens.ilkCount(iIonPool))); - amount = bound(amount, 0, ionPool.gem(_ilkIndex, address(this))); + amount = bound(amount, 0, lens.gem(iIonPool, _ilkIndex, address(this))); if (LOG) console.log("depositCollateral", amount); @@ -349,13 +361,13 @@ contract BorrowerHandler is Handler { } function withdrawCollateral(uint8 ilkIndex, uint256 amount, uint256 warpTimeAmount) public { - uint8 _ilkIndex = uint8(bound(ilkIndex, 0, ionPool.ilkCount())); + uint8 _ilkIndex = uint8(bound(ilkIndex, 0, lens.ilkCount(iIonPool))); uint256 ilkRate = ionPool.rate(_ilkIndex); uint256 maxRemovableCollateral; { uint256 vaultCollateral = ionPool.collateral(_ilkIndex, address(this)); - uint256 ilkSpot = ionPool.spot(_ilkIndex).getSpot(); + uint256 ilkSpot = ISpotOracle(lens.spot(iIonPool, _ilkIndex)).getSpot(); uint256 vaultNormalizedDebt = ionPool.normalizedDebt(_ilkIndex, address(this)); uint256 currentDebt = vaultNormalizedDebt * ilkRate; @@ -374,7 +386,7 @@ contract BorrowerHandler is Handler { } function gemJoin(uint8 ilkIndex, uint256 amount, uint256 warpTimeAmount) public { - uint8 _ilkIndex = uint8(bound(ilkIndex, 0, ionPool.ilkCount())); + uint8 _ilkIndex = uint8(bound(ilkIndex, 0, lens.ilkCount(iIonPool))); amount = bound(amount, 0, type(uint256).max); GemJoin _gemJoin = registry.gemJoins(_ilkIndex); @@ -394,9 +406,9 @@ contract BorrowerHandler is Handler { } function gemExit(uint8 ilkIndex, uint256 amount, uint256 warpTimeAmount) public { - uint8 _ilkIndex = uint8(bound(ilkIndex, 0, ionPool.ilkCount())); + uint8 _ilkIndex = uint8(bound(ilkIndex, 0, lens.ilkCount(iIonPool))); - amount = bound(amount, 0, ionPool.gem(_ilkIndex, address(this))); + amount = bound(amount, 0, lens.gem(iIonPool, _ilkIndex, address(this))); GemJoin _gemJoin = registry.gemJoins(_ilkIndex); if (LOG) console.log("gemExit", amount); @@ -415,12 +427,13 @@ contract BorrowerHandler is Handler { contract LiquidatorHandler is Handler { constructor( IonPoolExposed _ionPool, + IIonLens lens, IonRegistry _registry, ERC20PresetMinterPauser _underlying, uint16[] memory _distributionFactors, bool _log, bool _report ) - Handler(_ionPool, _underlying, _registry, _distributionFactors, _log, _report) + Handler(_ionPool, lens, _underlying, _registry, _distributionFactors, _log, _report) { } } diff --git a/test/invariant/RewardToken/ActorManager.t.sol b/test/invariant/RewardToken/ActorManager.t.sol index 9b895363..f15bfb94 100644 --- a/test/invariant/RewardToken/ActorManager.t.sol +++ b/test/invariant/RewardToken/ActorManager.t.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.21; import { WadRayMath } from "../../../src/libraries/math/WadRayMath.sol"; -import { RewardModuleSharedSetup } from "../../helpers/RewardModuleSharedSetup.sol"; +import { RewardTokenSharedSetup } from "../../helpers/RewardTokenSharedSetup.sol"; import { UserHandler, SupplyFactorIncreaseHandler } from "./Handlers.t.sol"; import { CommonBase } from "forge-std/Base.sol"; @@ -66,11 +66,11 @@ contract ActorManager is CommonBase, StdCheats, StdUtils { /** * @dev One big assumption of this invariant test is that `supplyFactor` is - * always increased in proportion to the increase in the `RewardModule` + * always increased in proportion to the increase in the `RewardToken` * contract's underlying balance since the last time `supplyFactor` was * increased. */ -contract RewardModule_InvariantTest is RewardModuleSharedSetup { +contract RewardToken_InvariantTest is RewardTokenSharedSetup { using WadRayMath for uint256; ActorManager public actorManager; @@ -114,7 +114,7 @@ contract RewardModule_InvariantTest is RewardModuleSharedSetup { assertEq(rewardModule.normalizedTotalSupply(), totalSupplyByBalances); } - function invariant_totalSupplyAlwaysBacked() external { + function invariant_lenderClaimAlwaysBacked() external { uint256 totalSupply = rewardModule.totalSupply(); uint256 underlyingBalance = underlying.balanceOf(address(rewardModule)); diff --git a/test/invariant/RewardToken/Handlers.t.sol b/test/invariant/RewardToken/Handlers.t.sol index 56e2ce7a..eb89fd80 100644 --- a/test/invariant/RewardToken/Handlers.t.sol +++ b/test/invariant/RewardToken/Handlers.t.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.21; import { WadRayMath } from "../../../src/libraries/math/WadRayMath.sol"; -import { RewardModuleExposed } from "../../helpers/RewardModuleSharedSetup.sol"; +import { RewardTokenExposed } from "../../helpers/RewardTokenSharedSetup.sol"; import { ERC20PresetMinterPauser } from "../../helpers/ERC20PresetMinterPauser.sol"; import { CommonBase } from "forge-std/Base.sol"; @@ -11,10 +11,10 @@ import { StdCheats } from "forge-std/StdCheats.sol"; import { StdUtils } from "forge-std/StdUtils.sol"; abstract contract Handler is CommonBase, StdCheats, StdUtils { - RewardModuleExposed public immutable REWARD_MODULE; + RewardTokenExposed public immutable REWARD_MODULE; ERC20PresetMinterPauser public immutable UNDERLYING; - constructor(RewardModuleExposed _rewardModule, ERC20PresetMinterPauser _underlying) { + constructor(RewardTokenExposed _rewardModule, ERC20PresetMinterPauser _underlying) { REWARD_MODULE = _rewardModule; UNDERLYING = _underlying; } @@ -24,10 +24,10 @@ contract UserHandler is Handler { using WadRayMath for uint256; constructor( - RewardModuleExposed _rewardModule, + RewardTokenExposed _rewardModule, ERC20PresetMinterPauser _underlying ) - Handler(RewardModuleExposed(_rewardModule), _underlying) + Handler(RewardTokenExposed(_rewardModule), _underlying) { } function mint(address account, uint256 amount) external { @@ -56,10 +56,10 @@ contract SupplyFactorIncreaseHandler is Handler { using WadRayMath for uint256; constructor( - RewardModuleExposed _REWARD_MODULE, + RewardTokenExposed _REWARD_MODULE, ERC20PresetMinterPauser _UNDERLYING ) - Handler(RewardModuleExposed(_REWARD_MODULE), _UNDERLYING) + Handler(RewardTokenExposed(_REWARD_MODULE), _UNDERLYING) { } function increaseSupplyFactor(uint256 amount) external { diff --git a/test/unit/concrete/GemJoin.t.sol b/test/unit/concrete/GemJoin.t.sol index b839b47f..46f9da13 100644 --- a/test/unit/concrete/GemJoin.t.sol +++ b/test/unit/concrete/GemJoin.t.sol @@ -61,14 +61,14 @@ contract GemJoin_Test is IonPoolSharedSetup { for (uint8 i = 0; i < gemJoins.length; i++) { mintableCollaterals[i].mint(address(this), amountToJoin); - assertEq(ionPool.gem(i, address(this)), 0); + assertEq(lens.gem(iIonPool, i, address(this)), 0); IERC20 gem = gemJoins[i].GEM(); gem.approve(address(gemJoins[i]), type(uint256).max); gemJoins[i].join(address(this), amountToJoin); - assertEq(ionPool.gem(i, address(this)), amountToJoin); + assertEq(lens.gem(iIonPool, i, address(this)), amountToJoin); } } @@ -77,7 +77,7 @@ contract GemJoin_Test is IonPoolSharedSetup { for (uint8 i = 0; i < gemJoins.length; i++) { mintableCollaterals[i].mint(address(this), amountToJoin); - assertEq(ionPool.gem(i, address(this)), 0); + assertEq(lens.gem(iIonPool, i, address(this)), 0); IERC20 gem = gemJoins[i].GEM(); gem.approve(address(gemJoins[i]), type(uint256).max); @@ -85,7 +85,7 @@ contract GemJoin_Test is IonPoolSharedSetup { vm.expectRevert(GemJoin.Int256Overflow.selector); gemJoins[i].join(address(this), amountToJoin); - assertEq(ionPool.gem(i, address(this)), 0); + assertEq(lens.gem(iIonPool, i, address(this)), 0); } } @@ -96,18 +96,18 @@ contract GemJoin_Test is IonPoolSharedSetup { for (uint8 i = 0; i < gemJoins.length; i++) { mintableCollaterals[i].mint(address(this), amountToJoin); - assertEq(ionPool.gem(i, address(this)), 0); + assertEq(lens.gem(iIonPool, i, address(this)), 0); IERC20 gem = gemJoins[i].GEM(); gem.approve(address(gemJoins[i]), type(uint256).max); gemJoins[i].join(address(this), amountToJoin); - assertEq(ionPool.gem(i, address(this)), amountToJoin); + assertEq(lens.gem(iIonPool, i, address(this)), amountToJoin); gemJoins[i].exit(address(this), amountToExit); - assertEq(ionPool.gem(i, address(this)), amountToJoin - amountToExit); + assertEq(lens.gem(iIonPool, i, address(this)), amountToJoin - amountToExit); } } @@ -118,19 +118,19 @@ contract GemJoin_Test is IonPoolSharedSetup { for (uint8 i = 0; i < gemJoins.length; i++) { mintableCollaterals[i].mint(address(this), amountToJoin); - assertEq(ionPool.gem(i, address(this)), 0); + assertEq(lens.gem(iIonPool, i, address(this)), 0); IERC20 gem = gemJoins[i].GEM(); gem.approve(address(gemJoins[i]), type(uint256).max); gemJoins[i].join(address(this), amountToJoin); - assertEq(ionPool.gem(i, address(this)), amountToJoin); + assertEq(lens.gem(iIonPool, i, address(this)), amountToJoin); vm.expectRevert(GemJoin.Int256Overflow.selector); gemJoins[i].exit(address(this), amountToExit); - assertEq(ionPool.gem(i, address(this)), amountToJoin); + assertEq(lens.gem(iIonPool, i, address(this)), amountToJoin); } } } diff --git a/test/unit/concrete/IonPool.t.sol b/test/unit/concrete/IonPool.t.sol index 0631ed97..90bc0ad6 100644 --- a/test/unit/concrete/IonPool.t.sol +++ b/test/unit/concrete/IonPool.t.sol @@ -6,7 +6,8 @@ import { RAY, WadRayMath } from "../../../src/libraries/math/WadRayMath.sol"; import { InterestRate, IlkData } from "../../../src/InterestRate.sol"; import { SpotOracle } from "../../../src/oracles/spot/SpotOracle.sol"; import { Whitelist } from "../../../src/Whitelist.sol"; -import { RewardModule } from "../../../src/reward/RewardModule.sol"; +import { RewardToken } from "../../../src/token/RewardToken.sol"; +import { ISpotOracle } from "../../../src/interfaces/ISpotOracle.sol"; import { IIonPoolEvents } from "../../helpers/IIonPoolEvents.sol"; import { IonPoolSharedSetup } from "../../helpers/IonPoolSharedSetup.sol"; @@ -34,7 +35,7 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { vm.prank(lender1); underlying.approve(address(ionPool), type(uint256).max); - for (uint256 i = 0; i < ionPool.ilkCount(); i++) { + for (uint256 i = 0; i < lens.ilkCount(iIonPool); i++) { ERC20PresetMinterPauser collateral = ERC20PresetMinterPauser(address(collaterals[i])); collateral.mint(borrower1, INITIAL_BORROWER_COLLATERAL_BALANCE); @@ -46,12 +47,12 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { } function test_SetUp() public override { - assertEq(ionPool.weth(), INITIAL_LENDER_UNDERLYING_BALANCE); + assertEq(lens.liquidity(iIonPool), INITIAL_LENDER_UNDERLYING_BALANCE); assertEq(underlying.balanceOf(address(ionPool)), INITIAL_LENDER_UNDERLYING_BALANCE); assertEq(ionPool.balanceOf(lender2), INITIAL_LENDER_UNDERLYING_BALANCE); - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { - assertEq(ionPool.gem(i, borrower1), INITIAL_BORROWER_COLLATERAL_BALANCE); + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { + assertEq(lens.gem(iIonPool, i, borrower1), INITIAL_BORROWER_COLLATERAL_BALANCE); assertEq(collaterals[i].balanceOf(address(gemJoins[i])), INITIAL_BORROWER_COLLATERAL_BALANCE); } } @@ -72,10 +73,10 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { function test_SupplyBase() public { uint256 supplyAmount = 1e18; - uint256 supplyAmountBeforeSupply = ionPool.weth(); + uint256 supplyAmountBeforeSupply = lens.liquidity(iIonPool); uint256 currentSupplyFactor = ionPool.supplyFactor(); - uint256 currentTotalDebt = ionPool.debt(); + uint256 currentTotalDebt = lens.debt(iIonPool); (uint256 supplyFactorIncrease,,, uint256 newDebtIncrease,) = ionPool.calculateRewardAndDebtDistribution(); vm.expectEmit(true, true, true, true); @@ -91,17 +92,17 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { vm.prank(lender1); ionPool.supply(lender1, supplyAmount, new bytes32[](0)); - assertEq(ionPool.weth(), supplyAmountBeforeSupply + supplyAmount); + assertEq(lens.liquidity(iIonPool), supplyAmountBeforeSupply + supplyAmount); assertEq(ionPool.balanceOf(lender1), supplyAmount); } function test_SupplyBaseToDifferentAddress() public { uint256 supplyAmount = 1e18; - uint256 supplyAmountBeforeSupply = ionPool.weth(); + uint256 supplyAmountBeforeSupply = lens.liquidity(iIonPool); uint256 currentSupplyFactor = ionPool.supplyFactor(); - uint256 currentTotalDebt = ionPool.debt(); + uint256 currentTotalDebt = lens.debt(iIonPool); (uint256 supplyFactorIncrease,,, uint256 newDebtIncrease,) = ionPool.calculateRewardAndDebtDistribution(); vm.expectEmit(true, true, true, true); @@ -117,7 +118,7 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { vm.prank(lender1); ionPool.supply(address(this), supplyAmount, new bytes32[](0)); - assertEq(ionPool.weth(), supplyAmountBeforeSupply + supplyAmount); + assertEq(lens.liquidity(iIonPool), supplyAmountBeforeSupply + supplyAmount); assertEq(ionPool.balanceOf(address(this)), supplyAmount); } @@ -125,16 +126,16 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { vm.startPrank(lender1); uint256 supplyAmount = 1e18; - uint256 supplyAmountBeforeSupply = ionPool.weth(); + uint256 supplyAmountBeforeSupply = lens.liquidity(iIonPool); ionPool.supply(lender1, supplyAmount, new bytes32[](0)); - assertEq(ionPool.weth(), supplyAmountBeforeSupply + supplyAmount); + assertEq(lens.liquidity(iIonPool), supplyAmountBeforeSupply + supplyAmount); assertEq(ionPool.balanceOf(lender1), supplyAmount); uint256 withdrawAmount = 0.5e18; uint256 currentSupplyFactor = ionPool.supplyFactor(); - uint256 currentTotalDebt = ionPool.debt(); + uint256 currentTotalDebt = lens.debt(iIonPool); (uint256 supplyFactorIncrease,,, uint256 newDebtIncrease,) = ionPool.calculateRewardAndDebtDistribution(); vm.expectEmit(true, true, true, true); @@ -149,7 +150,7 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { ); ionPool.withdraw(lender1, withdrawAmount); - assertEq(ionPool.weth(), supplyAmountBeforeSupply + supplyAmount - withdrawAmount); + assertEq(lens.liquidity(iIonPool), supplyAmountBeforeSupply + supplyAmount - withdrawAmount); assertEq(ionPool.balanceOf(lender1), supplyAmount - withdrawAmount); } @@ -157,16 +158,16 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { vm.startPrank(lender1); uint256 supplyAmount = 1e18; - uint256 supplyAmountBeforeSupply = ionPool.weth(); + uint256 supplyAmountBeforeSupply = lens.liquidity(iIonPool); ionPool.supply(lender1, supplyAmount, new bytes32[](0)); - assertEq(ionPool.weth(), supplyAmountBeforeSupply + supplyAmount); + assertEq(lens.liquidity(iIonPool), supplyAmountBeforeSupply + supplyAmount); assertEq(ionPool.balanceOf(lender1), supplyAmount); uint256 withdrawAmount = 0.5e18; uint256 currentSupplyFactor = ionPool.supplyFactor(); - uint256 currentTotalDebt = ionPool.debt(); + uint256 currentTotalDebt = lens.debt(iIonPool); (uint256 supplyFactorIncrease,,, uint256 newDebtIncrease,) = ionPool.calculateRewardAndDebtDistribution(); vm.expectEmit(true, true, true, true); @@ -181,13 +182,13 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { ); ionPool.withdraw(address(this), withdrawAmount); - assertEq(ionPool.weth(), supplyAmountBeforeSupply + supplyAmount - withdrawAmount); + assertEq(lens.liquidity(iIonPool), supplyAmountBeforeSupply + supplyAmount - withdrawAmount); assertEq(ionPool.balanceOf(lender1), supplyAmount - withdrawAmount); } function test_DepositCollateral() public { - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { - uint256 gemBeforeDeposit = ionPool.gem(i, borrower1); + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { + uint256 gemBeforeDeposit = lens.gem(iIonPool, i, borrower1); uint256 vaultCollateralBeforeDeposit = ionPool.collateral(i, borrower1); assertEq(gemBeforeDeposit, INITIAL_BORROWER_COLLATERAL_BALANCE); @@ -200,14 +201,14 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { vm.prank(borrower1); ionPool.depositCollateral(i, borrower1, borrower1, depositAmount, new bytes32[](0)); - assertEq(ionPool.gem(i, borrower1), gemBeforeDeposit - depositAmount); + assertEq(lens.gem(iIonPool, i, borrower1), gemBeforeDeposit - depositAmount); assertEq(ionPool.collateral(i, borrower1), vaultCollateralBeforeDeposit + depositAmount); } } function test_DepositCollateralToDifferentAddress() public { - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { - uint256 gem1BeforeDeposit = ionPool.gem(i, borrower1); + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { + uint256 gem1BeforeDeposit = lens.gem(iIonPool, i, borrower1); uint256 vaultBeforeDeposit = ionPool.collateral(i, borrower2); assertEq(gem1BeforeDeposit, INITIAL_BORROWER_COLLATERAL_BALANCE); @@ -226,14 +227,14 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { proof: new bytes32[](0) }); - assertEq(ionPool.gem(i, borrower1), gem1BeforeDeposit - depositAmount); + assertEq(lens.gem(iIonPool, i, borrower1), gem1BeforeDeposit - depositAmount); assertEq(ionPool.collateral(i, borrower2), vaultBeforeDeposit + depositAmount); } } function test_RevertWhen_DepositCollateralFromDifferentAddressWithoutConsent() public { - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { - uint256 gem1BeforeDeposit = ionPool.gem(i, borrower1); + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { + uint256 gem1BeforeDeposit = lens.gem(iIonPool, i, borrower1); uint256 vaultBeforeDeposit = ionPool.collateral(i, borrower2); assertEq(gem1BeforeDeposit, INITIAL_BORROWER_COLLATERAL_BALANCE); @@ -256,8 +257,8 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { } function test_DepositCollateralFromDifferentAddressWithConsent() public { - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { - uint256 gem1BeforeDeposit = ionPool.gem(i, borrower1); + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { + uint256 gem1BeforeDeposit = lens.gem(iIonPool, i, borrower1); uint256 vaultBeforeDeposit = ionPool.collateral(i, borrower2); assertEq(gem1BeforeDeposit, INITIAL_BORROWER_COLLATERAL_BALANCE); @@ -279,14 +280,14 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { proof: new bytes32[](0) }); - assertEq(ionPool.gem(i, borrower1), gem1BeforeDeposit - depositAmount); + assertEq(lens.gem(iIonPool, i, borrower1), gem1BeforeDeposit - depositAmount); assertEq(ionPool.collateral(i, borrower2), vaultBeforeDeposit + depositAmount); } } function test_WithdrawCollateral() public { - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { - uint256 gemBeforeDeposit = ionPool.gem(i, borrower1); + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { + uint256 gemBeforeDeposit = lens.gem(iIonPool, i, borrower1); uint256 vaultCollateralBeforeDeposit = ionPool.collateral(i, borrower1); assertEq(gemBeforeDeposit, INITIAL_BORROWER_COLLATERAL_BALANCE); @@ -297,7 +298,7 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { vm.prank(borrower1); ionPool.depositCollateral(i, borrower1, borrower1, depositAmount, new bytes32[](0)); - assertEq(ionPool.gem(i, borrower1), gemBeforeDeposit - depositAmount); + assertEq(lens.gem(iIonPool, i, borrower1), gemBeforeDeposit - depositAmount); assertEq(ionPool.collateral(i, borrower1), vaultCollateralBeforeDeposit + depositAmount); uint256 withdrawAmount = 1e18; @@ -307,14 +308,14 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { vm.prank(borrower1); ionPool.withdrawCollateral(i, borrower1, borrower1, withdrawAmount); - assertEq(ionPool.gem(i, borrower1), gemBeforeDeposit - depositAmount + withdrawAmount); + assertEq(lens.gem(iIonPool, i, borrower1), gemBeforeDeposit - depositAmount + withdrawAmount); assertEq(ionPool.collateral(i, borrower1), vaultCollateralBeforeDeposit + depositAmount - withdrawAmount); } } function test_WithdrawCollateralToDifferentAddress() public { - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { - uint256 gemBeforeDeposit = ionPool.gem(i, borrower1); + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { + uint256 gemBeforeDeposit = lens.gem(iIonPool, i, borrower1); uint256 vaultBeforeDeposit = ionPool.collateral(i, borrower1); assertEq(gemBeforeDeposit, INITIAL_BORROWER_COLLATERAL_BALANCE); @@ -325,7 +326,7 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { vm.prank(borrower1); ionPool.depositCollateral(i, borrower1, borrower1, depositAmount, new bytes32[](0)); - assertEq(ionPool.gem(i, borrower1), gemBeforeDeposit - depositAmount); + assertEq(lens.gem(iIonPool, i, borrower1), gemBeforeDeposit - depositAmount); assertEq(ionPool.collateral(i, borrower1), vaultBeforeDeposit + depositAmount); uint256 withdrawAmount = 1e18; @@ -335,15 +336,15 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { vm.prank(borrower1); ionPool.withdrawCollateral({ ilkIndex: i, user: borrower1, recipient: borrower2, amount: withdrawAmount }); - assertEq(ionPool.gem(i, borrower1), gemBeforeDeposit - depositAmount); + assertEq(lens.gem(iIonPool, i, borrower1), gemBeforeDeposit - depositAmount); assertEq(ionPool.collateral(i, borrower1), vaultBeforeDeposit + depositAmount - withdrawAmount); - assertEq(ionPool.gem(i, borrower2), withdrawAmount); + assertEq(lens.gem(iIonPool, i, borrower2), withdrawAmount); } } function test_RevertWhen_WithdrawCollateralFromDifferentAddressWithoutConsent() public { - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { - uint256 gemBeforeDeposit = ionPool.gem(i, borrower1); + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { + uint256 gemBeforeDeposit = lens.gem(iIonPool, i, borrower1); uint256 vaultBeforeDeposit = ionPool.collateral(i, borrower1); assertEq(gemBeforeDeposit, INITIAL_BORROWER_COLLATERAL_BALANCE); @@ -354,7 +355,7 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { vm.prank(borrower1); ionPool.depositCollateral(i, borrower1, borrower1, depositAmount, new bytes32[](0)); - assertEq(ionPool.gem(i, borrower1), gemBeforeDeposit - depositAmount); + assertEq(lens.gem(iIonPool, i, borrower1), gemBeforeDeposit - depositAmount); assertEq(ionPool.collateral(i, borrower1), vaultBeforeDeposit + depositAmount); uint256 withdrawAmount = 1e18; @@ -367,8 +368,8 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { } function test_WithdrawCollateralFromDifferentAddressWithConsent() public { - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { - uint256 gemBeforeDeposit = ionPool.gem(i, borrower1); + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { + uint256 gemBeforeDeposit = lens.gem(iIonPool, i, borrower1); uint256 vaultBeforeDeposit = ionPool.collateral(i, borrower1); assertEq(gemBeforeDeposit, INITIAL_BORROWER_COLLATERAL_BALANCE); @@ -379,7 +380,7 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { vm.prank(borrower1); ionPool.depositCollateral(i, borrower1, borrower1, depositAmount, new bytes32[](0)); - assertEq(ionPool.gem(i, borrower1), gemBeforeDeposit - depositAmount); + assertEq(lens.gem(iIonPool, i, borrower1), gemBeforeDeposit - depositAmount); assertEq(ionPool.collateral(i, borrower1), vaultBeforeDeposit + depositAmount); uint256 withdrawAmount = 1e18; @@ -392,9 +393,9 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { vm.prank(borrower2); ionPool.withdrawCollateral({ ilkIndex: i, user: borrower1, recipient: borrower2, amount: withdrawAmount }); - assertEq(ionPool.gem(i, borrower1), gemBeforeDeposit - depositAmount); + assertEq(lens.gem(iIonPool, i, borrower1), gemBeforeDeposit - depositAmount); assertEq(ionPool.collateral(i, borrower1), vaultBeforeDeposit + depositAmount - withdrawAmount); - assertEq(ionPool.gem(i, borrower2), withdrawAmount); + assertEq(lens.gem(iIonPool, i, borrower2), withdrawAmount); } } @@ -402,12 +403,12 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { uint256 collateralDepositAmount = 10e18; uint256 normalizedBorrowAmount = 5e18; - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { vm.prank(borrower1); ionPool.depositCollateral(i, borrower1, borrower1, collateralDepositAmount, new bytes32[](0)); uint256 rate = ionPool.rate(i); - uint256 liquidityBefore = ionPool.weth(); + uint256 liquidityBefore = lens.liquidity(iIonPool); assertEq(ionPool.collateral(i, borrower1), collateralDepositAmount); assertEq(underlying.balanceOf(borrower1), normalizedBorrowAmount.rayMulDown(rate) * i); @@ -420,8 +421,8 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { uint256 liquidityRemoved = normalizedBorrowAmount.rayMulDown(rate); assertEq(ionPool.normalizedDebt(i, borrower1), normalizedBorrowAmount); - assertEq(ionPool.totalNormalizedDebt(i), normalizedBorrowAmount); - assertEq(ionPool.weth(), liquidityBefore - liquidityRemoved); + assertEq(lens.totalNormalizedDebt(iIonPool, i), normalizedBorrowAmount); + assertEq(lens.liquidity(iIonPool), liquidityBefore - liquidityRemoved); assertEq(underlying.balanceOf(borrower1), normalizedBorrowAmount.rayMulDown(rate) * (i + 1)); } } @@ -430,12 +431,12 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { uint256 collateralDepositAmount = 10e18; uint256 normalizedBorrowAmount = 5e18; - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { vm.prank(borrower1); ionPool.depositCollateral(i, borrower1, borrower1, collateralDepositAmount, new bytes32[](0)); uint256 rate = ionPool.rate(i); - uint256 liquidityBefore = ionPool.weth(); + uint256 liquidityBefore = lens.liquidity(iIonPool); assertEq(ionPool.collateral(i, borrower1), collateralDepositAmount); assertEq(underlying.balanceOf(borrower2), normalizedBorrowAmount.rayMulDown(rate) * i); @@ -454,8 +455,8 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { uint256 liquidityRemoved = normalizedBorrowAmount.rayMulDown(rate); assertEq(ionPool.normalizedDebt(i, borrower1), normalizedBorrowAmount); - assertEq(ionPool.totalNormalizedDebt(i), normalizedBorrowAmount); - assertEq(ionPool.weth(), liquidityBefore - liquidityRemoved); + assertEq(lens.totalNormalizedDebt(iIonPool, i), normalizedBorrowAmount); + assertEq(lens.liquidity(iIonPool), liquidityBefore - liquidityRemoved); assertEq(underlying.balanceOf(borrower2), normalizedBorrowAmount.rayMulDown(rate) * (i + 1)); } } @@ -464,7 +465,7 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { uint256 collateralDepositAmount = 10e18; uint256 normalizedBorrowAmount = 0.5e18; - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { uint256 dust = 1e45; ionPool.updateIlkDust(i, dust); @@ -488,7 +489,7 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { uint256 collateralDepositAmount = 10e18; uint256 normalizedBorrowAmount = 5e18; - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { vm.prank(borrower1); ionPool.depositCollateral(i, borrower1, borrower1, collateralDepositAmount, new bytes32[](0)); @@ -513,12 +514,12 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { uint256 collateralDepositAmount = 10e18; uint256 normalizedBorrowAmount = 5e18; - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { vm.prank(borrower1); ionPool.depositCollateral(i, borrower1, borrower1, collateralDepositAmount, new bytes32[](0)); uint256 rate = ionPool.rate(i); - uint256 liquidityBefore = ionPool.weth(); + uint256 liquidityBefore = lens.liquidity(iIonPool); assertEq(ionPool.collateral(i, borrower1), collateralDepositAmount); assertEq(underlying.balanceOf(borrower2), normalizedBorrowAmount.rayMulDown(rate) * i); @@ -540,8 +541,8 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { uint256 liquidityRemoved = normalizedBorrowAmount.rayMulDown(rate); assertEq(ionPool.normalizedDebt(i, borrower1), normalizedBorrowAmount); - assertEq(ionPool.totalNormalizedDebt(i), normalizedBorrowAmount); - assertEq(ionPool.weth(), liquidityBefore - liquidityRemoved); + assertEq(lens.totalNormalizedDebt(iIonPool, i), normalizedBorrowAmount); + assertEq(lens.liquidity(iIonPool), liquidityBefore - liquidityRemoved); assertEq(underlying.balanceOf(borrower2), normalizedBorrowAmount.rayMulDown(rate) * (i + 1)); } } @@ -550,7 +551,7 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { uint256 collateralDepositAmount = 10e18; uint256 normalizedBorrowAmount = 11e18; - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { vm.prank(borrower1); ionPool.depositCollateral(i, borrower1, borrower1, collateralDepositAmount, new bytes32[](0)); @@ -558,7 +559,7 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { assertEq(underlying.balanceOf(borrower1), 0); uint256 rate = ionPool.rate(i); - uint256 spot = ionPool.spot(i).getSpot(); + uint256 spot = ISpotOracle(lens.spot(iIonPool, i)).getSpot(); vm.expectRevert( abi.encodeWithSelector( IonPool.UnsafePositionChange.selector, rate * normalizedBorrowAmount, collateralDepositAmount, spot @@ -573,7 +574,7 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { uint256 collateralDepositAmount = 10e18; uint256 normalizedBorrowAmount = 5e18; - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { uint256 debtCeiling = 2e45; ionPool.updateIlkDebtCeiling(i, debtCeiling); @@ -603,12 +604,12 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { uint256 borrowedSoFar; uint256 repaidSoFar; - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { vm.prank(borrower1); ionPool.depositCollateral(i, borrower1, borrower1, collateralDepositAmount, new bytes32[](0)); uint256 rate = ionPool.rate(i); - uint256 liquidityBefore = ionPool.weth(); + uint256 liquidityBefore = lens.liquidity(iIonPool); uint256 trueBorrowAmount = normalizedBorrowAmount.rayMulDown(rate); uint256 trueRepayAmount = normalizedRepayAmount.rayMulUp(rate); @@ -624,8 +625,8 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { uint256 liquidityRemoved = normalizedBorrowAmount.rayMulDown(rate); assertEq(ionPool.normalizedDebt(i, borrower1), normalizedBorrowAmount); - assertEq(ionPool.totalNormalizedDebt(i), normalizedBorrowAmount); - assertEq(ionPool.weth(), liquidityBefore - liquidityRemoved); + assertEq(lens.totalNormalizedDebt(iIonPool, i), normalizedBorrowAmount); + assertEq(lens.liquidity(iIonPool), liquidityBefore - liquidityRemoved); assertEq(underlying.balanceOf(borrower1), borrowedSoFar - repaidSoFar); vm.expectEmit(true, true, true, true); @@ -645,8 +646,8 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { uint256 liquidityAdded = normalizedRepayAmount.rayMulUp(rate); assertEq(ionPool.normalizedDebt(i, borrower1), normalizedBorrowAmount - normalizedRepayAmount); - assertEq(ionPool.totalNormalizedDebt(i), normalizedBorrowAmount - normalizedRepayAmount); - assertEq(ionPool.weth(), liquidityBefore - liquidityRemoved + liquidityAdded); + assertEq(lens.totalNormalizedDebt(iIonPool, i), normalizedBorrowAmount - normalizedRepayAmount); + assertEq(lens.liquidity(iIonPool), liquidityBefore - liquidityRemoved + liquidityAdded); assertEq(underlying.balanceOf(borrower1), borrowedSoFar - repaidSoFar); } } @@ -666,12 +667,12 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { uint256 initialBorrower2Balance = underlying.balanceOf(borrower2); uint256 borrowedSoFar; uint256 repaidSoFar; - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { vm.prank(borrower1); ionPool.depositCollateral(i, borrower1, borrower1, collateralDepositAmount, new bytes32[](0)); uint256 rate = ionPool.rate(i); - uint256 liquidityBefore = ionPool.weth(); + uint256 liquidityBefore = lens.liquidity(iIonPool); uint256 trueBorrowAmount = normalizedBorrowAmount.rayMulDown(rate); uint256 trueRepayAmount = normalizedRepayAmount.rayMulUp(rate); @@ -687,8 +688,8 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { uint256 liquidityRemoved = normalizedBorrowAmount.rayMulDown(rate); assertEq(ionPool.normalizedDebt(i, borrower1), normalizedBorrowAmount); - assertEq(ionPool.totalNormalizedDebt(i), normalizedBorrowAmount); - assertEq(ionPool.weth(), liquidityBefore - liquidityRemoved); + assertEq(lens.totalNormalizedDebt(iIonPool, i), normalizedBorrowAmount); + assertEq(lens.liquidity(iIonPool), liquidityBefore - liquidityRemoved); assertEq(underlying.balanceOf(borrower1), borrowedSoFar); vm.expectEmit(true, true, true, true); @@ -713,8 +714,8 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { uint256 liquidityAdded = normalizedRepayAmount.rayMulUp(rate); assertEq(ionPool.normalizedDebt(i, borrower1), normalizedBorrowAmount - normalizedRepayAmount); - assertEq(ionPool.totalNormalizedDebt(i), normalizedBorrowAmount - normalizedRepayAmount); - assertEq(ionPool.weth(), liquidityBefore - liquidityRemoved + liquidityAdded); + assertEq(lens.totalNormalizedDebt(iIonPool, i), normalizedBorrowAmount - normalizedRepayAmount); + assertEq(lens.liquidity(iIonPool), liquidityBefore - liquidityRemoved + liquidityAdded); assertEq(underlying.balanceOf(borrower1), borrowedSoFar); assertEq(underlying.balanceOf(borrower2), initialBorrower2Balance - repaidSoFar); } @@ -733,12 +734,12 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { underlying.mint(borrower2, 100e18); uint256 borrowedSoFar; - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { vm.prank(borrower1); ionPool.depositCollateral(i, borrower1, borrower1, collateralDepositAmount, new bytes32[](0)); uint256 rate = ionPool.rate(i); - uint256 liquidityBefore = ionPool.weth(); + uint256 liquidityBefore = lens.liquidity(iIonPool); uint256 trueBorrowAmount = normalizedBorrowAmount.rayMulDown(rate); @@ -753,8 +754,8 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { uint256 liquidityRemoved = normalizedBorrowAmount.rayMulDown(rate); assertEq(ionPool.normalizedDebt(i, borrower1), normalizedBorrowAmount); - assertEq(ionPool.totalNormalizedDebt(i), normalizedBorrowAmount); - assertEq(ionPool.weth(), liquidityBefore - liquidityRemoved); + assertEq(lens.totalNormalizedDebt(iIonPool, i), normalizedBorrowAmount); + assertEq(lens.liquidity(iIonPool), liquidityBefore - liquidityRemoved); assertEq(underlying.balanceOf(borrower1), borrowedSoFar); vm.expectRevert(abi.encodeWithSelector(IonPool.TakingWethWithoutConsent.selector, borrower2, borrower1)); @@ -783,12 +784,12 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { uint256 initialBorrower2Balance = underlying.balanceOf(borrower2); uint256 borrowedSoFar; uint256 repaidSoFar; - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { vm.prank(borrower1); ionPool.depositCollateral(i, borrower1, borrower1, collateralDepositAmount, new bytes32[](0)); uint256 rate = ionPool.rate(i); - uint256 liquidityBefore = ionPool.weth(); + uint256 liquidityBefore = lens.liquidity(iIonPool); uint256 trueBorrowAmount = normalizedBorrowAmount.rayMulDown(rate); uint256 trueRepayAmount = normalizedRepayAmount.rayMulUp(rate); @@ -804,8 +805,8 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { uint256 liquidityRemoved = normalizedBorrowAmount.rayMulDown(rate); assertEq(ionPool.normalizedDebt(i, borrower1), normalizedBorrowAmount); - assertEq(ionPool.totalNormalizedDebt(i), normalizedBorrowAmount); - assertEq(ionPool.weth(), liquidityBefore - liquidityRemoved); + assertEq(lens.totalNormalizedDebt(iIonPool, i), normalizedBorrowAmount); + assertEq(lens.liquidity(iIonPool), liquidityBefore - liquidityRemoved); assertEq(underlying.balanceOf(borrower1), borrowedSoFar); vm.prank(borrower2); @@ -833,8 +834,8 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { uint256 liquidityAdded = normalizedRepayAmount.rayMulUp(rate); assertEq(ionPool.normalizedDebt(i, borrower1), normalizedBorrowAmount - normalizedRepayAmount); - assertEq(ionPool.totalNormalizedDebt(i), normalizedBorrowAmount - normalizedRepayAmount); - assertEq(ionPool.weth(), liquidityBefore - liquidityRemoved + liquidityAdded); + assertEq(lens.totalNormalizedDebt(iIonPool, i), normalizedBorrowAmount - normalizedRepayAmount); + assertEq(lens.liquidity(iIonPool), liquidityBefore - liquidityRemoved + liquidityAdded); assertEq(underlying.balanceOf(borrower1), borrowedSoFar); assertEq(underlying.balanceOf(borrower2), initialBorrower2Balance - repaidSoFar); } @@ -859,12 +860,12 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { underlying.approve(address(ionPool), type(uint256).max); RepayLocs memory locs; - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { vm.prank(borrower1); ionPool.depositCollateral(i, borrower1, borrower1, collateralDepositAmount, new bytes32[](0)); uint256 rate = ionPool.rate(i); - uint256 liquidityBefore = ionPool.weth(); + uint256 liquidityBefore = lens.liquidity(iIonPool); locs.trueBorrowAmount = normalizedBorrowAmount.rayMulDown(rate); locs.trueRepayAmount = normalizedRepayAmount.rayMulUp(rate); @@ -883,10 +884,10 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { uint256 liquidityRemoved = normalizedBorrowAmount.rayMulDown(rate); - assertEq(ionPool.debtCeiling(i), newDebtCeiling); + assertEq(lens.debtCeiling(iIonPool, i), newDebtCeiling); assertEq(ionPool.normalizedDebt(i, borrower1), normalizedBorrowAmount); - assertEq(ionPool.totalNormalizedDebt(i), normalizedBorrowAmount); - assertEq(ionPool.weth(), liquidityBefore - liquidityRemoved); + assertEq(lens.totalNormalizedDebt(iIonPool, i), normalizedBorrowAmount); + assertEq(lens.liquidity(iIonPool), liquidityBefore - liquidityRemoved); assertEq(underlying.balanceOf(borrower1), locs.borrowedSoFar - locs.repaidSoFar); vm.expectEmit(true, true, true, true); @@ -906,8 +907,8 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { uint256 liquidityAdded = normalizedRepayAmount.rayMulUp(rate); assertEq(ionPool.normalizedDebt(i, borrower1), normalizedBorrowAmount - normalizedRepayAmount); - assertEq(ionPool.totalNormalizedDebt(i), normalizedBorrowAmount - normalizedRepayAmount); - assertEq(ionPool.weth(), liquidityBefore - liquidityRemoved + liquidityAdded); + assertEq(lens.totalNormalizedDebt(iIonPool, i), normalizedBorrowAmount - normalizedRepayAmount); + assertEq(lens.liquidity(iIonPool), liquidityBefore - liquidityRemoved + liquidityAdded); assertEq(underlying.balanceOf(borrower1), locs.borrowedSoFar - locs.repaidSoFar); } } @@ -927,13 +928,13 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { int256 collateralDepositAmount = 1e18; for (uint8 i = 0; i < collaterals.length; i++) { - uint256 initialGemBalance = ionPool.gem(i, address(this)); + uint256 initialGemBalance = lens.gem(iIonPool, i, address(this)); vm.expectEmit(true, true, true, true); emit MintAndBurnGem(i, address(this), collateralDepositAmount); ionPool.mintAndBurnGem(i, address(this), collateralDepositAmount); - assertEq(ionPool.gem(i, address(this)), uint256(int256(initialGemBalance) + collateralDepositAmount)); + assertEq(lens.gem(iIonPool, i, address(this)), uint256(int256(initialGemBalance) + collateralDepositAmount)); } } @@ -941,15 +942,15 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { uint256 collateralDepositAmount = 1e18; for (uint8 i = 0; i < collaterals.length; i++) { - uint256 initialGemBalance = ionPool.gem(i, borrower1); + uint256 initialGemBalance = lens.gem(iIonPool, i, borrower1); vm.expectEmit(true, true, true, true); emit TransferGem(i, borrower1, borrower2, collateralDepositAmount); vm.prank(borrower1); ionPool.transferGem(i, borrower1, borrower2, collateralDepositAmount); - assertEq(ionPool.gem(i, borrower1), initialGemBalance - collateralDepositAmount); - assertEq(ionPool.gem(i, borrower2), collateralDepositAmount); + assertEq(lens.gem(iIonPool, i, borrower1), initialGemBalance - collateralDepositAmount); + assertEq(lens.gem(iIonPool, i, borrower2), collateralDepositAmount); } } @@ -967,7 +968,7 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { uint256 collateralDepositAmount = 1e18; for (uint8 i = 0; i < collaterals.length; i++) { - uint256 initialGemBalance = ionPool.gem(i, borrower1); + uint256 initialGemBalance = lens.gem(iIonPool, i, borrower1); vm.prank(borrower1); ionPool.addOperator(borrower2); @@ -977,8 +978,8 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { vm.prank(borrower2); ionPool.transferGem(i, borrower1, borrower2, collateralDepositAmount); - assertEq(ionPool.gem(i, borrower1), initialGemBalance - collateralDepositAmount); - assertEq(ionPool.gem(i, borrower2), collateralDepositAmount); + assertEq(lens.gem(iIonPool, i, borrower1), initialGemBalance - collateralDepositAmount); + assertEq(lens.gem(iIonPool, i, borrower2), collateralDepositAmount); } } @@ -988,7 +989,7 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { vm.prank(borrower1); ionPool.addOperator(borrower2); - assertEq(ionPool.isOperator(borrower1, borrower2), true); + assertEq(lens.isOperator(iIonPool, borrower1, borrower2), true); } function test_RemoveOperator() external { @@ -1000,7 +1001,7 @@ contract IonPool_Test is IonPoolSharedSetup, IIonPoolEvents { vm.prank(borrower1); ionPool.removeOperator(borrower2); - assertEq(ionPool.isOperator(borrower1, borrower2), false); + assertEq(lens.isOperator(iIonPool, borrower1, borrower2), false); } } @@ -1019,7 +1020,7 @@ contract IonPool_InterestTest is IonPoolSharedSetup, IIonPoolEvents { vm.prank(lender1); underlying.approve(address(ionPool), type(uint256).max); - for (uint256 i = 0; i < ionPool.ilkCount(); i++) { + for (uint256 i = 0; i < lens.ilkCount(iIonPool); i++) { ERC20PresetMinterPauser collateral = ERC20PresetMinterPauser(address(collaterals[i])); collateral.mint(borrower1, INITIAL_BORROWER_COLLATERAL_BALANCE); @@ -1035,12 +1036,12 @@ contract IonPool_InterestTest is IonPoolSharedSetup, IIonPoolEvents { uint256 normalizedBorrowAmount = 5e18; vm.warp(block.timestamp + 1 days); - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { vm.prank(borrower1); ionPool.depositCollateral(i, borrower1, borrower1, collateralDepositAmount, new bytes32[](0)); uint256 rate = ionPool.rate(i); - uint256 liquidityBefore = ionPool.weth(); + uint256 liquidityBefore = lens.liquidity(iIonPool); assertEq(ionPool.collateral(i, borrower1), collateralDepositAmount); assertEq(underlying.balanceOf(borrower1), normalizedBorrowAmount.rayMulDown(rate) * i); @@ -1051,11 +1052,11 @@ contract IonPool_InterestTest is IonPoolSharedSetup, IIonPoolEvents { uint256 liquidityRemoved = normalizedBorrowAmount.rayMulDown(rate); assertEq(ionPool.normalizedDebt(i, borrower1), normalizedBorrowAmount); - assertEq(ionPool.totalNormalizedDebt(i), normalizedBorrowAmount); - assertEq(ionPool.weth(), liquidityBefore - liquidityRemoved); + assertEq(lens.totalNormalizedDebt(iIonPool, i), normalizedBorrowAmount); + assertEq(lens.liquidity(iIonPool), liquidityBefore - liquidityRemoved); assertEq(underlying.balanceOf(borrower1), normalizedBorrowAmount.rayMulDown(rate) * (i + 1)); - assertEq(ionPool.lastRateUpdate(i), block.timestamp); + assertEq(lens.lastRateUpdate(iIonPool, i), block.timestamp); } } @@ -1063,12 +1064,12 @@ contract IonPool_InterestTest is IonPoolSharedSetup, IIonPoolEvents { uint256 collateralDepositAmount = 10e18; uint256 normalizedBorrowAmount = 5e18; - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { vm.prank(borrower1); ionPool.depositCollateral(i, borrower1, borrower1, collateralDepositAmount, new bytes32[](0)); uint256 rate = ionPool.rate(i); - uint256 liquidityBefore = ionPool.weth(); + uint256 liquidityBefore = lens.liquidity(iIonPool); assertEq(ionPool.collateral(i, borrower1), collateralDepositAmount); assertEq(underlying.balanceOf(borrower1), normalizedBorrowAmount.rayMulDown(rate) * i); @@ -1079,8 +1080,8 @@ contract IonPool_InterestTest is IonPoolSharedSetup, IIonPoolEvents { uint256 liquidityRemoved = normalizedBorrowAmount.rayMulDown(rate); assertEq(ionPool.normalizedDebt(i, borrower1), normalizedBorrowAmount); - assertEq(ionPool.totalNormalizedDebt(i), normalizedBorrowAmount); - assertEq(ionPool.weth(), liquidityBefore - liquidityRemoved); + assertEq(lens.totalNormalizedDebt(iIonPool, i), normalizedBorrowAmount); + assertEq(lens.liquidity(iIonPool), liquidityBefore - liquidityRemoved); assertEq(underlying.balanceOf(borrower1), normalizedBorrowAmount.rayMulDown(rate) * (i + 1)); } @@ -1095,17 +1096,17 @@ contract IonPool_InterestTest is IonPoolSharedSetup, IIonPoolEvents { ) = ionPool.calculateRewardAndDebtDistribution(); uint256 supplyFactorBefore = ionPool.supplyFactorUnaccrued(); - uint256[] memory ratesBefore = new uint256[](ionPool.ilkCount()); - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { - ratesBefore[i] = ionPool.rateUnaccrued(i); + uint256[] memory ratesBefore = new uint256[](lens.ilkCount(iIonPool)); + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { + ratesBefore[i] = lens.rateUnaccrued(iIonPool, i); } - uint256 totalDebtBefore = ionPool.debtUnaccrued(); - uint256[] memory timestampsBefore = new uint256[](ionPool.ilkCount()); - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { - timestampsBefore[i] = ionPool.lastRateUpdate(i); + uint256 totalDebtBefore = lens.debtUnaccrued(iIonPool); + uint256[] memory timestampsBefore = new uint256[](lens.ilkCount(iIonPool)); + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { + timestampsBefore[i] = lens.lastRateUpdate(iIonPool, i); } - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { (uint256 newRateIncrease, uint256 newTimestampIncrease) = ionPool.calculateRewardAndDebtDistributionForIlk(i); assertEq(rateIncreases[i], newRateIncrease); @@ -1113,18 +1114,64 @@ contract IonPool_InterestTest is IonPoolSharedSetup, IIonPoolEvents { } assertEq(supplyFactorBefore + totalSupplyFactorIncrease, ionPool.supplyFactor()); - assertEq(totalDebtBefore + totalDebtIncrease, ionPool.debt()); - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + assertEq(totalDebtBefore + totalDebtIncrease, lens.debt(iIonPool)); + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { assertEq(ratesBefore[i] + rateIncreases[i], ionPool.rate(i)); } ionPool.accrueInterest(); assertEq(ionPool.supplyFactorUnaccrued(), ionPool.supplyFactor()); - assertEq(ionPool.debtUnaccrued(), ionPool.debt()); - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { - assertEq(ionPool.rateUnaccrued(i), ionPool.rate(i)); - assertEq(timestampsBefore[i] + timestampIncreases[i], ionPool.lastRateUpdate(i)); + assertEq(lens.debtUnaccrued(iIonPool), lens.debt(iIonPool)); + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { + assertEq(lens.rateUnaccrued(iIonPool, i), ionPool.rate(i)); + assertEq(timestampsBefore[i] + timestampIncreases[i], lens.lastRateUpdate(iIonPool, i)); + } + } + + // If zero borrow rate, only the last updated timestamp should update + function test_CalculateRewardAndDebtDistributionZeroBorrowRate() external { + // update interest rate module to have zero rates. + IlkData[] memory ilkConfigs = new IlkData[](3); + uint16[] memory distributionFactors = new uint16[](3); + distributionFactors[0] = 0.2e4; + distributionFactors[1] = 0.4e4; + distributionFactors[2] = 0.4e4; + + for (uint8 i; i != 3; ++i) { + IlkData memory ilkConfig = IlkData({ + adjustedProfitMargin: 0, + minimumKinkRate: 0, + reserveFactor: 0, + adjustedBaseRate: 0, + minimumBaseRate: 0, + optimalUtilizationRate: 9000, + distributionFactor: distributionFactors[i], + adjustedAboveKinkSlope: 0, + minimumAboveKinkSlope: 0 + }); + ilkConfigs[i] = ilkConfig; + } + + interestRateModule = new InterestRate(ilkConfigs, apyOracle); + ionPool.updateInterestRateModule(interestRateModule); + + vm.warp(block.timestamp + 1 days); + + ( + uint256 totalSupplyFactorIncrease, + , + uint104[] memory rateIncreases, + uint256 totalDebtIncrease, + uint48[] memory timestampIncreases + ) = ionPool.calculateRewardAndDebtDistribution(); + + assertEq(totalSupplyFactorIncrease, 0, "total supply factor"); + assertEq(totalDebtIncrease, 0, "total debt increase"); + + for (uint8 i; i != 3; ++i) { + assertEq(rateIncreases[i], 0, "rate"); + assertEq(timestampIncreases[i], 1 days, "timestamp increase"); } } @@ -1133,12 +1180,12 @@ contract IonPool_InterestTest is IonPoolSharedSetup, IIonPoolEvents { uint256 normalizedBorrowAmount = 5e18; vm.warp(block.timestamp + 1 days); - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { vm.prank(borrower1); ionPool.depositCollateral(i, borrower1, borrower1, collateralDepositAmount, new bytes32[](0)); uint256 rate = ionPool.rate(i); - uint256 liquidityBefore = ionPool.weth(); + uint256 liquidityBefore = lens.liquidity(iIonPool); assertEq(ionPool.collateral(i, borrower1), collateralDepositAmount); assertEq(underlying.balanceOf(borrower1), normalizedBorrowAmount.rayMulDown(rate) * i); @@ -1149,11 +1196,11 @@ contract IonPool_InterestTest is IonPoolSharedSetup, IIonPoolEvents { uint256 liquidityRemoved = normalizedBorrowAmount.rayMulDown(rate); assertEq(ionPool.normalizedDebt(i, borrower1), normalizedBorrowAmount); - assertEq(ionPool.totalNormalizedDebt(i), normalizedBorrowAmount); - assertEq(ionPool.weth(), liquidityBefore - liquidityRemoved); + assertEq(lens.totalNormalizedDebt(iIonPool, i), normalizedBorrowAmount); + assertEq(lens.liquidity(iIonPool), liquidityBefore - liquidityRemoved); assertEq(underlying.balanceOf(borrower1), normalizedBorrowAmount.rayMulDown(rate) * (i + 1)); - assertEq(ionPool.lastRateUpdate(i), block.timestamp); + assertEq(lens.lastRateUpdate(iIonPool, i), block.timestamp); } } @@ -1162,13 +1209,13 @@ contract IonPool_InterestTest is IonPoolSharedSetup, IIonPoolEvents { uint256 normalizedBorrowAmount = 5e18; uint256 borrowedSoFar; - uint256[] memory previousRates = new uint256[](ionPool.ilkCount()); - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + uint256[] memory previousRates = new uint256[](lens.ilkCount(iIonPool)); + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { vm.prank(borrower1); ionPool.depositCollateral(i, borrower1, borrower1, collateralDepositAmount, new bytes32[](0)); uint256 rate = ionPool.rate(i); - uint256 liquidityBefore = ionPool.weth(); + uint256 liquidityBefore = lens.liquidity(iIonPool); assertEq(ionPool.collateral(i, borrower1), collateralDepositAmount); assertEq(underlying.balanceOf(borrower1), normalizedBorrowAmount.rayMulDown(rate) * i); @@ -1184,13 +1231,150 @@ contract IonPool_InterestTest is IonPoolSharedSetup, IIonPoolEvents { uint256 liquidityRemoved = normalizedBorrowAmount.rayMulDown(rate); assertEq(ionPool.normalizedDebt(i, borrower1), normalizedBorrowAmount); - assertEq(ionPool.totalNormalizedDebt(i), normalizedBorrowAmount); - assertEq(ionPool.weth(), liquidityBefore - liquidityRemoved); + assertEq(lens.totalNormalizedDebt(iIonPool, i), normalizedBorrowAmount); + assertEq(lens.liquidity(iIonPool), liquidityBefore - liquidityRemoved); assertEq(underlying.balanceOf(borrower1), normalizedBorrowAmount.rayMulDown(rate) * (i + 1)); previousRates[i] = rate; } } + + // If distribution factor is zero, should return + // minimum kink rate. + function test_DivideByZeroWhenDistributionFactorIsZero() public { + IlkData[] memory ilkConfigs = new IlkData[](2); + uint16[] memory distributionFactors = new uint16[](2); + distributionFactors[0] = 0; + distributionFactors[1] = 1e4; + + uint96 minimumKinkRate = 4_062_570_058_138_700_000; + for (uint8 i; i != 2; ++i) { + IlkData memory ilkConfig = IlkData({ + adjustedProfitMargin: 0, + minimumKinkRate: minimumKinkRate, + reserveFactor: 0, + adjustedBaseRate: 0, + minimumBaseRate: 0, + optimalUtilizationRate: 9000, + distributionFactor: distributionFactors[i], + adjustedAboveKinkSlope: 0, + minimumAboveKinkSlope: 0 + }); + ilkConfigs[i] = ilkConfig; + } + + interestRateModule = new InterestRate(ilkConfigs, apyOracle); + + vm.warp(block.timestamp + 1 days); + + (uint256 zeroDistFactorBorrowRate,) = interestRateModule.calculateInterestRate(0, 10e45, 100e18); // 10% + // utilization + assertEq(zeroDistFactorBorrowRate, minimumKinkRate, "borrow rate should be minimum kink rate"); + + (uint256 nonZeroDistFactorBorrowRate,) = interestRateModule.calculateInterestRate(1, 100e45, 100e18); // 90% + // utilization + assertApproxEqAbs( + nonZeroDistFactorBorrowRate, minimumKinkRate, 1, "borrow rate at any util should be minimum kink rate" + ); + } + + // If scaling total eth supply with distribution factor truncates to zero, + // should return minimum base rate. + function test_DivideByZeroWhenTotalEthSupplyIsSmall() public { + IlkData[] memory ilkConfigs = new IlkData[](2); + uint16[] memory distributionFactors = new uint16[](2); + distributionFactors[0] = 0.5e4; + distributionFactors[1] = 0.5e4; + + uint96 minimumKinkRate = 4_062_570_058_138_700_000; + uint96 minimumBaseRate = 1_580_630_071_273_960_000; + for (uint8 i; i != 2; ++i) { + IlkData memory ilkConfig = IlkData({ + adjustedProfitMargin: 0, + minimumKinkRate: minimumKinkRate, + reserveFactor: 0, + adjustedBaseRate: 0, + minimumBaseRate: minimumBaseRate, + optimalUtilizationRate: 9000, + distributionFactor: distributionFactors[i], + adjustedAboveKinkSlope: 0, + minimumAboveKinkSlope: 0 + }); + ilkConfigs[i] = ilkConfig; + } + + interestRateModule = new InterestRate(ilkConfigs, apyOracle); + + vm.warp(block.timestamp + 1 days); + + (uint256 borrowRate,) = interestRateModule.calculateInterestRate(0, 0, 1); // dust amount of eth supply + assertEq(borrowRate, minimumBaseRate, "borrow rate should be minimum base rate"); + + (uint256 borrowRateWithoutTruncation,) = interestRateModule.calculateInterestRate(1, 90e45, 100e18); // 90% + // utilization + assertApproxEqAbs(borrowRateWithoutTruncation, minimumKinkRate, 1, "borrow rate without truncation"); + } + + function test_AccrueInterestWhenPaused() public { + uint256 collateralDepositAmount = 10e18; + uint256 normalizedBorrowAmount = 5e18; + + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { + vm.prank(borrower1); + ionPool.depositCollateral(i, borrower1, borrower1, collateralDepositAmount, new bytes32[](0)); + + uint256 rate = ionPool.rate(i); + uint256 liquidityBefore = lens.liquidity(iIonPool); + + assertEq(ionPool.collateral(i, borrower1), collateralDepositAmount); + assertEq(underlying.balanceOf(borrower1), normalizedBorrowAmount.rayMulDown(rate) * i); + + vm.prank(borrower1); + ionPool.borrow(i, borrower1, borrower1, normalizedBorrowAmount, new bytes32[](0)); + + uint256 liquidityRemoved = normalizedBorrowAmount.rayMulDown(rate); + + assertEq(ionPool.normalizedDebt(i, borrower1), normalizedBorrowAmount); + assertEq(lens.totalNormalizedDebt(iIonPool, i), normalizedBorrowAmount); + assertEq(lens.liquidity(iIonPool), liquidityBefore - liquidityRemoved); + assertEq(underlying.balanceOf(borrower1), normalizedBorrowAmount.rayMulDown(rate) * (i + 1)); + } + + vm.warp(block.timestamp + 1 hours); + + ionPool.pause(); + + uint256 rate0AfterPause = ionPool.rate(0); + uint256 rate1AfterPause = ionPool.rate(1); + uint256 rate2AfterPause = ionPool.rate(2); + + uint256 supplyFactorAfterPause = ionPool.supplyFactor(); + uint256 lenderBalanceAfterPause = ionPool.balanceOf(lender2); + + vm.warp(block.timestamp + 365 days); + + ( + uint256 totalSupplyFactorIncrease, + uint256 treasuryMintAmount, + uint104[] memory rateIncreases, + uint256 totalDebtIncrease, + uint48[] memory timestampIncreases + ) = ionPool.calculateRewardAndDebtDistribution(); + + assertEq(totalSupplyFactorIncrease, 0, "no supply factor increase"); + assertEq(treasuryMintAmount, 0, "no treasury mint amount"); + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { + assertEq(rateIncreases[i], 0, "no rate increase"); + assertEq(timestampIncreases[i], 365 days, "no timestamp increase"); + } + assertEq(totalDebtIncrease, 0, "no total debt increase"); + + assertEq(ionPool.balanceOf(lender2), lenderBalanceAfterPause, "lender balance doesn't change"); + assertEq(ionPool.supplyFactor(), supplyFactorAfterPause, "supply factor doesn't change"); + assertEq(ionPool.rate(0), rate0AfterPause, "rate 0 doesn't change"); + assertEq(ionPool.rate(1), rate1AfterPause, "rate 1 doesn't change"); + assertEq(ionPool.rate(2), rate2AfterPause, "rate 2 doesn't change"); + } } contract IonPool_AdminTest is IonPoolSharedSetup { @@ -1225,18 +1409,18 @@ contract IonPool_AdminTest is IonPoolSharedSetup { vm.prank(NON_ADMIN); ionPool.initializeIlk(newIlkAddress); - uint8 prevIlkCount = uint8(ionPool.ilkCount()); + uint8 prevIlkCount = uint8(lens.ilkCount(iIonPool)); vm.expectEmit(true, true, true, true); emit IlkInitialized(prevIlkCount, newIlkAddress); ionPool.initializeIlk(newIlkAddress); - assertEq(ionPool.ilkCount(), prevIlkCount + 1); - assertEq(ionPool.totalNormalizedDebt(prevIlkCount), 0); + assertEq(lens.ilkCount(iIonPool), prevIlkCount + 1); + assertEq(lens.totalNormalizedDebt(iIonPool, prevIlkCount), 0); assertEq(ionPool.rate(prevIlkCount), RAY); - assertEq(ionPool.lastRateUpdate(prevIlkCount), block.timestamp); - assertEq(address(ionPool.spot(prevIlkCount)), address(0)); - assertEq(ionPool.debtCeiling(prevIlkCount), 0); + assertEq(lens.lastRateUpdate(iIonPool, prevIlkCount), block.timestamp); + assertEq(address(lens.spot(iIonPool, prevIlkCount)), address(0)); + assertEq(lens.debtCeiling(iIonPool, prevIlkCount), 0); assertEq(ionPool.dust(prevIlkCount), 0); vm.expectRevert(abi.encodeWithSelector(IonPool.IlkAlreadyAdded.selector, newIlkAddress)); @@ -1247,7 +1431,7 @@ contract IonPool_AdminTest is IonPoolSharedSetup { } function test_RevertWhen_Initializing257ThIlk() public { - uint256 ilkCount = ionPool.ilkCount(); + uint256 ilkCount = lens.ilkCount(iIonPool); // Should lead to 256 total initialized ilks for (uint256 i = 0; i < 256 - ilkCount; i++) { ionPool.initializeIlk(vm.addr(i + 1)); @@ -1273,7 +1457,7 @@ contract IonPool_AdminTest is IonPoolSharedSetup { emit IlkSpotUpdated(i, address(newSpotAddress)); ionPool.updateIlkSpot(i, newSpotAddress); - assertEq(address(ionPool.spot(i)), address(newSpotAddress)); + assertEq(address(lens.spot(iIonPool, i)), address(newSpotAddress)); } } @@ -1293,7 +1477,7 @@ contract IonPool_AdminTest is IonPoolSharedSetup { emit IlkDebtCeilingUpdated(i, newIlkDebtCeiling); ionPool.updateIlkDebtCeiling(i, newIlkDebtCeiling); - assertEq(ionPool.debtCeiling(i), newIlkDebtCeiling); + assertEq(lens.debtCeiling(iIonPool, i), newIlkDebtCeiling); } } @@ -1356,7 +1540,7 @@ contract IonPool_AdminTest is IonPoolSharedSetup { emit InterestRateModuleUpdated(address(newInterestRateModule)); ionPool.updateInterestRateModule(newInterestRateModule); - assertEq(address(ionPool.interestRateModule()), address(newInterestRateModule)); + assertEq(address(lens.interestRateModule(iIonPool)), address(newInterestRateModule)); } function test_UpdateWhitelist() public { @@ -1376,7 +1560,7 @@ contract IonPool_AdminTest is IonPoolSharedSetup { emit WhitelistUpdated(newWhitelist); ionPool.updateWhitelist(Whitelist(newWhitelist)); - assertEq(ionPool.whitelist(), newWhitelist); + assertEq(lens.whitelist(iIonPool), newWhitelist); } function test_Pause() public { @@ -1427,7 +1611,7 @@ contract IonPool_AdminTest is IonPoolSharedSetup { emit TreasuryUpdate(address(1)); ionPool.updateTreasury(address(1)); - vm.expectRevert(RewardModule.InvalidTreasuryAddress.selector); + vm.expectRevert(RewardToken.InvalidTreasuryAddress.selector); ionPool.updateTreasury(address(0)); assertEq(ionPool.treasury(), address(1)); diff --git a/test/unit/concrete/Liquidation.t.sol b/test/unit/concrete/Liquidation.t.sol index f3e82a36..68530389 100644 --- a/test/unit/concrete/Liquidation.t.sol +++ b/test/unit/concrete/Liquidation.t.sol @@ -277,17 +277,17 @@ contract LiquidationTest is LiquidationSharedSetup { assertEq(healthRatio / 1e9, dArgs.targetHealth / 1e9, "resulting health ratio"); // no remaining bad debt, collateral, or ERC20 in liquidations contract - assertEq(ionPool.unbackedDebt(address(liquidation)), 0, "no unbacked debt left in liquidation contract"); - assertEq(ionPool.gem(ILK_INDEX, address(liquidation)), 0, "no gem left in liquidation contract"); + assertEq(lens.unbackedDebt(iIonPool, address(liquidation)), 0, "no unbacked debt left in liquidation contract"); + assertEq(lens.gem(iIonPool, ILK_INDEX, address(liquidation)), 0, "no gem left in liquidation contract"); assertEq(ionPool.underlying().balanceOf(address(liquidation)), 0, "no weth left in liquidation contract"); // nothing went to protocol contract - assertEq(ionPool.unbackedDebt(protocol), 0, "no unbacked debt in protocol"); - assertEq(ionPool.gem(ILK_INDEX, address(liquidation)), 0, "no gem in protocol"); + assertEq(lens.unbackedDebt(iIonPool, protocol), 0, "no unbacked debt in protocol"); + assertEq(lens.gem(iIonPool, ILK_INDEX, address(liquidation)), 0, "no gem in protocol"); assertEq(ionPool.underlying().balanceOf(address(liquidation)), 0, "no weth left in protocol"); // keeper gets the collaterals sold - assertEq(ionPool.gem(ILK_INDEX, keeper1), results.gemOut, "keeper gem"); + assertEq(lens.gem(iIonPool, ILK_INDEX, keeper1), results.gemOut, "keeper gem"); assertEq(ionPool.underlying().balanceOf(keeper1), keeperInitialUnderlying - expectedWethPaid, "keeper weth"); } @@ -353,17 +353,17 @@ contract LiquidationTest is LiquidationSharedSetup { // precision // no remaining bad debt, collateral, or ERC20 in liquidations contract - assertEq(ionPool.unbackedDebt(address(liquidation)), 0, "no unbacked debt left in liquidation contract"); - assertEq(ionPool.gem(ILK_INDEX, address(liquidation)), 0, "no gem left in liquidation contract"); + assertEq(lens.unbackedDebt(iIonPool, address(liquidation)), 0, "no unbacked debt left in liquidation contract"); + assertEq(lens.gem(iIonPool, ILK_INDEX, address(liquidation)), 0, "no gem left in liquidation contract"); assertEq(ionPool.underlying().balanceOf(address(liquidation)), 0, "no weth left in liquidation contract"); // nothing went to protocol contract - assertEq(ionPool.unbackedDebt(protocol), 0, "no unbacked debt in protocol"); - assertEq(ionPool.gem(ILK_INDEX, address(liquidation)), 0, "no gem in protocol"); + assertEq(lens.unbackedDebt(iIonPool, protocol), 0, "no unbacked debt in protocol"); + assertEq(lens.gem(iIonPool, ILK_INDEX, address(liquidation)), 0, "no gem in protocol"); assertEq(ionPool.underlying().balanceOf(address(liquidation)), 0, "no weth left in protocol"); // keeper gets the collaterals sold - assertEq(ionPool.gem(ILK_INDEX, keeper1), results.gemOut, "keeper gem"); + assertEq(lens.gem(iIonPool, ILK_INDEX, keeper1), results.gemOut, "keeper gem"); assertEq(ionPool.underlying().balanceOf(keeper1), keeperInitialUnderlying - expectedWethPaid, "keeper weth"); } @@ -431,17 +431,17 @@ contract LiquidationTest is LiquidationSharedSetup { assertEq(healthRatio / 1e9, dArgs.targetHealth / 1e9, "resulting health ratio"); // no remaining bad debt, collateral, or ERC20 in liquidations contract - assertEq(ionPool.unbackedDebt(address(liquidation)), 0, "no unbacked debt left in liquidation contract"); - assertEq(ionPool.gem(ILK_INDEX, address(liquidation)), 0, "no gem left in liquidation contract"); + assertEq(lens.unbackedDebt(iIonPool, address(liquidation)), 0, "no unbacked debt left in liquidation contract"); + assertEq(lens.gem(iIonPool, ILK_INDEX, address(liquidation)), 0, "no gem left in liquidation contract"); assertEq(ionPool.underlying().balanceOf(address(liquidation)), 0, "no weth left in liquidation contract"); // nothing went to protocol contract - assertEq(ionPool.unbackedDebt(protocol), 0, "no unbacked debt in protocol"); - assertEq(ionPool.gem(ILK_INDEX, address(liquidation)), 0, "no gem in protocol"); + assertEq(lens.unbackedDebt(iIonPool, protocol), 0, "no unbacked debt in protocol"); + assertEq(lens.gem(iIonPool, ILK_INDEX, address(liquidation)), 0, "no gem in protocol"); assertEq(ionPool.underlying().balanceOf(address(liquidation)), 0, "no weth left in protocol"); // keeper gets the collaterals sold - assertEq(ionPool.gem(ILK_INDEX, keeper1), results.gemOut, "keeper gem"); + assertEq(lens.gem(iIonPool, ILK_INDEX, keeper1), results.gemOut, "keeper gem"); assertEq(ionPool.underlying().balanceOf(keeper1), keeperInitialUnderlying - expectedWethPaid, "keeper weth"); } @@ -503,12 +503,12 @@ contract LiquidationTest is LiquidationSharedSetup { assertEq(actualResultingNormalizedDebt, 0, "resulting normalized debt"); // protocol takes on position - assertEq(ionPool.unbackedDebt(protocol), sArgs.normalizedDebt * sArgs.rate, "protocol unbacked debt"); - assertEq(ionPool.gem(ILK_INDEX, protocol), sArgs.collateral, "protocol gem"); + assertEq(lens.unbackedDebt(iIonPool, protocol), sArgs.normalizedDebt * sArgs.rate, "protocol unbacked debt"); + assertEq(lens.gem(iIonPool, ILK_INDEX, protocol), sArgs.collateral, "protocol gem"); // keeper is untouched assertEq(ionPool.underlying().balanceOf(keeper1), keeperInitialUnderlying, "keeper underlying balance"); - assertEq(ionPool.gem(ILK_INDEX, keeper1), 0, "keeper gem"); + assertEq(lens.gem(iIonPool, ILK_INDEX, keeper1), 0, "keeper gem"); } /** @@ -572,17 +572,17 @@ contract LiquidationTest is LiquidationSharedSetup { assertTrue(actualResultingCollateral >= results.collateral, "resulting collateral can be non-zero"); // no remaining bad debt, collateral, or ERC20 in liquidations contract - assertEq(ionPool.unbackedDebt(address(liquidation)), 0, "no unbacked debt left in liquidation contract"); - assertEq(ionPool.gem(ILK_INDEX, address(liquidation)), 0, "no gem left in liquidation contract"); + assertEq(lens.unbackedDebt(iIonPool, address(liquidation)), 0, "no unbacked debt left in liquidation contract"); + assertEq(lens.gem(iIonPool, ILK_INDEX, address(liquidation)), 0, "no gem left in liquidation contract"); assertEq(ionPool.underlying().balanceOf(address(liquidation)), 0, "no weth left in liquidation contract"); // nothing went to protocol contract - assertEq(ionPool.unbackedDebt(protocol), 0, "no unbacked debt in protocol"); - assertEq(ionPool.gem(ILK_INDEX, address(liquidation)), 0, "no gem in protocol"); + assertEq(lens.unbackedDebt(iIonPool, protocol), 0, "no unbacked debt in protocol"); + assertEq(lens.gem(iIonPool, ILK_INDEX, address(liquidation)), 0, "no gem in protocol"); assertEq(ionPool.underlying().balanceOf(address(liquidation)), 0, "no weth left in protocol"); // keeper gets the collaterals sold - assertEq(ionPool.gem(ILK_INDEX, keeper1), results.gemOut, "keeper gem"); + assertEq(lens.gem(iIonPool, ILK_INDEX, keeper1), results.gemOut, "keeper gem"); assertEq(ionPool.underlying().balanceOf(keeper1), keeperInitialUnderlying - expectedWethPaid, "keeper weth"); } } diff --git a/test/unit/concrete/RewardModule.t.sol b/test/unit/concrete/RewardModule.t.sol deleted file mode 100644 index 02c1d3a5..00000000 --- a/test/unit/concrete/RewardModule.t.sol +++ /dev/null @@ -1,174 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.21; - -import { RewardModule } from "../../../src/reward/RewardModule.sol"; -import { WadRayMath } from "../../../src/libraries/math/WadRayMath.sol"; - -import { RewardModuleSharedSetup } from "../../helpers/RewardModuleSharedSetup.sol"; - -contract RewardModule_UnitTest is RewardModuleSharedSetup { - using WadRayMath for uint256; - - uint256 internal constant INITIAL_UNDERYLING = 1000e18; - - function setUp() public override { - super.setUp(); - underlying.mint(address(this), INITIAL_UNDERYLING); - } - - function test_SetUp() external { - assertEq(rewardModule.name(), NAME); - assertEq(rewardModule.symbol(), SYMBOL); - assertEq(rewardModule.decimals(), DECIMALS); - assertEq(rewardModule.treasury(), TREASURY); - - assertEq(underlying.balanceOf(address(this)), INITIAL_UNDERYLING); - assertEq(underlying.balanceOf(address(rewardModule)), 0); - } - - function test_MintRewardBasic() external { - uint256 amountOfRewards = 100e18; - - underlying.approve(address(rewardModule), INITIAL_UNDERYLING); - vm.expectRevert(abi.encodeWithSelector(RewardModule.InvalidReceiver.selector, address(0))); - rewardModule.mint(address(0), amountOfRewards); - rewardModule.mint(address(this), amountOfRewards); - - assertEq(rewardModule.balanceOf(address(this)), amountOfRewards); - assertEq(underlying.balanceOf(address(this)), INITIAL_UNDERYLING - amountOfRewards); - assertEq(underlying.balanceOf(address(rewardModule)), amountOfRewards); - } - - function test_RevertWhen_MintingZeroTokens() external { - underlying.approve(address(rewardModule), INITIAL_UNDERYLING); - vm.expectRevert(RewardModule.InvalidMintAmount.selector); - rewardModule.mint(address(this), 0); - } - - function test_MintNormalizedZeroToTreasury() external { - underlying.approve(address(rewardModule), INITIAL_UNDERYLING); - // 1 wei / 2.5 RAY will be rounded down to zero - rewardModule.setSupplyFactor(2.5e27); - rewardModule.mintToTreasury(1 wei); - } - - function test_BurnRewardBasic() external { - uint256 amountOfRewards = 100e18; - - underlying.approve(address(rewardModule), INITIAL_UNDERYLING); - rewardModule.mint(address(this), amountOfRewards); - - assertEq(rewardModule.balanceOf(address(this)), amountOfRewards); - assertEq(underlying.balanceOf(address(this)), INITIAL_UNDERYLING - amountOfRewards); - - vm.expectRevert(abi.encodeWithSelector(RewardModule.InvalidSender.selector, address(0))); - rewardModule.burn(address(0), address(this), amountOfRewards); - rewardModule.burn(address(this), address(this), amountOfRewards); - - assertEq(rewardModule.balanceOf(address(this)), 0); - } - - function test_MintRewardWithSupplyFactorChange() external { - uint256 amountOfRewards = 100e18; - uint256 supplyFactorOld = rewardModule.supplyFactor(); - - underlying.approve(address(rewardModule), INITIAL_UNDERYLING); - rewardModule.mint(address(this), amountOfRewards); - - uint256 expectedNormalizedMint1 = amountOfRewards.rayDivDown(supplyFactorOld); - - assertEq(rewardModule.normalizedBalanceOf(address(this)), expectedNormalizedMint1); - assertEq(rewardModule.balanceOf(address(this)), amountOfRewards); - assertEq(underlying.balanceOf(address(this)), INITIAL_UNDERYLING - amountOfRewards); - assertEq(underlying.balanceOf(address(rewardModule)), amountOfRewards); - - uint256 supplyFactorNew = 1.5e27; - uint256 interestCreated = amountOfRewards.rayMulDown(supplyFactorNew - supplyFactorOld); - // Adds amount of underlying to the reward token contract based on how - // much the supply factor was changed - _depositInterestGains(interestCreated); - rewardModule.setSupplyFactor(supplyFactorNew); - - rewardModule.mint(address(this), amountOfRewards); - - uint256 expectedNormalizedMint2 = amountOfRewards.rayDivDown(supplyFactorNew); - uint256 totalDeposited = amountOfRewards * 2; - uint256 totalDepositsNormalized = expectedNormalizedMint1 + expectedNormalizedMint2; - uint256 totalValue = totalDepositsNormalized.rayMulDown(supplyFactorNew); - - assertEq(rewardModule.normalizedBalanceOf(address(this)), totalDepositsNormalized); - assertEq(rewardModule.balanceOf(address(this)), totalValue); - assertEq(underlying.balanceOf(address(this)), INITIAL_UNDERYLING - totalDeposited); - assertEq(underlying.balanceOf(address(rewardModule)), totalDeposited + interestCreated); - - uint256 supplyFactorSecondNew = 2.5e27; // 2.5 - interestCreated = amountOfRewards.rayMulDown(supplyFactorSecondNew - supplyFactorNew); - // Adds amount of underlying to the reward token contract based on how - // much the supply factor was changed - _depositInterestGains(interestCreated); - rewardModule.setSupplyFactor(supplyFactorSecondNew); - - vm.expectRevert(RewardModule.InvalidMintAmount.selector); - rewardModule.mint(address(this), 1 wei); - } - - function test_BurnRewardWithSupplyFactorChange() external { - uint256 amountOfRewards = 100e18; - uint256 supplyFactorOld = rewardModule.supplyFactor(); - - underlying.approve(address(rewardModule), INITIAL_UNDERYLING); - rewardModule.mint(address(this), amountOfRewards); - - uint256 expectedNormalizedMint1 = amountOfRewards.rayDivDown(supplyFactorOld); - - assertEq(rewardModule.normalizedBalanceOf(address(this)), expectedNormalizedMint1); - assertEq(rewardModule.balanceOf(address(this)), amountOfRewards); - assertEq(underlying.balanceOf(address(this)), INITIAL_UNDERYLING - amountOfRewards); - assertEq(underlying.balanceOf(address(rewardModule)), amountOfRewards); - - uint256 supplyFactorNew = 2.5e27; // 2.5 - uint256 interestCreated = amountOfRewards.rayMulDown(supplyFactorNew - supplyFactorOld); - // Adds amount of underlying to the reward token contract based on how - // much the supply factor was changed - _depositInterestGains(interestCreated); - rewardModule.setSupplyFactor(supplyFactorNew); - - rewardModule.mint(address(this), amountOfRewards); - - uint256 expectedNormalizedMint2 = amountOfRewards.rayDivDown(supplyFactorNew); - uint256 totalDeposited = amountOfRewards * 2; - uint256 totalDepositsNormalized = expectedNormalizedMint1 + expectedNormalizedMint2; - uint256 totalValue = totalDepositsNormalized.rayMulDown(supplyFactorNew); - - assertEq(rewardModule.normalizedBalanceOf(address(this)), totalDepositsNormalized); - assertEq(rewardModule.balanceOf(address(this)), totalValue); - assertEq(underlying.balanceOf(address(this)), INITIAL_UNDERYLING - totalDeposited); - assertEq(underlying.balanceOf(address(rewardModule)), totalDeposited + interestCreated); - - uint256 burnAmount = 150e18; - - vm.expectRevert( - abi.encodeWithSelector( - RewardModule.InsufficientBalance.selector, - address(this), - totalDepositsNormalized, - (totalValue + totalValue).rayDivDown(supplyFactorNew) - ) - ); - rewardModule.burn(address(this), address(this), totalValue + totalValue); - vm.expectRevert(abi.encodeWithSelector(RewardModule.InvalidSender.selector, address(0))); - rewardModule.burn(address(0), address(this), totalDepositsNormalized); - // vm.expectRevert(Reward.InvalidBurnAmount.selector); - // rewardModule.burn(address(this), address(this), 1 wei); - rewardModule.burn(address(this), address(this), burnAmount); - - assertEq(rewardModule.balanceOf(address(this)), totalValue - burnAmount); - assertEq(rewardModule.totalSupply(), totalValue - burnAmount); - assertEq( - rewardModule.normalizedBalanceOf(address(this)), - totalDepositsNormalized - burnAmount.rayDivDown(supplyFactorNew) - ); - assertEq(underlying.balanceOf(address(this)), INITIAL_UNDERYLING - totalDeposited + burnAmount); - assertEq(underlying.balanceOf(address(rewardModule)), totalDeposited + interestCreated - burnAmount); - } -} diff --git a/test/unit/concrete/RewardToken.t.sol b/test/unit/concrete/RewardToken.t.sol new file mode 100644 index 00000000..134448a4 --- /dev/null +++ b/test/unit/concrete/RewardToken.t.sol @@ -0,0 +1,374 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.21; + +import { RewardToken } from "../../../src/token/RewardToken.sol"; +import { IERC20Errors } from "../../../src/token/IERC20Errors.sol"; +import { WadRayMath } from "../../../src/libraries/math/WadRayMath.sol"; + +import { RewardTokenSharedSetup } from "../../helpers/RewardTokenSharedSetup.sol"; + +import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import { MessageHashUtils } from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; + +contract RewardToken_UnitTest is RewardTokenSharedSetup { + using WadRayMath for uint256; + + uint256 internal constant INITIAL_UNDERYLING = 1000e18; + + bytes private constant EIP712_REVISION = bytes("1"); + bytes32 private constant EIP712_DOMAIN = + keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); + + function setUp() public override { + super.setUp(); + underlying.mint(address(this), INITIAL_UNDERYLING); + } + + function test_SetUp() external { + assertEq(rewardModule.name(), NAME); + assertEq(rewardModule.symbol(), SYMBOL); + assertEq(rewardModule.decimals(), DECIMALS); + assertEq(rewardModule.treasury(), TREASURY); + + assertEq(underlying.balanceOf(address(this)), INITIAL_UNDERYLING); + assertEq(underlying.balanceOf(address(rewardModule)), 0); + } + + function test_MintRewardBasic() external { + uint256 amountOfRewards = 100e18; + + underlying.approve(address(rewardModule), INITIAL_UNDERYLING); + vm.expectRevert(abi.encodeWithSelector(RewardToken.InvalidReceiver.selector, address(0))); + rewardModule.mint(address(0), amountOfRewards); + rewardModule.mint(address(this), amountOfRewards); + + assertEq(rewardModule.normalizedBalanceOf(address(this)), amountOfRewards); + assertEq(underlying.balanceOf(address(this)), INITIAL_UNDERYLING - amountOfRewards); + assertEq(underlying.balanceOf(address(rewardModule)), amountOfRewards); + } + + function test_RevertWhen_MintingZeroTokens() external { + underlying.approve(address(rewardModule), INITIAL_UNDERYLING); + vm.expectRevert(RewardToken.InvalidMintAmount.selector); + rewardModule.mint(address(this), 0); + } + + function test_MintNormalizedZeroToTreasury() external { + underlying.approve(address(rewardModule), INITIAL_UNDERYLING); + // 1 wei / 2.5 RAY will be rounded down to zero + rewardModule.setSupplyFactor(2.5e27); + rewardModule.mintToTreasury(1 wei); + } + + function test_BurnRewardBasic() external { + uint256 amountOfRewards = 100e18; + + underlying.approve(address(rewardModule), INITIAL_UNDERYLING); + rewardModule.mint(address(this), amountOfRewards); + + assertEq(rewardModule.normalizedBalanceOf(address(this)), amountOfRewards); + assertEq(underlying.balanceOf(address(this)), INITIAL_UNDERYLING - amountOfRewards); + + vm.expectRevert(abi.encodeWithSelector(RewardToken.InvalidSender.selector, address(0))); + rewardModule.burn(address(0), address(this), amountOfRewards); + rewardModule.burn(address(this), address(this), amountOfRewards); + + assertEq(rewardModule.normalizedBalanceOf(address(this)), 0); + } + + function test_MintRewardWithSupplyFactorChange() external { + uint256 amountOfRewards = 100e18; + uint256 supplyFactorOld = rewardModule.supplyFactor(); + + underlying.approve(address(rewardModule), INITIAL_UNDERYLING); + rewardModule.mint(address(this), amountOfRewards); + + uint256 expectedNormalizedMint1 = amountOfRewards.rayDivDown(supplyFactorOld); + + assertEq(rewardModule.normalizedBalanceOf(address(this)), expectedNormalizedMint1); + assertEq(rewardModule.balanceOf(address(this)), amountOfRewards); + assertEq(underlying.balanceOf(address(this)), INITIAL_UNDERYLING - amountOfRewards); + assertEq(underlying.balanceOf(address(rewardModule)), amountOfRewards); + + uint256 supplyFactorNew = 1.5e27; + uint256 interestCreated = amountOfRewards.rayMulDown(supplyFactorNew - supplyFactorOld); + // Adds amount of underlying to the reward token contract based on how + // much the supply factor was changed + _depositInterestGains(interestCreated); + rewardModule.setSupplyFactor(supplyFactorNew); + + rewardModule.mint(address(this), amountOfRewards); + + uint256 expectedNormalizedMint2 = amountOfRewards.rayDivDown(supplyFactorNew); + uint256 totalDeposited = amountOfRewards * 2; + uint256 totalDepositsNormalized = expectedNormalizedMint1 + expectedNormalizedMint2; + uint256 totalValue = totalDepositsNormalized.rayMulDown(supplyFactorNew); + + assertEq(rewardModule.normalizedBalanceOf(address(this)), totalDepositsNormalized); + assertEq(rewardModule.balanceOf(address(this)), totalValue); + assertEq(underlying.balanceOf(address(this)), INITIAL_UNDERYLING - totalDeposited); + assertEq(underlying.balanceOf(address(rewardModule)), totalDeposited + interestCreated); + + uint256 supplyFactorSecondNew = 2.5e27; // 2.5 + interestCreated = amountOfRewards.rayMulDown(supplyFactorSecondNew - supplyFactorNew); + // Adds amount of underlying to the reward token contract based on how + // much the supply factor was changed + _depositInterestGains(interestCreated); + rewardModule.setSupplyFactor(supplyFactorSecondNew); + + vm.expectRevert(RewardToken.InvalidMintAmount.selector); + rewardModule.mint(address(this), 1 wei); + } + + function test_BurnRewardWithSupplyFactorChange() external { + uint256 amountOfRewards = 100e18; + uint256 supplyFactorOld = rewardModule.supplyFactor(); + + underlying.approve(address(rewardModule), INITIAL_UNDERYLING); + rewardModule.mint(address(this), amountOfRewards); + + uint256 expectedNormalizedMint1 = amountOfRewards.rayDivDown(supplyFactorOld); + + assertEq(rewardModule.normalizedBalanceOf(address(this)), expectedNormalizedMint1); + assertEq(rewardModule.balanceOf(address(this)), amountOfRewards); + assertEq(underlying.balanceOf(address(this)), INITIAL_UNDERYLING - amountOfRewards); + assertEq(underlying.balanceOf(address(rewardModule)), amountOfRewards); + + uint256 supplyFactorNew = 2.5e27; // 2.5 + uint256 interestCreated = amountOfRewards.rayMulDown(supplyFactorNew - supplyFactorOld); + // Adds amount of underlying to the reward token contract based on how + // much the supply factor was changed + _depositInterestGains(interestCreated); + rewardModule.setSupplyFactor(supplyFactorNew); + + rewardModule.mint(address(this), amountOfRewards); + + uint256 expectedNormalizedMint2 = amountOfRewards.rayDivDown(supplyFactorNew); + uint256 totalDeposited = amountOfRewards * 2; + uint256 totalDepositsNormalized = expectedNormalizedMint1 + expectedNormalizedMint2; + uint256 totalValue = totalDepositsNormalized.rayMulDown(supplyFactorNew); + + assertEq(rewardModule.normalizedBalanceOf(address(this)), totalDepositsNormalized); + assertEq(rewardModule.balanceOf(address(this)), totalValue); + assertEq(underlying.balanceOf(address(this)), INITIAL_UNDERYLING - totalDeposited); + assertEq(underlying.balanceOf(address(rewardModule)), totalDeposited + interestCreated); + + uint256 burnAmount = 150e18; + uint256 burnAmountNormalized = burnAmount.rayDivUp(supplyFactorNew); + + vm.expectRevert( + abi.encodeWithSelector( + RewardToken.InsufficientBalance.selector, + address(this), + totalDepositsNormalized, + (totalValue + totalValue).rayDivDown(supplyFactorNew) + ) + ); + rewardModule.burn(address(this), address(this), totalValue + totalValue); + vm.expectRevert(abi.encodeWithSelector(RewardToken.InvalidSender.selector, address(0))); + rewardModule.burn(address(0), address(this), totalValue); + + vm.expectRevert(RewardToken.InvalidBurnAmount.selector); + rewardModule.burn(address(this), address(this), 0 wei); // only 0 wei will revert with InvalidBurnAmount since + // RewardToken rounds up burn amount in protocol favor + + rewardModule.burn(address(this), address(this), burnAmount); + + assertEq(rewardModule.balanceOf(address(this)), totalValue - burnAmount); + assertEq( + rewardModule.normalizedTotalSupply(), + totalDepositsNormalized - burnAmountNormalized, + "total supply after burn" + ); + assertEq(rewardModule.normalizedBalanceOf(address(this)), totalDepositsNormalized - burnAmountNormalized); + assertEq(underlying.balanceOf(address(this)), INITIAL_UNDERYLING - totalDeposited + burnAmount); + assertEq(underlying.balanceOf(address(rewardModule)), totalDeposited + interestCreated - burnAmount); + } + + function test_transfer() external { + uint256 amountOfRewardTokens = 100e18; + + underlying.approve(address(rewardModule), INITIAL_UNDERYLING); + rewardModule.mint(address(this), amountOfRewardTokens); + + assertEq(rewardModule.normalizedBalanceOf(address(this)), amountOfRewardTokens); + assertEq(underlying.balanceOf(address(this)), INITIAL_UNDERYLING - amountOfRewardTokens); + assertEq(underlying.balanceOf(address(rewardModule)), amountOfRewardTokens); + + vm.expectRevert( + abi.encodeWithSelector( + IERC20Errors.ERC20InsufficientBalance.selector, + address(this), + amountOfRewardTokens, + amountOfRewardTokens + 1 + ) + ); + rewardModule.transfer(receivingUser, amountOfRewardTokens + 1); + vm.expectRevert(abi.encodeWithSelector(IERC20Errors.ERC20InvalidReceiver.selector, address(0))); + rewardModule.transfer(address(0), amountOfRewardTokens); + vm.expectRevert(abi.encodeWithSelector(RewardToken.SelfTransfer.selector, address(this))); + rewardModule.transfer(address(this), amountOfRewardTokens); + rewardModule.transfer(receivingUser, amountOfRewardTokens); + + assertEq(rewardModule.normalizedBalanceOf(address(this)), 0); + assertEq(rewardModule.normalizedBalanceOf(receivingUser), amountOfRewardTokens); + assertEq(underlying.balanceOf(address(this)), INITIAL_UNDERYLING - amountOfRewardTokens); + } + + function test_transferFromWithApprove() external { + uint256 amountOfRewardTokens = 100e18; + + underlying.approve(address(rewardModule), INITIAL_UNDERYLING); + rewardModule.mint(sendingUser, amountOfRewardTokens); + + assertEq(rewardModule.normalizedBalanceOf(sendingUser), amountOfRewardTokens); + assertEq(rewardModule.normalizedBalanceOf(receivingUser), 0); + assertEq(rewardModule.allowance(sendingUser, spender), 0); + assertEq(underlying.balanceOf(address(this)), INITIAL_UNDERYLING - amountOfRewardTokens); + assertEq(underlying.balanceOf(address(rewardModule)), amountOfRewardTokens); + + vm.prank(sendingUser); + rewardModule.approve(spender, amountOfRewardTokens); + + assertEq(rewardModule.allowance(sendingUser, spender), amountOfRewardTokens); + + vm.expectRevert( + abi.encodeWithSelector( + IERC20Errors.ERC20InsufficientAllowance.selector, address(this), 0, amountOfRewardTokens + ) + ); + rewardModule.transferFrom(sendingUser, receivingUser, amountOfRewardTokens); + vm.expectRevert( + abi.encodeWithSelector( + IERC20Errors.ERC20InsufficientAllowance.selector, + spender, + amountOfRewardTokens, + amountOfRewardTokens + 1 + ) + ); + vm.startPrank(spender); + rewardModule.transferFrom(sendingUser, receivingUser, amountOfRewardTokens + 1); + rewardModule.transferFrom(sendingUser, receivingUser, amountOfRewardTokens); + + assertEq(rewardModule.normalizedBalanceOf(sendingUser), 0); + assertEq(rewardModule.normalizedBalanceOf(receivingUser), amountOfRewardTokens); + assertEq(rewardModule.allowance(sendingUser, spender), 0); + } + + function test_transferFromWithPermit() external { + uint256 amountOfRewardTokens = 100e18; + + underlying.approve(address(rewardModule), INITIAL_UNDERYLING); + rewardModule.mint(sendingUser, amountOfRewardTokens); + + assertEq(rewardModule.normalizedBalanceOf(sendingUser), amountOfRewardTokens); + assertEq(rewardModule.normalizedBalanceOf(receivingUser), 0); + assertEq(rewardModule.allowance(sendingUser, spender), 0); + assertEq(underlying.balanceOf(address(this)), INITIAL_UNDERYLING - amountOfRewardTokens); + assertEq(underlying.balanceOf(address(rewardModule)), amountOfRewardTokens); + + { + bytes32 PERMIT_TYPEHASH = rewardModule.PERMIT_TYPEHASH(); + bytes32 domainSeparator = keccak256( + abi.encode( + EIP712_DOMAIN, + keccak256(bytes(rewardModule.name())), + keccak256(EIP712_REVISION), + block.chainid, + address(rewardModule) + ) + ); + + uint256 deadline = block.timestamp + 30 minutes; + + bytes32 structHash = + keccak256(abi.encode(PERMIT_TYPEHASH, sendingUser, spender, amountOfRewardTokens, 0, deadline)); + MessageHashUtils.toTypedDataHash(domainSeparator, structHash); + + (uint8 v, bytes32 r, bytes32 s) = + vm.sign(sendingUserPrivateKey, MessageHashUtils.toTypedDataHash(domainSeparator, structHash)); + + rewardModule.permit(sendingUser, spender, amountOfRewardTokens, deadline, v, r, s); + } + + assertEq(rewardModule.allowance(sendingUser, spender), amountOfRewardTokens); + + vm.expectRevert( + abi.encodeWithSelector( + IERC20Errors.ERC20InsufficientAllowance.selector, address(this), 0, amountOfRewardTokens + ) + ); + rewardModule.transferFrom(sendingUser, receivingUser, amountOfRewardTokens); + vm.expectRevert( + abi.encodeWithSelector( + IERC20Errors.ERC20InsufficientAllowance.selector, + spender, + amountOfRewardTokens, + amountOfRewardTokens + 1 + ) + ); + vm.startPrank(spender); + rewardModule.transferFrom(sendingUser, receivingUser, amountOfRewardTokens + 1); + rewardModule.transferFrom(sendingUser, receivingUser, amountOfRewardTokens); + + assertEq(rewardModule.normalizedBalanceOf(sendingUser), 0); + assertEq(rewardModule.normalizedBalanceOf(receivingUser), amountOfRewardTokens); + assertEq(rewardModule.allowance(sendingUser, spender), 0); + } + + function test_permit() external { + uint256 amountOfRewardTokens = 100e18; + + underlying.approve(address(rewardModule), INITIAL_UNDERYLING); + rewardModule.mint(sendingUser, amountOfRewardTokens); + + assertEq(rewardModule.normalizedBalanceOf(sendingUser), amountOfRewardTokens); + assertEq(rewardModule.normalizedBalanceOf(receivingUser), 0); + assertEq(rewardModule.allowance(sendingUser, spender), 0); + assertEq(underlying.balanceOf(address(this)), INITIAL_UNDERYLING - amountOfRewardTokens); + assertEq(underlying.balanceOf(address(rewardModule)), amountOfRewardTokens); + + { + bytes32 PERMIT_TYPEHASH = rewardModule.PERMIT_TYPEHASH(); + bytes32 domainSeparator = keccak256( + abi.encode( + EIP712_DOMAIN, + keccak256(bytes(rewardModule.name())), + keccak256(EIP712_REVISION), + block.chainid, + address(rewardModule) + ) + ); + uint256 deadline = block.timestamp + 30 minutes; + + // Have spender try to sign on behalf of sendingUser (should fail) + bytes32 structHash = + keccak256(abi.encode(PERMIT_TYPEHASH, sendingUser, spender, amountOfRewardTokens, 0, deadline)); + + (uint8 v, bytes32 r, bytes32 s) = + vm.sign(spenderPrivateKey, MessageHashUtils.toTypedDataHash(domainSeparator, structHash)); + + vm.expectRevert(abi.encodeWithSelector(RewardToken.ERC2612InvalidSigner.selector, spender, sendingUser)); + rewardModule.permit(sendingUser, spender, amountOfRewardTokens, deadline, v, r, s); + + (v, r, s) = vm.sign(sendingUserPrivateKey, MessageHashUtils.toTypedDataHash(domainSeparator, structHash)); + (uint8 vMalleable, bytes32 rMalleable, bytes32 sMalleable) = _calculateMalleableSignature(v, r, s); + + // Openzeppelin ECDSA library already prevents the use of malleable signatures, even if nonce-based replay + // protection wasn't included + vm.expectRevert(abi.encodeWithSelector(ECDSA.ECDSAInvalidSignatureS.selector, sMalleable)); + rewardModule.permit( + sendingUser, spender, amountOfRewardTokens, deadline, vMalleable, rMalleable, sMalleable + ); + + uint256 prevBlockTimestamp = block.timestamp; + vm.warp(deadline + 1); + vm.expectRevert(abi.encodeWithSelector(RewardToken.ERC2612ExpiredSignature.selector, deadline)); + rewardModule.permit(sendingUser, spender, amountOfRewardTokens, deadline, v, r, s); + vm.warp(prevBlockTimestamp); + rewardModule.permit(sendingUser, spender, amountOfRewardTokens, deadline, v, r, s); + } + + assertEq(rewardModule.allowance(sendingUser, spender), amountOfRewardTokens); + } +} diff --git a/test/unit/concrete/vault/Vault.t.sol b/test/unit/concrete/vault/Vault.t.sol new file mode 100644 index 00000000..4b8e15bf --- /dev/null +++ b/test/unit/concrete/vault/Vault.t.sol @@ -0,0 +1,1964 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.21; + +import { ERC20PresetMinterPauser } from "./../../../helpers/ERC20PresetMinterPauser.sol"; +import { VaultSharedSetup } from "./../../../helpers/VaultSharedSetup.sol"; + +import { WadRayMath, RAY } from "./../../../../src/libraries/math/WadRayMath.sol"; +import { Vault } from "./../../../../src/vault/Vault.sol"; +import { IonPool } from "./../../../../src/IonPool.sol"; +import { IIonPool } from "./../../../../src/interfaces/IIonPool.sol"; +import { EnumerableSet } from "openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol"; +import { Math } from "openzeppelin-contracts/contracts/utils/math/Math.sol"; +import { IAccessControl } from "openzeppelin-contracts/contracts/access/IAccessControl.sol"; +import { IERC20 } from "openzeppelin-contracts/contracts/interfaces/IERC20.sol"; +import "forge-std/Test.sol"; +import { console2 } from "forge-std/console2.sol"; + +using EnumerableSet for EnumerableSet.AddressSet; +using WadRayMath for uint256; +using Math for uint256; + +contract VaultSetUpTest is VaultSharedSetup { + function setUp() public override { + super.setUp(); + } + + function test_AddSupportedMarketsSeparately() public { + vault = new Vault( + BASE_ASSET, FEE_RECIPIENT, ZERO_FEES, "Ion Vault Token", "IVT", INITIAL_DELAY, VAULT_ADMIN, emptyMarketsArgs + ); + + vm.startPrank(vault.defaultAdmin()); + vault.grantRole(vault.OWNER_ROLE(), OWNER); + vault.grantRole(vault.ALLOCATOR_ROLE(), OWNER); + vm.stopPrank(); + + vm.startPrank(OWNER); + + IIonPool[] memory market1 = new IIonPool[](1); + market1[0] = weEthIonPool; + IIonPool[] memory market2 = new IIonPool[](1); + market2[0] = rsEthIonPool; + IIonPool[] memory market3 = new IIonPool[](1); + market3[0] = rswEthIonPool; + + uint256[] memory allocationCaps = new uint256[](1); + uint256 allocationCap = 1 ether; + allocationCaps[0] = allocationCap; + + vault.addSupportedMarkets(market1, allocationCaps, market1, market1); + + address[] memory supportedMarkets1 = vault.getSupportedMarkets(); + + assertEq(supportedMarkets1.length, 1, "supported markets length one"); + assertEq(supportedMarkets1[0], address(weEthIonPool), "first supported markets address"); + + assertEq(address(vault.supplyQueue(0)), address(weEthIonPool), "first in supply queue"); + assertEq(address(vault.withdrawQueue(0)), address(weEthIonPool), "first in withdraw queue"); + assertEq(vault.caps(weEthIonPool), allocationCap, "weEthIonPool allocation cap"); + + IIonPool[] memory queue2 = new IIonPool[](2); + queue2[0] = weEthIonPool; + queue2[1] = rsEthIonPool; + + vault.addSupportedMarkets(market2, allocationCaps, queue2, queue2); + address[] memory supportedMarkets2 = vault.getSupportedMarkets(); + assertEq(supportedMarkets2.length, 2, "supported markets length two"); + assertEq(supportedMarkets2[1], address(rsEthIonPool), "second supported markets address"); + + assertEq(address(vault.supplyQueue(1)), address(rsEthIonPool), "second in supply queue"); + assertEq(address(vault.withdrawQueue(1)), address(rsEthIonPool), "second in withdraw queue"); + assertEq(vault.caps(rsEthIonPool), allocationCap, "rsEthIonPool allocation cap"); + + IIonPool[] memory queue3 = new IIonPool[](3); + queue3[0] = weEthIonPool; + queue3[1] = rsEthIonPool; + queue3[2] = rswEthIonPool; + + vault.addSupportedMarkets(market3, allocationCaps, queue3, queue3); + address[] memory supportedMarkets3 = vault.getSupportedMarkets(); + assertEq(supportedMarkets3.length, 3, "supported markets length three"); + assertEq(supportedMarkets3[2], address(rswEthIonPool), "third supported markets address"); + + assertEq(address(vault.supplyQueue(2)), address(rswEthIonPool), "third in supply queue"); + assertEq(address(vault.withdrawQueue(2)), address(rswEthIonPool), "third in withdraw queue"); + assertEq(vault.caps(rswEthIonPool), allocationCap, "rswEthIonPool allocation cap"); + + vm.stopPrank(); + } + + function test_AddSupportedMarketsTogether() public { + vault = new Vault( + BASE_ASSET, FEE_RECIPIENT, ZERO_FEES, "Ion Vault Token", "IVT", INITIAL_DELAY, VAULT_ADMIN, emptyMarketsArgs + ); + + vm.startPrank(vault.defaultAdmin()); + vault.grantRole(vault.OWNER_ROLE(), OWNER); + vault.grantRole(vault.ALLOCATOR_ROLE(), OWNER); + vm.stopPrank(); + + vm.startPrank(OWNER); + + IIonPool[] memory markets = new IIonPool[](3); + markets[0] = weEthIonPool; + markets[1] = rsEthIonPool; + markets[2] = rswEthIonPool; + + uint256[] memory allocationCaps = new uint256[](3); + allocationCaps[0] = 1 ether; + allocationCaps[1] = 2 ether; + allocationCaps[2] = 3 ether; + + vault.addSupportedMarkets(markets, allocationCaps, markets, markets); + address[] memory supportedMarkets = vault.getSupportedMarkets(); + + assertEq(supportedMarkets.length, 3, "supported markets length"); + assertEq(supportedMarkets[0], address(weEthIonPool), "first supported markets address"); + assertEq(supportedMarkets[1], address(rsEthIonPool), "second supported markets address"); + assertEq(supportedMarkets[2], address(rswEthIonPool), "third supported markets address"); + + assertEq(address(vault.supplyQueue(0)), address(weEthIonPool), "first in supply queue"); + assertEq(address(vault.supplyQueue(1)), address(rsEthIonPool), "second in supply queue"); + assertEq(address(vault.supplyQueue(2)), address(rswEthIonPool), "third in supply queue"); + + assertEq(address(vault.withdrawQueue(0)), address(weEthIonPool), "first in withdraw queue"); + assertEq(address(vault.withdrawQueue(1)), address(rsEthIonPool), "second in withdraw queue"); + assertEq(address(vault.withdrawQueue(2)), address(rswEthIonPool), "third in withdraw queue"); + + assertEq(vault.caps(weEthIonPool), 1 ether, "weEthIonPool allocation cap"); + assertEq(vault.caps(rsEthIonPool), 2 ether, "rsEthIonPool allocation cap"); + assertEq(vault.caps(rswEthIonPool), 3 ether, "rswEthIonPool allocation cap"); + + vm.stopPrank(); + } + + function test_Revert_AddSupportedMarkets_InvalidSupportedMarkets() public { + IERC20 wrongBaseAsset = IERC20(address(new ERC20PresetMinterPauser("Wrong Wrapped Staked ETH", "wstETH"))); + + IIonPool newIonPool = deployIonPool(wrongBaseAsset, WEETH, address(this)); + + IIonPool[] memory markets = new IIonPool[](1); + markets[0] = newIonPool; + + uint256[] memory allocationCaps = new uint256[](1); + allocationCaps[0] = 1e18; + + IIonPool[] memory queue = new IIonPool[](4); + queue[0] = weEthIonPool; + queue[1] = rsEthIonPool; + queue[2] = rswEthIonPool; + queue[3] = newIonPool; + + vm.startPrank(OWNER); + + // wrong base asset revert + vm.expectRevert(abi.encodeWithSelector(Vault.InvalidUnderlyingAsset.selector, newIonPool)); + vault.addSupportedMarkets(markets, allocationCaps, queue, queue); + + // zero address revert + vm.expectRevert(); + markets[0] = IIonPool(address(0)); + vault.addSupportedMarkets(markets, allocationCaps, queue, queue); + + vm.stopPrank(); + } + + function test_Revert_AddSupportedMarkets_MarketAlreadySupported() public { } + + function test_Revert_AddSupportedMarkets_MaxSupportedMarketsReached() public { + vault = new Vault( + BASE_ASSET, FEE_RECIPIENT, ZERO_FEES, "Ion Vault Token", "IVT", INITIAL_DELAY, VAULT_ADMIN, emptyMarketsArgs + ); + + vm.startPrank(vault.defaultAdmin()); + vault.grantRole(vault.OWNER_ROLE(), OWNER); + vault.grantRole(vault.ALLOCATOR_ROLE(), OWNER); + vm.stopPrank(); + + IIonPool[] memory markets = new IIonPool[](vault.MAX_SUPPORTED_MARKETS() + 1); + uint256[] memory allocationCaps = new uint256[](vault.MAX_SUPPORTED_MARKETS() + 1); + + for (uint8 i = 0; i < vault.MAX_SUPPORTED_MARKETS() + 1; i++) { + markets[i] = deployIonPool(BASE_ASSET, WEETH, address(this)); + allocationCaps[i] = 1 ether; + } + + vm.startPrank(OWNER); + vm.expectRevert(Vault.MaxSupportedMarketsReached.selector); + vault.addSupportedMarkets(markets, allocationCaps, markets, markets); + vm.stopPrank(); + } + + function test_RemoveSingleSupportedMarket() public { + uint256[] memory allocationCaps = new uint256[](1); + allocationCaps[0] = 1e18; + + IIonPool[] memory marketsToRemove = new IIonPool[](1); + marketsToRemove[0] = weEthIonPool; + + IIonPool[] memory supplyQueue = new IIonPool[](2); + supplyQueue[0] = rsEthIonPool; + supplyQueue[1] = rswEthIonPool; + + IIonPool[] memory withdrawQueue = new IIonPool[](2); + withdrawQueue[0] = rswEthIonPool; + withdrawQueue[1] = rsEthIonPool; + + vm.prank(OWNER); + vault.updateAllocationCaps(marketsToRemove, allocationCaps); + + assertEq(vault.caps(weEthIonPool), 1e18, "allocation cap"); + assertEq(BASE_ASSET.allowance(address(vault), address(weEthIonPool)), type(uint256).max, "allowance"); + + vm.prank(OWNER); + vault.removeSupportedMarkets(marketsToRemove, supplyQueue, withdrawQueue); + + address[] memory supportedMarkets = vault.getSupportedMarkets(); + + assertEq(supportedMarkets.length, 2, "supported markets"); + // weEth rsEth rswEth => rswEth rsEth + // weEth is swapped and popped + assertEq(address(supportedMarkets[0]), address(rswEthIonPool), "first in supported markets"); + assertEq(address(supportedMarkets[1]), address(rsEthIonPool), "second in supported markets"); + + assertEq(address(vault.supplyQueue(0)), address(rsEthIonPool), "first in supply queue"); + assertEq(address(vault.supplyQueue(1)), address(rswEthIonPool), "second in supply queue"); + + assertEq(address(vault.withdrawQueue(0)), address(rswEthIonPool), "first in withdraw queue"); + assertEq(address(vault.withdrawQueue(1)), address(rsEthIonPool), "second in withdraw queue"); + + assertEq(vault.caps(weEthIonPool), 0, "allocation cap deleted"); + assertEq(BASE_ASSET.allowance(address(vault), address(weEthIonPool)), 0, "approval revoked"); + } + + function test_RemoveAllSupportedMarkets() public { + uint256[] memory allocationCaps = new uint256[](3); + allocationCaps[0] = 1e18; + allocationCaps[1] = 1e18; + allocationCaps[2] = 1e18; + + IIonPool[] memory marketsToRemove = new IIonPool[](3); + marketsToRemove[0] = weEthIonPool; + marketsToRemove[1] = rsEthIonPool; + marketsToRemove[2] = rswEthIonPool; + + IIonPool[] memory supplyQueue = new IIonPool[](0); + + IIonPool[] memory withdrawQueue = new IIonPool[](0); + + vm.prank(OWNER); + vault.updateAllocationCaps(marketsToRemove, allocationCaps); + + vm.prank(OWNER); + vault.removeSupportedMarkets(marketsToRemove, supplyQueue, withdrawQueue); + + address[] memory supportedMarkets = vault.getSupportedMarkets(); + + assertEq(supportedMarkets.length, 0, "supported markets"); + + vm.expectRevert(); + vault.supplyQueue(0); + vm.expectRevert(); + vault.withdrawQueue(0); + + assertEq(vault.caps(weEthIonPool), 0, "allocation cap deleted"); + assertEq(vault.caps(rsEthIonPool), 0, "allocation cap deleted"); + assertEq(vault.caps(rswEthIonPool), 0, "allocation cap deleted"); + + assertEq(BASE_ASSET.allowance(address(vault), address(weEthIonPool)), 0, "approval revoked"); + assertEq(BASE_ASSET.allowance(address(vault), address(rsEthIonPool)), 0, "approval revoked"); + assertEq(BASE_ASSET.allowance(address(vault), address(rswEthIonPool)), 0, "approval revoked"); + } + + function test_Revert_RemoveMarkets_IdleMarketWithBalance() public { + IIonPool IDLE = vault.IDLE(); + + IIonPool[] memory market = new IIonPool[](1); + market[0] = IDLE; + + uint256[] memory allocationCaps = new uint256[](1); + allocationCaps[0] = 10e18; + + IIonPool[] memory queue = new IIonPool[](4); + queue[0] = IDLE; + queue[1] = weEthIonPool; + queue[2] = rsEthIonPool; + queue[3] = rswEthIonPool; + + vm.prank(OWNER); + vault.addSupportedMarkets(market, allocationCaps, queue, queue); + + // make a deposit into the idle pool + uint256 depositAmount = 5e18; + setERC20Balance(address(BASE_ASSET), address(this), depositAmount); + + vault.deposit(depositAmount, address(this)); + + assertEq(BASE_ASSET.balanceOf(address(vault)), depositAmount, "deposited to IDLE"); + + IIonPool[] memory newQueue = new IIonPool[](3); + queue[0] = weEthIonPool; + queue[1] = rsEthIonPool; + queue[2] = rswEthIonPool; + + vm.prank(OWNER); + vm.expectRevert(Vault.InvalidIdleMarketRemovalNonZeroBalance.selector); + vault.removeSupportedMarkets(market, newQueue, newQueue); + } + + function test_Revert_RemoveMarkets_IonPoolMarketWithBalance() public { + IIonPool[] memory market = new IIonPool[](1); + market[0] = weEthIonPool; + + uint256[] memory allocationCaps = new uint256[](1); + allocationCaps[0] = 10e18; + + IIonPool[] memory queue = new IIonPool[](2); + queue[0] = rsEthIonPool; + queue[1] = rswEthIonPool; + + vm.prank(OWNER); + vault.updateAllocationCaps(market, allocationCaps); + + uint256 depositAmount = 5e18; + setERC20Balance(address(BASE_ASSET), address(this), depositAmount); + + vault.deposit(depositAmount, address(this)); + + assertGt(weEthIonPool.normalizedBalanceOf(address(vault)), 0, "deposited to weEthIonPool"); + + vm.prank(OWNER); + vm.expectRevert(abi.encodeWithSelector(Vault.InvalidMarketRemovalNonZeroSupply.selector, weEthIonPool)); + vault.removeSupportedMarkets(market, queue, queue); + } + + function test_Revert_RemoveMarkets_MarketNotSupported() public { + IIonPool[] memory market = new IIonPool[](1); + market[0] = IDLE; + + IIonPool[] memory queue = new IIonPool[](3); + queue[0] = weEthIonPool; + queue[1] = rsEthIonPool; + queue[2] = rswEthIonPool; + + vm.prank(OWNER); + vm.expectRevert(abi.encodeWithSelector(Vault.MarketNotSupported.selector, IDLE)); + vault.removeSupportedMarkets(market, queue, queue); + } + + function test_Revert_RemoveMarkets_WrongQueues() public { + // wrong queue length + IIonPool[] memory market = new IIonPool[](1); + market[0] = weEthIonPool; + + // there should be 2 markets left, but this inputs 3 markets into the queues + IIonPool[] memory queue = new IIonPool[](3); + queue[0] = weEthIonPool; + queue[1] = rsEthIonPool; + queue[2] = rswEthIonPool; + + vm.prank(OWNER); + vm.expectRevert(abi.encodeWithSelector(Vault.InvalidQueueLength.selector, 3, 2)); + vault.removeSupportedMarkets(market, queue, queue); + } + + function test_RemoveMarkets_WithMulticall() public { + // for removing weEthIonPool + IIonPool[] memory marketsToRemove = new IIonPool[](1); + marketsToRemove[0] = weEthIonPool; + + IIonPool[] memory queue = new IIonPool[](2); + queue[0] = rsEthIonPool; + queue[1] = rswEthIonPool; + + // for updating allocation caps + + uint256[] memory allocationCaps = new uint256[](3); + allocationCaps[0] = 10e18; + allocationCaps[1] = 10e18; + allocationCaps[2] = 10e18; + + // for fully withdrawing from weEthIonPool and fully depositing to rsEthIonPool + Vault.MarketAllocation[] memory allocs = new Vault.MarketAllocation[](2); + allocs[0] = Vault.MarketAllocation({ pool: weEthIonPool, assets: type(int256).min }); + allocs[1] = Vault.MarketAllocation({ pool: rsEthIonPool, assets: type(int256).max }); + + vm.prank(OWNER); + vault.updateAllocationCaps(markets, allocationCaps); + + uint256 depositAmount = 5e18; + setERC20Balance(address(BASE_ASSET), address(this), depositAmount); + vault.deposit(depositAmount, address(this)); + + assertGt(weEthIonPool.normalizedBalanceOf(address(vault)), 0, "deposited to weEthIonPool"); + + bytes memory reallocateCalldata = abi.encodeWithSelector(Vault.reallocate.selector, allocs); + + bytes memory removeMarketCalldata = + abi.encodeWithSelector(Vault.removeSupportedMarkets.selector, marketsToRemove, queue, queue); + + bytes[] memory multicallData = new bytes[](2); + multicallData[0] = reallocateCalldata; + multicallData[1] = removeMarketCalldata; + + vm.prank(OWNER); + vault.multicall(multicallData); + + vm.expectRevert(abi.encodeWithSelector(Vault.MarketNotSupported.selector, weEthIonPool)); + vault.supportedMarketsIndexOf(address(weEthIonPool)); + + assertEq(vault.supportedMarketsLength(), 2, "supported markets length"); + assertTrue(!vault.containsSupportedMarket(address(weEthIonPool)), "does not contain weEthIonPool"); + } + + function test_UpdateSupplyQueue() public { + IIonPool[] memory supplyQueue = new IIonPool[](3); + supplyQueue[0] = rsEthIonPool; + supplyQueue[1] = rswEthIonPool; + supplyQueue[2] = weEthIonPool; + + vm.startPrank(OWNER); + vault.updateSupplyQueue(supplyQueue); + + assertEq(address(vault.supplyQueue(0)), address(supplyQueue[0]), "updated supply queue"); + assertEq(address(vault.supplyQueue(1)), address(supplyQueue[1]), "updated supply queue"); + assertEq(address(vault.supplyQueue(2)), address(supplyQueue[2]), "updated supply queue"); + } + + function test_Revert_UpdateSupplyQueue() public { + IIonPool[] memory invalidLengthQueue = new IIonPool[](5); + for (uint8 i = 0; i < 5; i++) { + invalidLengthQueue[i] = weEthIonPool; + } + + vm.startPrank(OWNER); + + vm.expectRevert(abi.encodeWithSelector(Vault.InvalidQueueLength.selector, 5, 3)); + vault.updateSupplyQueue(invalidLengthQueue); + + IIonPool[] memory zeroAddressQueue = new IIonPool[](3); + + vm.expectRevert(abi.encodeWithSelector(Vault.MarketNotSupported.selector, address(0))); + vault.updateSupplyQueue(zeroAddressQueue); + + IIonPool wrongIonPool = IIonPool(address(uint160(uint256(keccak256("address not in supported markets"))))); + IIonPool[] memory notSupportedQueue = new IIonPool[](3); + notSupportedQueue[0] = rsEthIonPool; + notSupportedQueue[1] = rswEthIonPool; + notSupportedQueue[2] = wrongIonPool; + + vm.expectRevert(abi.encodeWithSelector(Vault.MarketNotSupported.selector, wrongIonPool)); + vault.updateSupplyQueue(notSupportedQueue); + } + + function test_UpdateWithdrawQueue() public { } + + function test_Revert_UpdateWithdrawQueue() public { } + + function test_Revert_DuplicateIonPoolArray() public { } + + function test_UpdateFeePercentage() public { + vm.prank(OWNER); + vault.updateFeePercentage(0.1e27); + + assertEq(0.1e27, vault.feePercentage(), "fee percentage"); + } + + function test_UpdateFeeRecipient() public { + address newFeeRecipient = newAddress("new fee recipient"); + + vm.prank(OWNER); + vault.updateFeeRecipient(newFeeRecipient); + + assertEq(newFeeRecipient, vault.feeRecipient(), "fee recipient"); + } +} + +contract VaultRolesAndPrivilegedFunctions is VaultSharedSetup { + IIonPool newIonPool; + IIonPool[] newSupplyQueue; + IIonPool[] newWithdrawQueue; + + function setUp() public override { + super.setUp(); + + newIonPool = deployIonPool(BASE_ASSET, WEETH, address(this)); + + newSupplyQueue = new IIonPool[](4); + newSupplyQueue[0] = newIonPool; + newSupplyQueue[1] = weEthIonPool; + newSupplyQueue[2] = rsEthIonPool; + newSupplyQueue[3] = rswEthIonPool; + + newWithdrawQueue = new IIonPool[](4); + newWithdrawQueue[0] = newIonPool; + newWithdrawQueue[1] = rsEthIonPool; + newWithdrawQueue[2] = rswEthIonPool; + newWithdrawQueue[3] = weEthIonPool; + } + + function test_DefaultAdmin_RoleAssignment() public { + address owner1 = newAddress("owner1"); + address owner2 = newAddress("owner2"); + + address allocator1 = newAddress("allocator1"); + + assertEq(vault.DEFAULT_ADMIN_ROLE(), vault.getRoleAdmin(vault.OWNER_ROLE()), "owner role admin"); + assertEq(vault.DEFAULT_ADMIN_ROLE(), vault.getRoleAdmin(vault.ALLOCATOR_ROLE()), "allocator role admin"); + + vm.startPrank(vault.defaultAdmin()); + vault.grantRole(vault.OWNER_ROLE(), owner1); + vault.grantRole(vault.OWNER_ROLE(), owner2); + vault.grantRole(vault.ALLOCATOR_ROLE(), allocator1); + vm.stopPrank(); + + assertTrue(vault.hasRole(vault.OWNER_ROLE(), owner1), "owner1"); + assertTrue(vault.hasRole(vault.OWNER_ROLE(), owner2), "owner2"); + assertTrue(vault.hasRole(vault.ALLOCATOR_ROLE(), allocator1), "allocator1"); + + vm.startPrank(vault.defaultAdmin()); + vault.revokeRole(vault.OWNER_ROLE(), owner1); + vm.stopPrank(); + + assertFalse(vault.hasRole(vault.OWNER_ROLE(), owner1), "owner1 revoked"); + } + + function test_OwnerRole() public { + address notOwner = newAddress("not owner"); + address owner = newAddress("owner"); + + uint256 newFeePerc = 0.05e27; + address newFeeRecipient = newAddress("new fee recipient"); + + IIonPool[] memory marketsToAdd = new IIonPool[](1); + marketsToAdd[0] = newIonPool; + + uint256[] memory allocationCaps = new uint256[](1); + allocationCaps[0] = 1e18; + + IIonPool[] memory ionPoolToUpdate = new IIonPool[](1); + ionPoolToUpdate[0] = weEthIonPool; + + vm.startPrank(vault.defaultAdmin()); + vault.grantRole(vault.OWNER_ROLE(), owner); + vm.stopPrank(); + + // from owner + vm.startPrank(owner); + vault.updateFeePercentage(newFeePerc); + vault.updateFeeRecipient(newFeeRecipient); + vault.updateAllocationCaps(ionPoolToUpdate, allocationCaps); + vm.stopPrank(); + + // grant owner also the allocator role + vm.startPrank(vault.defaultAdmin()); + vault.grantRole(vault.ALLOCATOR_ROLE(), owner); + vm.stopPrank(); + + // from owner with also the allocator role + vm.startPrank(owner); + vault.addSupportedMarkets(marketsToAdd, allocationCaps, newSupplyQueue, newWithdrawQueue); + vm.stopPrank(); + + // not from owner + vm.startPrank(notOwner); + + bytes memory notOwnerRevert = abi.encodeWithSelector( + IAccessControl.AccessControlUnauthorizedAccount.selector, notOwner, vault.OWNER_ROLE() + ); + + vm.expectRevert(notOwnerRevert); + vault.updateFeePercentage(newFeePerc); + + vm.expectRevert(notOwnerRevert); + vault.updateFeeRecipient(newFeeRecipient); + + vm.expectRevert(notOwnerRevert); + vault.addSupportedMarkets(marketsToAdd, allocationCaps, newSupplyQueue, newWithdrawQueue); + + vm.expectRevert(notOwnerRevert); + vault.updateAllocationCaps(ionPoolToUpdate, allocationCaps); + + vm.stopPrank(); + } + + function test_AllocatorRole() public { + address notAllocator = newAddress("not allocator"); + address allocator = newAddress("allocator"); + + newSupplyQueue = new IIonPool[](3); + newSupplyQueue[0] = rswEthIonPool; + newSupplyQueue[1] = weEthIonPool; + newSupplyQueue[2] = rsEthIonPool; + + newWithdrawQueue = new IIonPool[](3); + newWithdrawQueue[0] = weEthIonPool; + newWithdrawQueue[1] = rsEthIonPool; + newWithdrawQueue[2] = rswEthIonPool; + + Vault.MarketAllocation[] memory allocs = new Vault.MarketAllocation[](3); + allocs[0] = Vault.MarketAllocation({ pool: rswEthIonPool, assets: 0 }); + allocs[1] = Vault.MarketAllocation({ pool: weEthIonPool, assets: 0 }); + allocs[2] = Vault.MarketAllocation({ pool: rsEthIonPool, assets: 0 }); + + bytes memory notAllocatorRevert = abi.encodeWithSelector( + IAccessControl.AccessControlUnauthorizedAccount.selector, notAllocator, vault.ALLOCATOR_ROLE() + ); + + vm.startPrank(vault.defaultAdmin()); + vault.grantRole(vault.ALLOCATOR_ROLE(), allocator); + vm.stopPrank(); + + vm.startPrank(notAllocator); + + vm.expectRevert(notAllocatorRevert); + vault.updateSupplyQueue(newSupplyQueue); + + vm.expectRevert(notAllocatorRevert); + vault.updateWithdrawQueue(newWithdrawQueue); + + vm.expectRevert(notAllocatorRevert); + vault.reallocate(allocs); + + vm.stopPrank(); + + vm.startPrank(allocator); + vault.updateSupplyQueue(newSupplyQueue); + vault.updateWithdrawQueue(newWithdrawQueue); + vault.reallocate(allocs); + vm.stopPrank(); + } +} + +abstract contract VaultDeposit is VaultSharedSetup { + function setUp() public virtual override { + super.setUp(); + } + + function test_Deposit_WithoutSupplyCap_WithoutAllocationCap() public { + uint256 depositAmount = 1e18; + setERC20Balance(address(BASE_ASSET), address(this), depositAmount); + + updateSupplyQueue(vault, weEthIonPool, rsEthIonPool, rswEthIonPool); + updateSupplyCaps(vault, type(uint256).max, type(uint256).max, type(uint256).max); + updateAllocationCaps(vault, type(uint256).max, type(uint256).max, type(uint256).max); + + uint256 prevWeEthShares = weEthIonPool.normalizedBalanceOf(address(vault)); + + vault.deposit(depositAmount, address(this)); + + assertEq(vault.totalSupply(), depositAmount, "vault shares total supply"); + assertEq(vault.balanceOf(address(this)), depositAmount, "user vault shares balance"); + assertEq(BASE_ASSET.balanceOf(address(vault)), 0, "base asset balance should be zero"); + assertEq( + weEthIonPool.balanceOf(address(vault)), + claimAfterDeposit(prevWeEthShares, depositAmount, weEthIonPool.supplyFactor()), + "vault iToken claim" + ); + } + + function test_Deposit_WithoutSupplyCap_WithAllocationCap_EqualDeposits() public { + uint256 depositAmount = 3e18; + setERC20Balance(address(BASE_ASSET), address(this), depositAmount); + + updateSupplyQueue(vault, weEthIonPool, rsEthIonPool, rswEthIonPool); + updateSupplyCaps(vault, type(uint256).max, type(uint256).max, type(uint256).max); + updateAllocationCaps(vault, 1e18, 1e18, 1e18); + + uint256 prevWeEthShares = weEthIonPool.normalizedBalanceOf(address(vault)); + uint256 prevRsEthShares = rsEthIonPool.normalizedBalanceOf(address(vault)); + uint256 prevRswEthShares = rswEthIonPool.normalizedBalanceOf(address(vault)); + + // 3e18 gets spread out equally amongst the three pools + vault.deposit(depositAmount, address(this)); + + assertEq(vault.totalSupply(), depositAmount, "vault shares total supply"); + assertEq(vault.balanceOf(address(this)), depositAmount, "user vault shares balance"); + assertEq(BASE_ASSET.balanceOf(address(vault)), 0, "base asset balance should be zero"); + + assertEq( + weEthIonPool.balanceOf(address(vault)), + claimAfterDeposit(prevWeEthShares, 1e18, weEthIonPool.supplyFactor()), + "weEth vault iToken claim" + ); + assertEq( + rsEthIonPool.balanceOf(address(vault)), + claimAfterDeposit(prevRsEthShares, 1e18, rsEthIonPool.supplyFactor()), + "rsEth vault iToken claim" + ); + assertEq( + rswEthIonPool.balanceOf(address(vault)), + claimAfterDeposit(prevRswEthShares, 1e18, rswEthIonPool.supplyFactor()), + "rswEth vault iToken claim" + ); + } + + function test_Deposit_WithoutSupplyCap_WithAllocationCap_DifferentDeposits() public { + uint256 depositAmount = 10e18; + setERC20Balance(address(BASE_ASSET), address(this), depositAmount); + + updateSupplyQueue(vault, rsEthIonPool, rswEthIonPool, weEthIonPool); + updateSupplyCaps(vault, type(uint256).max, type(uint256).max, type(uint256).max); + updateAllocationCaps(vault, 3e18, 5e18, 7e18); + + uint256 prevWeEthShares = weEthIonPool.normalizedBalanceOf(address(vault)); + uint256 prevRsEthShares = rsEthIonPool.normalizedBalanceOf(address(vault)); + uint256 prevRswEthShares = rswEthIonPool.normalizedBalanceOf(address(vault)); + + // 3e18 gets spread out equally amongst the three pools + vault.deposit(depositAmount, address(this)); + + assertEq(vault.totalSupply(), depositAmount, "vault shares total supply"); + assertEq(vault.balanceOf(address(this)), depositAmount, "user vault shares balance"); + assertEq(BASE_ASSET.balanceOf(address(vault)), 0, "base asset balance should be zero"); + + assertEq( + weEthIonPool.balanceOf(address(vault)), + claimAfterDeposit(prevWeEthShares, 2e18, weEthIonPool.supplyFactor()), + "weEth vault iToken claim" + ); + assertEq( + rsEthIonPool.balanceOf(address(vault)), + claimAfterDeposit(prevRsEthShares, 3e18, rsEthIonPool.supplyFactor()), + "rsEth vault iToken claim" + ); + assertEq( + rswEthIonPool.balanceOf(address(vault)), + claimAfterDeposit(prevRswEthShares, 5e18, rswEthIonPool.supplyFactor()), + "rswEth vault iToken claim" + ); + } + + function test_Deposit_SupplyCap_Below_AllocationCap_DifferentDeposits() public { + uint256 depositAmount = 12e18; + setERC20Balance(address(BASE_ASSET), address(this), depositAmount); + + address[] memory supportedMarkets = vault.getSupportedMarkets(); + + updateSupplyQueue(vault, rsEthIonPool, rswEthIonPool, weEthIonPool); + updateSupplyCaps(vault, 3e18, 10e18, 5e18); + updateAllocationCaps(vault, 5e18, 7e18, 20e18); + + uint256 prevWeEthShares = weEthIonPool.normalizedBalanceOf(address(vault)); + uint256 prevRsEthShares = rsEthIonPool.normalizedBalanceOf(address(vault)); + uint256 prevRswEthShares = rswEthIonPool.normalizedBalanceOf(address(vault)); + + vault.deposit(depositAmount, address(this)); + + assertEq(vault.totalSupply(), depositAmount, "vault shares total supply"); + assertEq(vault.balanceOf(address(this)), depositAmount, "user vault shares balance"); + assertEq(BASE_ASSET.balanceOf(address(vault)), 0, "base asset balance should be zero"); + + assertEq( + weEthIonPool.balanceOf(address(vault)), + claimAfterDeposit(prevWeEthShares, 2e18, weEthIonPool.supplyFactor()), + "weEth vault iToken claim" + ); + assertEq( + rsEthIonPool.balanceOf(address(vault)), + claimAfterDeposit(prevRsEthShares, 3e18, rsEthIonPool.supplyFactor()), + "rsEth vault iToken claim" + ); + assertEq( + rswEthIonPool.balanceOf(address(vault)), + claimAfterDeposit(prevRswEthShares, 7e18, rswEthIonPool.supplyFactor()), + "rswEth vault iToken claim" + ); + } + + function test_Revert_Deposit_AllCaps_Filled() public { + uint256 depositAmount = 12e18; + setERC20Balance(address(BASE_ASSET), address(this), depositAmount); + + updateSupplyQueue(vault, rsEthIonPool, rswEthIonPool, weEthIonPool); + updateSupplyCaps(vault, 1e18, 1e18, 1e18); + updateAllocationCaps(vault, 1e18, 1e18, 1e18); + + vm.expectRevert(Vault.AllSupplyCapsReached.selector); + vault.deposit(depositAmount, address(this)); + } + + function test_SupplyToIonPool_AllocationCapAndSupplyCapDiffs() public { } + + /** + * - Exact shares to mint must be minted to the user. + * - Resulting state should be the same as having used `deposit` after + * converting the shares to assets. + */ + function test_Mint_WithoutSupplyCap_WithoutAllocationCap() public { + uint256 sharesToMint = 1e18; + + setERC20Balance(address(BASE_ASSET), address(this), 100e18); + + uint256 initialAssetBalance = BASE_ASSET.balanceOf(address(this)); + uint256 initialTotalSupply = vault.totalSupply(); + uint256 initialTotalAssets = vault.totalAssets(); + + updateSupplyQueue(vault, weEthIonPool, rsEthIonPool, rswEthIonPool); + updateSupplyCaps(vault, type(uint256).max, type(uint256).max, type(uint256).max); + updateAllocationCaps(vault, type(uint256).max, type(uint256).max, type(uint256).max); + + uint256 expectedDepositAmount = vault.previewMint(sharesToMint); + + uint256 assetsDeposited = vault.mint(sharesToMint, address(this)); + + uint256 assetBalanceDiff = initialAssetBalance - BASE_ASSET.balanceOf(address(this)); + uint256 totalSupplyDiff = vault.totalSupply() - initialTotalSupply; + uint256 totalAssetsDiff = vault.totalAssets() - initialTotalAssets; + + uint256 totalAssetsRoundingError = (weEthIonPool.supplyFactor() + 2) / RAY + 1; + + assertEq(totalSupplyDiff, sharesToMint, "vault shares total supply"); + + // when you deposit, as IonPool rounds in protocol favor, totalAssets() may be lower than expected + assertLe( + expectedDepositAmount - totalAssetsDiff, totalAssetsRoundingError, "vault total assetes with rounding error" + ); + + assertEq(vault.balanceOf(address(this)), sharesToMint, "user vault shares balance"); + assertEq(assetBalanceDiff, expectedDepositAmount, "preview amount deposited"); + assertEq(assetsDeposited, expectedDepositAmount, "mint return value"); + } + + function test_Deposit_SkipPauseReverts() public { + // If the market is paused, then the deposit iteration should skip it. + updateAllocationCaps(vault, 10 ether, 20 ether, 30 ether); + + uint256 depositAmt = 30 ether; + setERC20Balance(address(BASE_ASSET), address(this), depositAmt); + + // The second market is paused. + rsEthIonPool.pause(); + + // 10 ether in weEthIonPool, 20 ether in rswEthIonPool + vault.deposit(depositAmt, address(this)); + + assertEq( + weEthIonPool.balanceOf(address(vault)), + claimAfterDeposit(0, 10 ether, weEthIonPool.supplyFactor()), + "weEthIonPool balance" + ); + assertEq(rsEthIonPool.balanceOf(address(vault)), 0, "rsEthIonPool balance"); + assertEq( + rswEthIonPool.balanceOf(address(vault)), + claimAfterDeposit(0, 20 ether, rswEthIonPool.supplyFactor()), + "rswEthIonPool balance" + ); + } + + function test_Deposit_AllMarketsPaused() public { + updateAllocationCaps(vault, 10 ether, 20 ether, 30 ether); + + weEthIonPool.pause(); + rsEthIonPool.pause(); + rswEthIonPool.pause(); + + uint256 depositAmt = 30 ether; + setERC20Balance(address(BASE_ASSET), address(this), depositAmt); + + vm.expectRevert(Vault.AllSupplyCapsReached.selector); + vault.deposit(depositAmt, address(this)); + } + + function test_Mint_AllMarkets() public { } +} + +abstract contract VaultWithdraw is VaultSharedSetup { + function setUp() public virtual override { + super.setUp(); + } + + function test_Withdraw_SingleMarket() public { + uint256 depositAmount = 10e18; + uint256 withdrawAmount = 5e18; + + setERC20Balance(address(BASE_ASSET), address(this), depositAmount); + + updateSupplyQueue(vault, rsEthIonPool, rswEthIonPool, weEthIonPool); + updateSupplyCaps(vault, type(uint256).max, type(uint256).max, type(uint256).max); + updateAllocationCaps(vault, type(uint256).max, type(uint256).max, type(uint256).max); + + updateWithdrawQueue(vault, rsEthIonPool, rswEthIonPool, weEthIonPool); + + vault.deposit(depositAmount, address(this)); + + // state before withdraw + uint256 prevTotalAssets = vault.totalAssets(); + uint256 prevTotalSupply = vault.totalSupply(); + uint256 prevMaxWithdraw = vault.maxWithdraw(address(this)); + + vault.withdraw(withdrawAmount, address(this), address(this)); + + // expectation ignoring rounding errors + uint256 expectedNewTotalAssets = prevTotalAssets - withdrawAmount; + uint256 expectedMaxWithdraw = prevMaxWithdraw - withdrawAmount; + + uint256 expectedSharesBurned = + withdrawAmount.mulDiv(prevTotalSupply + 1, prevTotalAssets + 1, Math.Rounding.Ceil); + uint256 expectedNewTotalSupply = prevTotalSupply - expectedSharesBurned; + + // vault + assertLe(vault.totalAssets(), expectedNewTotalAssets, "vault total assets"); + assertLe( + expectedNewTotalAssets - vault.totalAssets(), + rsEthIonPool.supplyFactor() / RAY, + "vault total assets rounding error" + ); + assertEq(vault.totalSupply(), expectedNewTotalSupply, "vault shares total supply"); + + assertEq(vault.totalAssets(), rsEthIonPool.balanceOf(address(vault)), "single market for total assets"); + assertEq(BASE_ASSET.balanceOf(address(vault)), 0, "valt's base asset balance should be zero"); + + // user + assertLe(vault.maxWithdraw(address(this)), expectedMaxWithdraw, "user max withdraw"); + assertLe( + expectedMaxWithdraw - vault.maxWithdraw(address(this)), + rsEthIonPool.supplyFactor() / RAY, + "user max withdraw rounding error" + ); + + assertEq(BASE_ASSET.balanceOf(address(this)), withdrawAmount, "user base asset balance"); + } + + function test_Withdraw_MultipleMarkets() public { + uint256 depositAmount = 10e18; + uint256 withdrawAmount = 9e18; + + setERC20Balance(address(BASE_ASSET), address(this), depositAmount); + + updateSupplyQueue(vault, rsEthIonPool, rswEthIonPool, weEthIonPool); + updateSupplyCaps(vault, 2e18, 3e18, 5e18); + updateAllocationCaps(vault, 2e18, 3e18, 5e18); + + updateWithdrawQueue(vault, rsEthIonPool, rswEthIonPool, weEthIonPool); + + vault.deposit(depositAmount, address(this)); + + // state before withdraw + uint256 prevTotalAssets = vault.totalAssets(); + uint256 prevTotalSupply = vault.totalSupply(); + uint256 prevMaxWithdraw = vault.maxWithdraw(address(this)); + + vault.withdraw(withdrawAmount, address(this), address(this)); + + uint256 expectedNewTotalAssets = prevTotalAssets - withdrawAmount; + uint256 expectedMaxWithdraw = prevMaxWithdraw - withdrawAmount; + + uint256 expectedSharesBurned = + withdrawAmount.mulDiv(prevTotalSupply + 1, prevTotalAssets + 1, Math.Rounding.Ceil); + uint256 expectedNewTotalSupply = prevTotalSupply - expectedSharesBurned; + + // error bound for resulting total assets after a withdraw + uint256 totalAssetsRoundingError = totalAssetsREAfterWithdraw(4e18, weEthIonPool.supplyFactor()); + uint256 maxWithdrawRoundingError = maxWithdrawREAfterWithdraw(withdrawAmount, prevTotalAssets, prevTotalSupply); + + // pool1 deposit 2 withdraw 2 + // pool2 deposit 3 withdraw 3 + // pool3 deposit 5 withdraw 4 + + // vault + assertLe(vault.totalAssets(), expectedNewTotalAssets, "vault total assets"); + assertLe( + expectedNewTotalAssets - vault.totalAssets(), + weEthIonPool.supplyFactor() / RAY, + "vault total assets rounding error" + ); + assertEq(vault.totalSupply(), expectedNewTotalSupply, "vault shares total supply"); + + assertEq(rsEthIonPool.balanceOf(address(vault)), 0, "vault pool1 balance"); + assertEq(rswEthIonPool.balanceOf(address(vault)), 0, "vault pool2 balance"); + assertLe( + expectedNewTotalAssets - weEthIonPool.balanceOf(address(vault)), + weEthIonPool.supplyFactor() / RAY, + "vault pool3 balance" + ); + + assertEq(BASE_ASSET.balanceOf(address(vault)), 0, "vault base asset balance should be zero"); + + // users + assertLe( + expectedMaxWithdraw - vault.maxWithdraw(address(this)), + weEthIonPool.supplyFactor() / RAY, + "user max withdraw" + ); + } + + function test_Revert_Withdraw_NotEnoughLiquidity() public { + uint256 depositAmount = 10e18; + uint256 withdrawAmount = 20e18; + + setERC20Balance(address(BASE_ASSET), address(this), depositAmount); + + updateAllocationCaps(vault, 2e18, 3e18, 5e18); + + vault.deposit(depositAmount, address(this)); + + vm.expectRevert(Vault.NotEnoughLiquidityToWithdraw.selector); + vault.withdraw(withdrawAmount, address(this), address(this)); + } + + function test_Withdraw_SkipPauseReverts() public { + uint256 depositAmt = 6e18; + uint256 withdrawAmt = 3e18; + + updateAllocationCaps(vault, 1e18, 2e18, 3e18); + + // Deposit 1e18 to weETH, 2e18 to rsETH, 3e18 to rswETH + // rsETH is paused + // Withdraw 1e18 from weETH, 0 from rsETH, 2e18 from rswETH + + setERC20Balance(address(BASE_ASSET), address(this), depositAmt); + vault.deposit(depositAmt, address(this)); + + uint256 initialWeEthIonPoolDeposit = weEthIonPool.balanceOf(address(vault)); + uint256 initialRsEthIonPoolDeposit = rsEthIonPool.balanceOf(address(vault)); + uint256 initialRswEthIonPoolDeposit = rswEthIonPool.balanceOf(address(vault)); + + rsEthIonPool.pause(); + + vault.withdraw(withdrawAmt, address(this), address(this)); + + uint256 rswEthIonPoolWithdrawAmt = withdrawAmt - initialWeEthIonPoolDeposit; + uint256 expectedRswEthIonPoolDeposit = initialRswEthIonPoolDeposit - rswEthIonPoolWithdrawAmt; + uint256 rswEthIonPoolDeposit = rswEthIonPool.balanceOf(address(vault)); + + assertEq(weEthIonPool.balanceOf(address(vault)), 0, "weEthIonPool balance"); + assertEq( + rsEthIonPool.balanceOf(address(vault)), initialRsEthIonPoolDeposit, "rsEthIonPool deposit should not change" + ); + assertLe( + expectedRswEthIonPoolDeposit - rswEthIonPoolDeposit, + rswEthIonPool.supplyFactor() / RAY, + "rswEthIonPool balance" + ); + } + + // try to deposit and withdraw same amounts + function test_Withdraw_FullWithdraw() public { } + + function test_Withdraw_Different_Queue_Order() public { } + + function test_DepositAndWithdraw_MultipleUsers() public { } +} + +abstract contract VaultReallocate is VaultSharedSetup { + function setUp() public virtual override { + super.setUp(); + } + + // --- Reallocate --- + + function test_Reallocate_AcrossAllMarkets() public { + uint256 depositAmount = 10e18; + + setERC20Balance(address(BASE_ASSET), address(this), depositAmount); + + updateSupplyQueue(vault, rsEthIonPool, rswEthIonPool, weEthIonPool); + updateSupplyCaps(vault, type(uint256).max, type(uint256).max, type(uint256).max); + updateAllocationCaps(vault, 2e18, 3e18, 5e18); + + vault.deposit(depositAmount, address(this)); + + updateAllocationCaps(vault, type(uint256).max, type(uint256).max, type(uint256).max); + + uint256 prevTotalAssets = vault.totalAssets(); + + uint256 prevRsEthClaim = rsEthIonPool.balanceOf(address(vault)); + uint256 prevRswEthClaim = rswEthIonPool.balanceOf(address(vault)); + uint256 prevWeEthClaim = weEthIonPool.balanceOf(address(vault)); + + int256 rswEthDiff = -1e18; + int256 weEthDiff = -2e18; + int256 rsEthDiff = 3e18; + + uint256 expNewRsEthClaim = uint256(int256(prevRsEthClaim) + rsEthDiff); + uint256 expNewRswEthClaim = uint256(int256(prevRswEthClaim) + rswEthDiff); + uint256 expNewWeEthClaim = uint256(int256(prevWeEthClaim) + weEthDiff); + + // withdraw 2 from pool2 + // withdraw 1 from pool3 + // deposit 3 to pool1 + Vault.MarketAllocation[] memory allocs = new Vault.MarketAllocation[](3); + allocs[0] = Vault.MarketAllocation({ pool: rswEthIonPool, assets: rswEthDiff }); + allocs[1] = Vault.MarketAllocation({ pool: weEthIonPool, assets: weEthDiff }); + allocs[2] = Vault.MarketAllocation({ pool: rsEthIonPool, assets: rsEthDiff }); + + vm.prank(ALLOCATOR); + vault.reallocate(allocs); + + uint256 newTotalAssets = vault.totalAssets(); + + assertApproxEqAbs( + rsEthIonPool.balanceOf(address(vault)), + expNewRsEthClaim, + rsEthIonPool.supplyFactor() / RAY, + "rsEth vault iToken claim" + ); + assertApproxEqAbs( + rswEthIonPool.balanceOf(address(vault)), + expNewRswEthClaim, + rswEthIonPool.supplyFactor() / RAY, + "rswEth vault iToken claim" + ); + assertApproxEqAbs( + weEthIonPool.balanceOf(address(vault)), + expNewWeEthClaim, + weEthIonPool.supplyFactor() / RAY, + "weEth vault iToken claim" + ); + + assertEq(BASE_ASSET.balanceOf(address(this)), 0, "base asset balance"); + + uint256 cumulativeRoundingError = + rswEthIonPool.supplyFactor() / RAY + weEthIonPool.supplyFactor() / RAY + rsEthIonPool.supplyFactor() / RAY; + assertApproxEqAbs( + prevTotalAssets, newTotalAssets, cumulativeRoundingError, "total assets should remain the same" + ); + } + + function test_Reallocate_ToSingleMarket_MaxWithdraw_MaxDeposit() public { + uint256 depositAmount = 10e18; + + setERC20Balance(address(BASE_ASSET), address(this), depositAmount); + + updateSupplyQueue(vault, weEthIonPool, rswEthIonPool, rsEthIonPool); + updateSupplyCaps(vault, type(uint256).max, type(uint256).max, type(uint256).max); + updateAllocationCaps(vault, 2e18, 3e18, 5e18); + + vault.deposit(depositAmount, address(this)); + + updateAllocationCaps(vault, type(uint256).max, type(uint256).max, type(uint256).max); + + uint256 prevWeEthClaim = weEthIonPool.balanceOf(address(vault)); + uint256 prevRswEthClaim = rswEthIonPool.balanceOf(address(vault)); + uint256 prevRsEthClaim = rsEthIonPool.balanceOf(address(vault)); + uint256 expRswEthClaim = prevRswEthClaim + prevWeEthClaim + prevRsEthClaim; + + uint256 prevTotalAssets = vault.totalAssets(); + + // withdraw 5 from rsEthIonPool + // withdraw 2 from weEthIonPool + // deposit 7 to rswEthIonPool + int256 rsEthDiff = type(int256).min; + int256 weEthDiff = type(int256).min; + int256 rswEthDiff = type(int256).max; + + Vault.MarketAllocation[] memory allocs = new Vault.MarketAllocation[](3); + allocs[0] = Vault.MarketAllocation({ pool: rsEthIonPool, assets: rsEthDiff }); + allocs[1] = Vault.MarketAllocation({ pool: weEthIonPool, assets: weEthDiff }); + allocs[2] = Vault.MarketAllocation({ pool: rswEthIonPool, assets: rswEthDiff }); + + vm.prank(ALLOCATOR); + vault.reallocate(allocs); + + uint256 newTotalAssets = vault.totalAssets(); + + assertEq(rsEthIonPool.balanceOf(address(vault)), 0, "rsEth vault iToken claim"); + assertEq(weEthIonPool.balanceOf(address(vault)), 0, "weEth vault iToken claim"); + assertApproxEqAbs( + rswEthIonPool.balanceOf(address(vault)), + expRswEthClaim, + rswEthIonPool.supplyFactor() / RAY, + "rswEth vault iToken claim" + ); + + assertApproxEqAbs( + prevTotalAssets, newTotalAssets, rswEthIonPool.supplyFactor() / RAY, "total assets should remain the same" + ); + } + + function test_Revert_Reallocate_AllocationCapExceeded() public { + uint256 depositAmount = 10e18; + + setERC20Balance(address(BASE_ASSET), address(this), depositAmount); + + updateSupplyQueue(vault, weEthIonPool, rswEthIonPool, rsEthIonPool); + updateSupplyCaps(vault, type(uint256).max, type(uint256).max, type(uint256).max); + updateAllocationCaps(vault, 2e18, 3e18, 5e18); + + vault.deposit(depositAmount, address(this)); + + updateAllocationCaps(vault, 3e18, type(uint256).max, type(uint256).max); + + uint256 prevTotalAssets = vault.totalAssets(); + + uint256 weEthCurrentSupplied = weEthIonPool.balanceOf(address(vault)); + + // tries to deposit 2e18 + 2e18 to 3e18 allocation cap + Vault.MarketAllocation[] memory allocs = new Vault.MarketAllocation[](3); + allocs[0] = Vault.MarketAllocation({ pool: rswEthIonPool, assets: -1e18 }); + allocs[1] = Vault.MarketAllocation({ pool: rsEthIonPool, assets: -1e18 }); + allocs[2] = Vault.MarketAllocation({ pool: weEthIonPool, assets: 2e18 }); + + vm.prank(ALLOCATOR); + vm.expectRevert(abi.encodeWithSelector(Vault.AllocationCapExceeded.selector, weEthCurrentSupplied + 2e18, 3e18)); + vault.reallocate(allocs); + } + + function test_Revert_Reallocate_SupplyCapExceeded() public { + uint256 depositAmount = 10e18; + + setERC20Balance(address(BASE_ASSET), address(this), depositAmount); + + updateSupplyQueue(vault, weEthIonPool, rswEthIonPool, rsEthIonPool); + updateSupplyCaps(vault, type(uint256).max, type(uint256).max, type(uint256).max); + updateAllocationCaps(vault, 2e18, 3e18, 5e18); + + vault.deposit(depositAmount, address(this)); + + updateAllocationCaps(vault, type(uint256).max, type(uint256).max, type(uint256).max); + updateSupplyCaps(vault, 5e18, type(uint256).max, type(uint256).max); + + uint256 prevTotalAssets = vault.totalAssets(); + + // tries to deposit 10e18 to 9e18 allocation cap + Vault.MarketAllocation[] memory allocs = new Vault.MarketAllocation[](3); + allocs[0] = Vault.MarketAllocation({ pool: rswEthIonPool, assets: type(int256).min }); + allocs[1] = Vault.MarketAllocation({ pool: rsEthIonPool, assets: type(int256).min }); + allocs[2] = Vault.MarketAllocation({ pool: weEthIonPool, assets: 4e18 }); + + vm.prank(ALLOCATOR); + vm.expectRevert(abi.encodeWithSelector(IIonPool.DepositSurpassesSupplyCap.selector, 4e18, 5e18)); + // vm.expectRevert(IIonPool.DepositSurpassesSupplyCap.selector); + vault.reallocate(allocs); + } +} + +abstract contract VaultWithIdlePool is VaultSharedSetup { + IIonPool[] marketsToAdd; + uint256[] allocationCaps; + + function setUp() public virtual override { + super.setUp(); + + vault = new Vault( + BASE_ASSET, FEE_RECIPIENT, ZERO_FEES, "Ion Vault Token", "IVT", INITIAL_DELAY, VAULT_ADMIN, emptyMarketsArgs + ); + + BASE_ASSET.approve(address(vault), type(uint256).max); + + marketsToAdd = new IIonPool[](4); + marketsToAdd[0] = weEthIonPool; + marketsToAdd[1] = IDLE; + marketsToAdd[2] = rsEthIonPool; + marketsToAdd[3] = rswEthIonPool; + + allocationCaps = new uint256[](4); + allocationCaps[0] = 10e18; + allocationCaps[1] = 20e18; + allocationCaps[2] = 30e18; + allocationCaps[3] = 40e18; + + vm.startPrank(vault.defaultAdmin()); + + vault.grantRole(vault.OWNER_ROLE(), OWNER); + vault.grantRole(vault.ALLOCATOR_ROLE(), OWNER); + vault.grantRole(vault.ALLOCATOR_ROLE(), ALLOCATOR); + + vm.stopPrank(); + + vm.prank(OWNER); + vault.addSupportedMarkets(marketsToAdd, allocationCaps, marketsToAdd, marketsToAdd); + } + + function test_Deposit_AllMarkets_FirstDeposit() public { + uint256 depositAmount = 70e18; + setERC20Balance(address(BASE_ASSET), address(this), depositAmount); + + uint256 weEthIonPoolSF = weEthIonPool.supplyFactor(); + uint256 rsEthIonPoolSF = rsEthIonPool.supplyFactor(); + uint256 rswEthIonPoolSF = rswEthIonPool.supplyFactor(); + + vault.deposit(depositAmount, address(this)); + + // weEthIonPool should be full at 10e18 + // IDLE should be full at 20e18 + // rsEthIonPool should be full at 30e18 + // rswEthIonPool should be at 10e18 + assertLe( + 10e18 - weEthIonPool.balanceOf(address(vault)), postDepositClaimRE(10e18, weEthIonPoolSF), "weEthIonPool" + ); + assertEq(BASE_ASSET.balanceOf(address(vault)), 20e18, "IDLE"); + assertLe( + 30e18 - rsEthIonPool.balanceOf(address(vault)), postDepositClaimRE(30e18, rsEthIonPoolSF), "rsEthIonPool" + ); + assertLe( + 10e18 - rswEthIonPool.balanceOf(address(vault)), postDepositClaimRE(10e18, rswEthIonPoolSF), "rswEthIonPool" + ); + assertEq(BASE_ASSET.balanceOf(address(this)), 0, "user balance"); + } + + function test_Deposit_AllMarkets_SecondDeposit() public { } + + function test_Mint_AllMarkets_FirstMint() public { + uint256 sharesToMint = 70e18; + + uint256 weEthIonPoolSF = weEthIonPool.supplyFactor(); + uint256 rsEthIonPoolSF = rsEthIonPool.supplyFactor(); + uint256 rswEthIonPoolSF = rswEthIonPool.supplyFactor(); + + uint256 expectedDepositAmount = vault.previewMint(sharesToMint); + setERC20Balance(address(BASE_ASSET), address(this), expectedDepositAmount); + + vault.mint(sharesToMint, address(this)); + + uint256 remainingAssets = expectedDepositAmount; + + uint256 expectedWeEthIonPoolClaim = Math.min(remainingAssets, vault.caps(weEthIonPool)); + remainingAssets -= expectedWeEthIonPoolClaim; + + uint256 expectedIdleClaim = Math.min(remainingAssets, vault.caps(IDLE)); + remainingAssets -= expectedIdleClaim; + + uint256 expectedRsEthIonPoolClaim = Math.min(remainingAssets, vault.caps(rsEthIonPool)); + remainingAssets -= expectedRsEthIonPoolClaim; + + uint256 expectedRswEthIonPoolClaim = Math.min(remainingAssets, vault.caps(rswEthIonPool)); + remainingAssets -= expectedRswEthIonPoolClaim; + + assertEq(remainingAssets, 0, "test variables"); + assertLe( + expectedWeEthIonPoolClaim - weEthIonPool.balanceOf(address(vault)), + postDepositClaimRE(expectedWeEthIonPoolClaim, weEthIonPoolSF), + "weEthIonPool" + ); + assertEq(BASE_ASSET.balanceOf(address(vault)), expectedIdleClaim, "IDLE"); + assertLe( + expectedRsEthIonPoolClaim - rsEthIonPool.balanceOf(address(vault)), + postDepositClaimRE(expectedWeEthIonPoolClaim, rsEthIonPoolSF), + "rsEthIonPool" + ); + assertLe( + expectedRswEthIonPoolClaim - rswEthIonPool.balanceOf(address(vault)), + postDepositClaimRE(expectedRswEthIonPoolClaim, rswEthIonPoolSF), + "rswEthIonPool" + ); + assertEq(BASE_ASSET.balanceOf(address(this)), 0, "user balance"); + } + + function test_Mint_AllMarkets_SecondMint() public { } + + function test_PartialWithdraw() public { + uint256 depositAmount = 70e18; + setERC20Balance(address(BASE_ASSET), address(this), depositAmount); + vault.deposit(depositAmount, address(this)); + + // expected values + uint256 prevTotalAssets = vault.totalAssets(); + uint256 supplyFactor = rsEthIonPool.supplyFactor(); + + uint256 weEthIonPoolClaim = weEthIonPool.balanceOf(address(vault)); + uint256 idleClaim = BASE_ASSET.balanceOf(address(vault)); + uint256 rsEthIonPoolClaim = rsEthIonPool.balanceOf(address(vault)); + uint256 rswEthIonPoolClaim = rswEthIonPool.balanceOf(address(vault)); + + uint256 withdrawAmount = 40e18; + + uint256 expectedTotalAssets = prevTotalAssets - withdrawAmount; + + uint256 remainingAssets = withdrawAmount; + + uint256 weEthIonPoolWithdraw = Math.min(weEthIonPoolClaim, remainingAssets); + remainingAssets -= weEthIonPoolWithdraw; // about 10 out of 10 + + uint256 idleWithdraw = Math.min(idleClaim, remainingAssets); + remainingAssets -= idleWithdraw; // about 20 out of 20 + + uint256 rsEthIonPoolWithdraw = Math.min(rsEthIonPoolClaim, remainingAssets); + remainingAssets -= rsEthIonPoolWithdraw; // about 10 out of 30 + + // uint256 rswEthIonPoolWithdraw = Math.min(rswEthIonPoolClaim, remainingAssets); + // remainingAssets -= rswEthIonPoolWithdraw; + + assertEq(remainingAssets, 0, "test variables"); + + vault.withdraw(withdrawAmount, address(this), address(this)); + + // vault total assets decreases by withdraw amount + rounding error + assertLe( + expectedTotalAssets - vault.totalAssets(), + postDepositClaimRE(withdrawAmount, supplyFactor), + "vault total assets" + ); + assertEq(weEthIonPool.balanceOf(address(vault)), 0, "weEthIonPool claim"); + assertEq(BASE_ASSET.balanceOf(address(vault)), 0, "idle deposits"); + assertLt( + (rsEthIonPoolClaim - rsEthIonPoolWithdraw) - rsEthIonPool.balanceOf(address(vault)), + postDepositClaimRE(withdrawAmount, supplyFactor), + "rsEthIonPool claim" + ); + assertEq(rswEthIonPool.balanceOf(address(vault)), rswEthIonPoolClaim, "rswEthIonPool claim"); + + // user gains withdrawn balance + assertEq(BASE_ASSET.balanceOf(address(this)), withdrawAmount, "user base asset balance"); + } + + function test_MaxWithdraw() public { + uint256 depositAmount = 70e18; + setERC20Balance(address(BASE_ASSET), address(this), depositAmount); + vault.deposit(depositAmount, address(this)); + + uint256 withdrawAmount = vault.maxWithdraw(address(this)); + vault.withdraw(withdrawAmount, address(this), address(this)); + + assertEq(vault.totalAssets(), 0, "vault total assets"); + assertEq(vault.totalSupply(), 0, "vault total shares"); + + assertEq(BASE_ASSET.balanceOf(address(this)), withdrawAmount, "user base asset balance"); + assertEq(vault.balanceOf(address(this)), 0, "user shares balance"); + } + + function test_MaxRedeem() public { + uint256 depositAmount = 70e18; + setERC20Balance(address(BASE_ASSET), address(this), depositAmount); + vault.deposit(depositAmount, address(this)); + + // all deposits are available to be withdrawn. + uint256 redeemAmount = vault.maxRedeem(address(this)); + + uint256 withdrawnAssets = vault.redeem(redeemAmount, address(this), address(this)); + + uint256 weEthRoundingError = (weEthIonPool.supplyFactor()) / RAY + 1; + uint256 rsEthRoundingError = (rsEthIonPool.supplyFactor()) / RAY + 1; + uint256 rswEthRoundingError = (rswEthIonPool.supplyFactor()) / RAY + 1; + uint256 roundingError = weEthRoundingError + rsEthRoundingError + rswEthRoundingError; + + // _maxWithdraw rounds down inside the `IonPool` to calculate the claims + // and the shares conversion rounds down again. + assertLe(vault.totalAssets(), roundingError, "vault total assets"); + assertLe(vault.totalSupply(), roundingError, "vault total shares"); + + assertEq(withdrawnAssets, BASE_ASSET.balanceOf(address(this)), "user base asset balance"); + assertLe(vault.balanceOf(address(this)), 1, "user shares balance"); + } + + function test_Reallocate_DepositToIdle() public { + uint256 depositAmount = 70e18; + setERC20Balance(address(BASE_ASSET), address(this), depositAmount); + vault.deposit(depositAmount, address(this)); + + IIonPool[] memory ionPoolToUpdate = new IIonPool[](1); + ionPoolToUpdate[0] = IDLE; + uint256[] memory newAllocationCaps = new uint256[](1); + newAllocationCaps[0] = 50e18; + + vm.prank(OWNER); + vault.updateAllocationCaps(ionPoolToUpdate, newAllocationCaps); + + // 10 weEth 20 idle 30 rsEth 10 rswEth + uint256 prevWeEthClaim = weEthIonPool.balanceOf(address(vault)); + uint256 prevIdleClaim = BASE_ASSET.balanceOf(address(vault)); + uint256 prevRsEthClaim = rsEthIonPool.balanceOf(address(vault)); + uint256 prevRswEthClaim = rswEthIonPool.balanceOf(address(vault)); + + uint256 weEthSF = weEthIonPool.supplyFactor(); + uint256 rsEthSF = rsEthIonPool.supplyFactor(); + + int256 weEthDiff = -1e18; + int256 rsEthDiff = -2e18; + int256 idleDiff = 3e18; + + uint256 expectedWeEthClaim = uint256(int256(prevWeEthClaim) + weEthDiff); + uint256 expectedIdleClaim = uint256(int256(prevIdleClaim) + idleDiff); + uint256 expectedRsEthClaim = uint256(int256(prevRsEthClaim) + rsEthDiff); + + // withdraw 5 from weEth, withdraw 7 from idle, deposit 12 to rswEth + Vault.MarketAllocation[] memory allocs = new Vault.MarketAllocation[](3); + allocs[0] = Vault.MarketAllocation({ pool: weEthIonPool, assets: weEthDiff }); + allocs[1] = Vault.MarketAllocation({ pool: rsEthIonPool, assets: rsEthDiff }); + allocs[2] = Vault.MarketAllocation({ pool: IDLE, assets: idleDiff }); + + vm.prank(ALLOCATOR); + vault.reallocate(allocs); + + assertLt( + expectedWeEthClaim - weEthIonPool.balanceOf(address(vault)), postDepositClaimRE(0, weEthSF), "weEthIonPol" + ); + assertEq(BASE_ASSET.balanceOf(address(vault)), expectedIdleClaim, "IDLE"); + assertLt( + expectedRsEthClaim - rsEthIonPool.balanceOf(address(vault)), postDepositClaimRE(0, rsEthSF), "rswEthIonPol" + ); + assertEq(prevRswEthClaim, rswEthIonPool.balanceOf(address(vault)), "rswEthIonPool"); + } + + function test_Reallocate_WithdrawFromIdle() public { + uint256 depositAmount = 70e18; + setERC20Balance(address(BASE_ASSET), address(this), depositAmount); + vault.deposit(depositAmount, address(this)); + + // 10 weEth 20 idle 30 rsEth 10 rswEth + uint256 prevWeEthClaim = weEthIonPool.balanceOf(address(vault)); + uint256 prevIdleClaim = BASE_ASSET.balanceOf(address(vault)); + uint256 prevRsEthClaim = rsEthIonPool.balanceOf(address(vault)); + uint256 prevRswEthClaim = rswEthIonPool.balanceOf(address(vault)); + + uint256 weEthSF = weEthIonPool.supplyFactor(); + uint256 rswEthSF = rswEthIonPool.supplyFactor(); + + int256 weEthDiff = -5e18; + int256 idleDiff = -7e18; + int256 rswEthDiff = 12e18; + + uint256 expectedWeEthClaim = uint256(int256(prevWeEthClaim) + weEthDiff); + uint256 expectedIdleClaim = uint256(int256(prevIdleClaim) + idleDiff); + uint256 expectedRswEthClaim = uint256(int256(prevRswEthClaim) + rswEthDiff); + + // withdraw 5 from weEth, withdraw 7 from idle, deposit 12 to rswEth + Vault.MarketAllocation[] memory allocs = new Vault.MarketAllocation[](3); + allocs[0] = Vault.MarketAllocation({ pool: weEthIonPool, assets: weEthDiff }); + allocs[1] = Vault.MarketAllocation({ pool: IDLE, assets: idleDiff }); + allocs[2] = Vault.MarketAllocation({ pool: rswEthIonPool, assets: rswEthDiff }); + + vm.prank(ALLOCATOR); + vault.reallocate(allocs); + + assertLt( + expectedWeEthClaim - weEthIonPool.balanceOf(address(vault)), postDepositClaimRE(0, weEthSF), "weEthIonPol" + ); + assertEq(BASE_ASSET.balanceOf(address(vault)), expectedIdleClaim, "IDLE"); + assertLt( + expectedRswEthClaim - rswEthIonPool.balanceOf(address(vault)), + postDepositClaimRE(0, rswEthSF), + "rswEthIonPol" + ); + assertEq(prevRsEthClaim, rsEthIonPool.balanceOf(address(vault)), "rsEthIonPool"); + } +} + +contract VaultERC4626ExternalViews is VaultSharedSetup { + function setUp() public override { + super.setUp(); + } + + function test_TotalAssetsWithSinglePausedIonPool() public { + weEthIonPool.updateSupplyCap(type(uint256).max); + weEthIonPool.updateIlkDebtCeiling(0, type(uint256).max); + + supply(address(this), weEthIonPool, 1000e18); + borrow(address(this), weEthIonPool, weEthGemJoin, 100e18, 70e18); + + uint256[] memory allocationCaps = new uint256[](3); + allocationCaps[0] = 20e18; + allocationCaps[1] = 0; + allocationCaps[2] = 0; + + vm.prank(OWNER); + vault.updateAllocationCaps(markets, allocationCaps); + + uint256 depositAmt = 10e18; + setERC20Balance(address(BASE_ASSET), address(this), depositAmt); + vault.deposit(depositAmt, address(this)); + + assertEq(weEthIonPool.balanceOf(address(vault)), depositAmt, "weEthIonPool balance"); + + // Pause the weEthIonPool, stop accruing interest + weEthIonPool.pause(); + assertTrue(weEthIonPool.paused(), "weEthIonPool is paused"); + + vm.warp(block.timestamp + 365 days); + + assertEq(weEthIonPool.balanceOf(address(vault)), depositAmt, "weEthIonPool accrues interest"); + assertEq( + weEthIonPool.balanceOfUnaccrued(address(vault)), + weEthIonPool.balanceOf(address(vault)), + "weEthIonPool unaccrued balance" + ); + + uint256 totalAssets = vault.totalAssets(); + assertEq(totalAssets, depositAmt, "total assets with paused IonPool does not include interest"); + + // When unpaused, should now accrue interest + weEthIonPool.unpause(); + vm.warp(block.timestamp + 365 days); + + assertGt(weEthIonPool.balanceOf(address(vault)), depositAmt, "weEthIonPool accrues interest"); + assertGt( + weEthIonPool.balanceOf(address(vault)), + weEthIonPool.balanceOfUnaccrued(address(vault)), + "weEthIonPool unaccrued balance" + ); + + assertGt(vault.totalAssets(), depositAmt, "total assets with paused IonPool does not include interest"); + } + + function test_TotalAssetsWithMultiplePausedIonPools() public { + // Make sure every pool has debt to accrue interest from + uint256 initialSupplyAmt = 1000e18; + weEthIonPool.updateSupplyCap(type(uint256).max); + rsEthIonPool.updateSupplyCap(type(uint256).max); + rswEthIonPool.updateSupplyCap(type(uint256).max); + + weEthIonPool.updateIlkDebtCeiling(0, type(uint256).max); + rsEthIonPool.updateIlkDebtCeiling(0, type(uint256).max); + rswEthIonPool.updateIlkDebtCeiling(0, type(uint256).max); + + supply(address(this), weEthIonPool, initialSupplyAmt); + borrow(address(this), weEthIonPool, weEthGemJoin, 100e18, 70e18); + + supply(address(this), rsEthIonPool, initialSupplyAmt); + borrow(address(this), rsEthIonPool, rsEthGemJoin, 100e18, 70e18); + + supply(address(this), rswEthIonPool, initialSupplyAmt); + borrow(address(this), rswEthIonPool, rswEthGemJoin, 100e18, 70e18); + + uint256[] memory allocationCaps = new uint256[](3); + uint256 weEthIonPoolAmt = 10e18; + uint256 rsEthIonPoolAmt = 20e18; + uint256 rswEthIonPoolAmt = 30e18; + allocationCaps[0] = weEthIonPoolAmt; + allocationCaps[1] = rsEthIonPoolAmt; + allocationCaps[2] = rswEthIonPoolAmt; + + vm.prank(OWNER); + vault.updateAllocationCaps(markets, allocationCaps); + + uint256 depositAmt = 60e18; + setERC20Balance(address(BASE_ASSET), address(this), depositAmt); + vault.deposit(depositAmt, address(this)); + + assertEq(weEthIonPool.balanceOf(address(vault)), weEthIonPoolAmt, "weEthIonPool balance"); + assertEq(rsEthIonPool.balanceOf(address(vault)), rsEthIonPoolAmt, "rsEthIonPool balance"); + assertEq(rswEthIonPool.balanceOf(address(vault)), rswEthIonPoolAmt, "rswEthIonPool balance"); + + weEthIonPool.pause(); + // NOTE rsEthIonPool is not paused + rswEthIonPool.pause(); + + assertTrue(weEthIonPool.paused(), "weEthIonPool is paused"); + assertFalse(rsEthIonPool.paused(), "rsEthIonPool is not paused"); + assertTrue(rswEthIonPool.paused(), "rswEthIonPool is paused"); + + vm.warp(block.timestamp + 365 days); + + // The 'unaccrued' values should not change + assertEq(weEthIonPool.balanceOfUnaccrued(address(vault)), weEthIonPoolAmt, "weEthIonPool balance"); + assertEq(rsEthIonPool.balanceOfUnaccrued(address(vault)), rsEthIonPoolAmt, "rsEthIonPool balance"); + assertEq(rswEthIonPool.balanceOfUnaccrued(address(vault)), rswEthIonPoolAmt, "rswEthIonPool balance"); + + // When paused, the unaccrued and accrued balanceOf should be the same + assertEq( + weEthIonPool.balanceOf(address(vault)), + weEthIonPool.balanceOfUnaccrued(address(vault)), + "weEthIonPool balance increases" + ); + assertEq( + rswEthIonPool.balanceOf(address(vault)), + rswEthIonPool.balanceOfUnaccrued(address(vault)), + "rswEthIonPool balance increases" + ); + + // When not paused, the accrued balanceOf should be greater + assertGt( + rsEthIonPool.balanceOf(address(vault)), + rsEthIonPool.balanceOfUnaccrued(address(vault)), + "rsEthIonPool balance does not change" + ); + + uint256 expectedTotalAssets = weEthIonPool.balanceOfUnaccrued(address(vault)) + + rsEthIonPool.balanceOf(address(vault)) + rswEthIonPool.balanceOfUnaccrued(address(vault)); + + assertEq( + vault.totalAssets(), expectedTotalAssets, "total assets without accounting for interest in paused IonPools" + ); + } + + // --- Max --- + // Get max and submit max transactions + + function test_MaxDepositView_AllocationAndSupplyCaps() public { + uint256 maxDeposit = vault.maxDeposit(NULL); + assertEq(maxDeposit, 0, "initial max deposit"); + + uint256[] memory allocationCaps = new uint256[](3); + allocationCaps[0] = 10e18; + allocationCaps[1] = 20e18; + allocationCaps[2] = 30e18; + + vm.prank(OWNER); + vault.updateAllocationCaps(markets, allocationCaps); + + maxDeposit = vault.maxDeposit(NULL); + assertEq(maxDeposit, 60e18, "new max deposit after update allocation cap"); + + // change IonPool supply cap + weEthIonPool.updateSupplyCap(5e18); // 10 allocation cap > 5 supply cap + + maxDeposit = vault.maxDeposit(NULL); + assertEq(maxDeposit, 55e18, "max deposit after update supply cap"); + } + + function test_MaxDeposit_AfterDeposits() public { } + + function test_MaxMint_MintAmount() public { + uint256[] memory allocationCaps = new uint256[](3); + allocationCaps[0] = 10e18; + allocationCaps[1] = 20e18; + allocationCaps[2] = 30e18; + + vm.prank(OWNER); + vault.updateAllocationCaps(markets, allocationCaps); + + uint256 maxMintShares = vault.maxMint(NULL); + + setERC20Balance(address(BASE_ASSET), address(this), 60e18); + vault.mint(maxMintShares, address(this)); + + uint256 resultingShares = vault.balanceOf(address(this)); + + uint256 maxWithdrawableAssets = vault.previewRedeem(resultingShares); + uint256 maxRedeemableShares = vault.previewWithdraw(maxWithdrawableAssets); + + assertEq(resultingShares, 60e18, "resulting shares"); + assertEq(maxWithdrawableAssets, 60e18, "resulting claim"); + assertEq(maxRedeemableShares, 60e18, "redeemable shares"); + } + + function test_MaxWithdraw() public { } + + function test_MaxRedeem() public { } + + function test_MaxWithdrawWithPausedPools() public { + uint256[] memory allocationCaps = new uint256[](3); + allocationCaps[0] = 10e18; + allocationCaps[1] = 20e18; + allocationCaps[2] = 30e18; + + vm.prank(OWNER); + vault.updateAllocationCaps(markets, allocationCaps); + + uint256 depositAmt = 35e18; + setERC20Balance(address(BASE_ASSET), address(this), depositAmt); + vault.deposit(depositAmt, address(this)); + + uint256 maxWithdrawBeforePause = vault.maxWithdraw(address(this)); + + weEthIonPool.pause(); + uint256 maxWithdrawAfterPause = vault.maxWithdraw(address(this)); + + rsEthIonPool.pause(); + uint256 maxWithdrawAfterSecondPause = vault.maxWithdraw(address(this)); + + rswEthIonPool.pause(); + uint256 maxWithdrawAfterThirdPause = vault.maxWithdraw(address(this)); + + assertEq(maxWithdrawBeforePause, depositAmt, "max withdraw before pause"); + assertEq(maxWithdrawAfterPause, depositAmt - 10e18, "max withdraw after pause"); + assertEq(maxWithdrawAfterSecondPause, depositAmt - 30e18, "max withdraw after second pause"); + assertEq(maxWithdrawAfterThirdPause, 0, "max withdraw after third pause"); + } + + function test_MaxDepositWithPausedPools() public { + uint256[] memory allocationCaps = new uint256[](3); + allocationCaps[0] = 10e18; + allocationCaps[1] = 20e18; + allocationCaps[2] = 30e18; + + vm.prank(OWNER); + vault.updateAllocationCaps(markets, allocationCaps); + + uint256 maxDepositBeforePause = vault.maxDeposit(NULL); + + weEthIonPool.pause(); + uint256 maxDepositAfterPause = vault.maxDeposit(NULL); + + rsEthIonPool.pause(); + uint256 maxDepositAfterSecondPause = vault.maxDeposit(NULL); + + rswEthIonPool.pause(); + uint256 maxDepositAfterThirdPause = vault.maxDeposit(NULL); + + assertEq(maxDepositBeforePause, 60e18, "max deposit before pause"); + assertEq(maxDepositAfterPause, 50e18, "max deposit after pause"); + assertEq(maxDepositAfterSecondPause, 30e18, "max deposit after second pause"); + assertEq(maxDepositAfterThirdPause, 0, "max deposit after third pause"); + } + + function test_WithdrawWithPausedPools() public { } + + // --- Previews --- + + // Check the difference between preview and actual + + function test_PreviewDeposit() public { } + + function test_PreviewMint() public { } + + function test_PreviewWithdraw() public { } + + function test_PreviewRedeem() public { } +} + +contract VaultInflationAttack is VaultSharedSetup { + function setUp() public override { + super.setUp(); + } + + /** + * Starting Attacker Balance: 11e18 + 10 + * Attacker Mint: 10 shares + * Attacker Donation: 11e18 + * Alice Deposit: 1e18 + * Alice Shares Minted: + * + * How much did the attacker lose during the donation? + * Attacker Donated 11e18, + */ + function test_InflationAttackNotProfitable() public { + IIonPool[] memory market = new IIonPool[](1); + market[0] = IDLE; + + uint256[] memory allocationCaps = new uint256[](1); + allocationCaps[0] = type(uint256).max; + + IIonPool[] memory queue = new IIonPool[](4); + queue[0] = IDLE; + queue[1] = weEthIonPool; + queue[2] = rsEthIonPool; + queue[3] = rswEthIonPool; + + vm.prank(OWNER); + vault.addSupportedMarkets(market, allocationCaps, queue, queue); + + uint256 donationAmt = 11e18; + uint256 mintAmt = 10; + + // fund attacker + setERC20Balance(address(BASE_ASSET), address(this), donationAmt + mintAmt); + + uint256 initialAssetBalance = BASE_ASSET.balanceOf(address(this)); + console2.log("attacker balance before : "); + console2.log(initialAssetBalance); + + vault.mint(mintAmt, address(this)); + uint256 attackerClaimAfterMint = vault.previewRedeem(vault.balanceOf(address(this))); + + console2.log("attackerClaimAfterMint: "); + console2.log(attackerClaimAfterMint); + + console2.log("donationAmt: "); + console2.log(donationAmt); + + // donate to inflate exchange rate by increasing `totalAssets` + IERC20(address(BASE_ASSET)).transfer(address(vault), donationAmt); + + // how much of this donation was captured by the virtual shares on the vault? + uint256 attackerClaimAfterDonation = vault.previewRedeem(vault.balanceOf(address(this))); + + console2.log("attackerClaimAfterDonation: "); + console2.log(attackerClaimAfterDonation); + + uint256 lossFromDonation = attackerClaimAfterMint + donationAmt - attackerClaimAfterDonation; + + console2.log("loss from donation: "); + console2.log(lossFromDonation); + + address alice = address(0xabcd); + setERC20Balance(address(BASE_ASSET), alice, 10e18 + 10); + + vm.startPrank(alice); + IERC20(address(BASE_ASSET)).approve(address(vault), 1e18); + vault.deposit(1e18, alice); + vm.stopPrank(); + + // Alice gained zero shares due to exchange rate inflation + uint256 aliceShares = vault.balanceOf(alice); + console.log("alice must lose all her shares : "); + console.log(aliceShares); + + // How much of alice's deposits were captured by the attacker's shares? + uint256 attackerClaimAfterAlice = vault.previewRedeem(vault.balanceOf(address(this))); + uint256 attackerGainFromAlice = attackerClaimAfterAlice - attackerClaimAfterDonation; + console2.log("attackerGainFromAlice: "); + console2.log(attackerGainFromAlice); + + vault.redeem(vault.balanceOf(address(this)) - 3, address(this), address(this)); + uint256 afterAssetBalance = BASE_ASSET.balanceOf(address(this)); + + console.log("attacker balance after : "); + console.log(afterAssetBalance); + + assertLe(attackerGainFromAlice, lossFromDonation, "attack must not be profitable"); + assertLe(afterAssetBalance, initialAssetBalance, "attacker must not be profitable"); + } +} + +contract VaultDeposit_WithoutSupplyFactor is VaultDeposit { + function setUp() public override(VaultDeposit) { + super.setUp(); + } +} + +contract VaultDeposit_WithSupplyFactor is VaultDeposit { + function setUp() public override(VaultDeposit) { + super.setUp(); + withSupplyFactor(); + } +} + +contract VaultDeposit_WithInflatedSupplyFactor is VaultDeposit { + function setUp() public override(VaultDeposit) { + super.setUp(); + withInflatedSupplyFactor(); + } +} + +contract VaultWithdraw_WithoutSupplyFactor is VaultWithdraw { + function setUp() public override(VaultWithdraw) { + super.setUp(); + } +} + +contract VaultWithdraw_WithSupplyFactor is VaultWithdraw { + function setUp() public override(VaultWithdraw) { + super.setUp(); + withSupplyFactor(); + } +} + +contract VaultWithdraw_WithInflatedSupplyFactor is VaultWithdraw { + function setUp() public override(VaultWithdraw) { + super.setUp(); + withInflatedSupplyFactor(); + } +} + +contract VaultReallocate_WithoutSupplyFactor is VaultReallocate { + function setUp() public override(VaultReallocate) { + super.setUp(); + } +} + +contract VaultReallocate_WithSupplyFactor is VaultReallocate { + function setUp() public override(VaultReallocate) { + super.setUp(); + withSupplyFactor(); + } +} + +contract VaultReallocate_WithInflatedSupplyFactor is VaultReallocate { + function setUp() public override(VaultReallocate) { + super.setUp(); + withInflatedSupplyFactor(); + } +} + +contract VaultWithIdlePool_WithoutSupplyFactor is VaultWithIdlePool { + function setUp() public override(VaultWithIdlePool) { + super.setUp(); + } +} + +contract VaultWithIdlePool_WithSupplyFactor is VaultWithIdlePool { + function setUp() public override(VaultWithIdlePool) { + super.setUp(); + withSupplyFactor(); + } +} + +contract VaultWithIdlePool_WithInflatedSupplyFactor is VaultWithIdlePool { + function setUp() public override(VaultWithIdlePool) { + super.setUp(); + withInflatedSupplyFactor(); + } +} diff --git a/test/unit/concrete/vault/VaultWithYield.t.sol b/test/unit/concrete/vault/VaultWithYield.t.sol new file mode 100644 index 00000000..cbdfe74b --- /dev/null +++ b/test/unit/concrete/vault/VaultWithYield.t.sol @@ -0,0 +1,90 @@ +// // SPDX-License-Identifier: GPL-2.0-or-later +// pragma solidity 0.8.21; + +// import { VaultSharedSetup } from "../../../helpers/VaultSharedSetup.sol"; + +// import { console2 } from "forge-std/console2.sol"; + +// contract Vault_WithYieldWithoutFee is VaultSharedSetup { +// uint256 constant INITIAL_SUPPLY_AMT = 1000e18; + +// function setUp() public virtual override { +// super.setUp(); + +// weEthIonPool.updateSupplyCap(type(uint256).max); +// rsEthIonPool.updateSupplyCap(type(uint256).max); +// rswEthIonPool.updateSupplyCap(type(uint256).max); + +// weEthIonPool.updateIlkDebtCeiling(0, type(uint256).max); +// rsEthIonPool.updateIlkDebtCeiling(0, type(uint256).max); +// rswEthIonPool.updateIlkDebtCeiling(0, type(uint256).max); + +// supply(address(this), weEthIonPool, INITIAL_SUPPLY_AMT); +// borrow(address(this), weEthIonPool, weEthGemJoin, 100e18, 70e18); + +// supply(address(this), rsEthIonPool, INITIAL_SUPPLY_AMT); +// borrow(address(this), rsEthIonPool, rsEthGemJoin, 100e18, 70e18); + +// supply(address(this), rswEthIonPool, INITIAL_SUPPLY_AMT); +// borrow(address(this), rswEthIonPool, rswEthGemJoin, 100e18, 70e18); +// } + +// function test_AccrueYieldSingleMarket_NoFee() public { +// // When yield is accrued, +// // the total assets increases, +// // the vault shares should stay the same. + +// uint256 depositAmount = 100e18; +// setERC20Balance(address(BASE_ASSET), address(this), depositAmount); + +// updateSupplyQueue(vault, weEthIonPool, rsEthIonPool, rswEthIonPool); +// updateSupplyCaps(vault, type(uint256).max, type(uint256).max, type(uint256).max); +// updateAllocationCaps(vault, type(uint256).max, type(uint256).max, type(uint256).max); + +// vault.deposit(depositAmount, address(this)); + +// // before yield accrual +// uint256 prevTotalAssets = vault.totalAssets(); +// uint256 prevWeEthIonPoolClaim = weEthIonPool.getUnderlyingClaimOf(address(vault)); + +// vm.warp(block.timestamp + 365 days); + +// (uint256 totalSupplyFactorIncrease,,,,) = weEthIonPool.calculateRewardAndDebtDistribution(); +// console2.log("totalSupplyFactorIncrease: ", totalSupplyFactorIncrease); +// assertGt(totalSupplyFactorIncrease, 0, "total supply factor increase"); + +// weEthIonPool.accrueInterest(); + +// // after yield accrual +// uint256 newTotalAssets = vault.totalAssets(); +// uint256 newWeEthIonPoolClaim = weEthIonPool.getUnderlyingClaimOf(address(vault)); + +// console2.log("prevTotalAssets: ", prevTotalAssets); +// console2.log("newTotalAssets: ", newTotalAssets); + +// // ionPool +// assertEq( +// newTotalAssets - prevTotalAssets, newWeEthIonPoolClaim - prevTotalAssets, "yield accrual to total assets" +// ); + +// // vault + +// // users +// } + +// function test_AccrueYieldSingleMarket_WithFee() public { + +// } + +// function test_AccrueYieldAllMarkets() public { } + +// function test_WithFee_AccrueYieldSingleMarket() public { } + +// function test_WithFee_AccrueYieldAllMarkets() public { } +// } + +// contract Vault_WithRate_WithYieldAndFee is Vault_WithYieldAndFee { +// function setUp() public override { +// super.setUp(); +// } +// } diff --git a/test/unit/fuzz/IonPool.t.sol b/test/unit/fuzz/IonPool.t.sol index 8fccbbcb..6414fe1b 100644 --- a/test/unit/fuzz/IonPool.t.sol +++ b/test/unit/fuzz/IonPool.t.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.21; import { IonPool } from "../../../src/IonPool.sol"; import { WadRayMath, RAY } from "../../../src/libraries/math/WadRayMath.sol"; +import { ISpotOracle } from "../../../src/interfaces/ISpotOracle.sol"; import { IIonPoolEvents } from "../../helpers/IIonPoolEvents.sol"; import { IonPoolSharedSetup } from "../../helpers/IonPoolSharedSetup.sol"; @@ -49,11 +50,11 @@ abstract contract IonPool_LenderFuzzTestBase is IonPoolSharedSetup, IIonPoolEven uint256 normalizedAmount = supplyAmount.rayDivDown(currentSupplyFactor); vm.assume(supplyAmount < type(uint128).max && normalizedAmount > 0); - uint256 supplyAmountBeforeSupply = ionPool.weth(); + uint256 supplyAmountBeforeSupply = lens.liquidity(iIonPool); underlying.mint(lender1, supplyAmount); - uint256 currentTotalDebt = ionPool.debt(); + uint256 currentTotalDebt = lens.debt(iIonPool); (uint256 supplyFactorIncrease,,, uint256 newDebtIncrease,) = ionPool.calculateRewardAndDebtDistribution(); vm.expectEmit(true, true, true, true); @@ -69,11 +70,12 @@ abstract contract IonPool_LenderFuzzTestBase is IonPoolSharedSetup, IIonPoolEven vm.prank(lender1); ionPool.supply(lender1, supplyAmount, new bytes32[](0)); - assertEq(ionPool.weth(), supplyAmountBeforeSupply + supplyAmount); - assertEq(ionPool.balanceOf(lender1), normalizedAmount.rayMulDown(currentSupplyFactor)); + assertEq(lens.liquidity(iIonPool), supplyAmountBeforeSupply + supplyAmount, "weth"); + assertEq(ionPool.normalizedBalanceOf(lender1), normalizedAmount, "ionPool balanceOf"); uint256 roundingError = currentSupplyFactor / RAY; - assertLe(ionPool.balanceOf(lender1) - roundingError, supplyAmount); + + assertLe(ionPool.balanceOf(lender1) - roundingError, supplyAmount, "balanceOf rounding error"); } function testFuzz_SupplyBaseToDifferentAddress(uint256 supplyAmount) public { @@ -84,9 +86,9 @@ abstract contract IonPool_LenderFuzzTestBase is IonPoolSharedSetup, IIonPoolEven underlying.mint(lender1, supplyAmount); - uint256 supplyAmountBeforeSupply = ionPool.weth(); + uint256 supplyAmountBeforeSupply = lens.liquidity(iIonPool); - uint256 currentTotalDebt = ionPool.debt(); + uint256 currentTotalDebt = lens.debt(iIonPool); (uint256 supplyFactorIncrease,,, uint256 newDebtIncrease,) = ionPool.calculateRewardAndDebtDistribution(); vm.expectEmit(true, true, true, true); @@ -102,8 +104,8 @@ abstract contract IonPool_LenderFuzzTestBase is IonPoolSharedSetup, IIonPoolEven vm.prank(lender1); ionPool.supply(address(this), supplyAmount, new bytes32[](0)); - assertEq(ionPool.weth(), supplyAmountBeforeSupply + supplyAmount); - assertEq(ionPool.balanceOf(address(this)), normalizedAmount.rayMulDown(currentSupplyFactor)); + assertEq(lens.liquidity(iIonPool), supplyAmountBeforeSupply + supplyAmount); + assertEq(ionPool.normalizedBalanceOf(address(this)), normalizedAmount); uint256 roundingError = currentSupplyFactor / RAY; assertLe(ionPool.balanceOf(address(this)) - roundingError, supplyAmount); @@ -129,7 +131,7 @@ abstract contract IonPool_LenderFuzzTestBase is IonPoolSharedSetup, IIonPoolEven // Changing supply factor, means that the interest will be deposited _changeSupplyFactorIfNeeded(); - uint256 supplyAmountAfterRebase = ionPool.weth(); + uint256 supplyAmountAfterRebase = lens.liquidity(iIonPool); uint256 lender1BalanceAfterRebase = ionPool.balanceOf(lender1); assertEq(supplyAmountAfterRebase, lender1BalanceAfterRebase); @@ -141,7 +143,7 @@ abstract contract IonPool_LenderFuzzTestBase is IonPoolSharedSetup, IIonPoolEven uint256 underlyingBeforeWithdraw = underlying.balanceOf(lender1); uint256 rewardAssetBalanceBeforeWithdraw = ionPool.balanceOf(lender1); - locs.currentTotalDebt = ionPool.debt(); + locs.currentTotalDebt = lens.debt(iIonPool); (locs.supplyFactorIncrease,,, locs.newDebtIncrease,) = ionPool.calculateRewardAndDebtDistribution(); vm.expectEmit(true, true, true, true); @@ -162,13 +164,13 @@ abstract contract IonPool_LenderFuzzTestBase is IonPoolSharedSetup, IIonPoolEven uint256 underlyingWithdrawn = underlyingAfterWithdraw - underlyingBeforeWithdraw; uint256 rewardAssetBurned = rewardAssetBalanceBeforeWithdraw - rewardAssetBalanceAfterWithdraw; - assertEq(ionPool.weth(), supplyAmountAfterRebase - locs.withdrawAmount); + assertEq(lens.liquidity(iIonPool), supplyAmountAfterRebase - locs.withdrawAmount); assertEq(underlyingAfterWithdraw, underlyingBeforeWithdraw + locs.withdrawAmount); // Most important invariant assertGe(rewardAssetBurned, underlyingWithdrawn); uint256 roundingError = currentSupplyFactor / RAY; - assertLt(ionPool.balanceOf(lender1), lender1BalanceAfterRebase - locs.withdrawAmount + roundingError); + assertLt(ionPool.normalizedBalanceOf(lender1), lender1BalanceAfterRebase - locs.withdrawAmount + roundingError); } function testFuzz_WithdrawBaseToDifferentAddress(uint256 supplyAmount, uint256 withdrawAmount) public { @@ -184,10 +186,10 @@ abstract contract IonPool_LenderFuzzTestBase is IonPoolSharedSetup, IIonPoolEven // Changing supply factor, means that the interest will be deposited _changeSupplyFactorIfNeeded(); - uint256 supplyAmountAfterRebase = ionPool.weth(); + uint256 supplyAmountAfterRebase = lens.liquidity(iIonPool); uint256 lender1BalanceAfterRebase = ionPool.balanceOf(lender1); - assertEq(supplyAmountAfterRebase, lender1BalanceAfterRebase); + assertEq(supplyAmountAfterRebase, lender1BalanceAfterRebase, "amount after rebase"); uint256 currentSupplyFactor = ionPool.supplyFactor(); locs.withdrawAmount = bound(locs.withdrawAmount, 0, supplyAmountAfterRebase); @@ -196,7 +198,7 @@ abstract contract IonPool_LenderFuzzTestBase is IonPoolSharedSetup, IIonPoolEven uint256 underlyingBeforeWithdraw = underlying.balanceOf(lender2); uint256 rewardAssetBalanceBeforeWithdraw = ionPool.balanceOf(lender1); - locs.currentTotalDebt = ionPool.debt(); + locs.currentTotalDebt = lens.debt(iIonPool); (locs.supplyFactorIncrease,,, locs.newDebtIncrease,) = ionPool.calculateRewardAndDebtDistribution(); vm.expectEmit(true, true, true, true); @@ -217,13 +219,17 @@ abstract contract IonPool_LenderFuzzTestBase is IonPoolSharedSetup, IIonPoolEven uint256 underlyingWithdrawn = underlyingAfterWithdraw - underlyingBeforeWithdraw; uint256 rewardAssetBurned = rewardAssetBalanceBeforeWithdraw - rewardAssetBalanceAfterWithdraw; - assertEq(ionPool.weth(), supplyAmountAfterRebase - locs.withdrawAmount); - assertEq(underlyingAfterWithdraw, underlyingBeforeWithdraw + locs.withdrawAmount); + assertEq(lens.liquidity(iIonPool), supplyAmountAfterRebase - locs.withdrawAmount, "weth"); + assertEq(underlyingAfterWithdraw, underlyingBeforeWithdraw + locs.withdrawAmount, "underlying"); // Most important invariant - assertGe(rewardAssetBurned, underlyingWithdrawn); + assertGe(rewardAssetBurned, underlyingWithdrawn, "burned greater than withdrawn"); uint256 roundingError = currentSupplyFactor / RAY; - assertLt(ionPool.balanceOf(lender1), lender1BalanceAfterRebase - locs.withdrawAmount + roundingError); + assertLt( + ionPool.balanceOf(lender1), + lender1BalanceAfterRebase - locs.withdrawAmount + roundingError, + "underlying claim" + ); } } @@ -251,13 +257,13 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv function testFuzz_DepositCollateral(uint256 depositAmount) public { vm.assume(depositAmount < type(uint128).max); - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { ERC20PresetMinterPauser collateral = ERC20PresetMinterPauser(address(collaterals[i])); collateral.mint(borrower1, depositAmount); vm.prank(borrower1); gemJoins[i].join(borrower1, depositAmount); - uint256 gemBeforeDeposit = ionPool.gem(i, borrower1); + uint256 gemBeforeDeposit = lens.gem(iIonPool, i, borrower1); uint256 vaultCollateralBeforeDeposit = ionPool.collateral(i, borrower1); assertEq(gemBeforeDeposit, depositAmount); @@ -268,7 +274,7 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv vm.prank(borrower1); ionPool.depositCollateral(i, borrower1, borrower1, depositAmount, new bytes32[](0)); - assertEq(ionPool.gem(i, borrower1), gemBeforeDeposit - depositAmount); + assertEq(lens.gem(iIonPool, i, borrower1), gemBeforeDeposit - depositAmount); assertEq(ionPool.collateral(i, borrower1), vaultCollateralBeforeDeposit + depositAmount); } } @@ -276,13 +282,13 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv function testFuzz_DepositCollateralToDifferentAddress(uint256 depositAmount) public { vm.assume(depositAmount < type(uint128).max); - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { ERC20PresetMinterPauser collateral = ERC20PresetMinterPauser(address(collaterals[i])); collateral.mint(borrower1, depositAmount); vm.prank(borrower1); gemJoins[i].join(borrower1, depositAmount); - uint256 gem1BeforeDeposit = ionPool.gem(i, borrower1); + uint256 gem1BeforeDeposit = lens.gem(iIonPool, i, borrower1); uint256 vaultBeforeDeposit = ionPool.collateral(i, borrower2); assertEq(gem1BeforeDeposit, depositAmount); @@ -299,7 +305,7 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv proof: new bytes32[](0) }); - assertEq(ionPool.gem(i, borrower1), gem1BeforeDeposit - depositAmount); + assertEq(lens.gem(iIonPool, i, borrower1), gem1BeforeDeposit - depositAmount); assertEq(ionPool.collateral(i, borrower2), vaultBeforeDeposit + depositAmount); } } @@ -307,13 +313,13 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv function testFuzz_RevertWhen_DepositCollateralFromDifferentAddressWithoutConsent(uint256 depositAmount) public { vm.assume(depositAmount < type(uint128).max && depositAmount > 0); - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { ERC20PresetMinterPauser collateral = ERC20PresetMinterPauser(address(collaterals[i])); collateral.mint(borrower1, depositAmount); vm.prank(borrower1); gemJoins[i].join(borrower1, depositAmount); - uint256 gem1BeforeDeposit = ionPool.gem(i, borrower1); + uint256 gem1BeforeDeposit = lens.gem(iIonPool, i, borrower1); uint256 vaultBeforeDeposit = ionPool.collateral(i, borrower2); assertEq(gem1BeforeDeposit, depositAmount); @@ -336,13 +342,13 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv function testFuzz_DepositCollateralFromDifferentAddressWithConsent(uint256 depositAmount) public { vm.assume(depositAmount < type(uint128).max); - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { ERC20PresetMinterPauser collateral = ERC20PresetMinterPauser(address(collaterals[i])); collateral.mint(borrower1, depositAmount); vm.prank(borrower1); gemJoins[i].join(borrower1, depositAmount); - uint256 gem1BeforeDeposit = ionPool.gem(i, borrower1); + uint256 gem1BeforeDeposit = lens.gem(iIonPool, i, borrower1); uint256 vaultBeforeDeposit = ionPool.collateral(i, borrower2); assertEq(gem1BeforeDeposit, depositAmount); @@ -362,7 +368,7 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv proof: new bytes32[](0) }); - assertEq(ionPool.gem(i, borrower1), gem1BeforeDeposit - depositAmount); + assertEq(lens.gem(iIonPool, i, borrower1), gem1BeforeDeposit - depositAmount); assertEq(ionPool.collateral(i, borrower2), vaultBeforeDeposit + depositAmount); } } @@ -370,13 +376,13 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv function testFuzz_WithdrawCollateral(uint256 depositAmount, uint256 withdrawAmount) public { vm.assume(depositAmount < type(uint128).max); - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { ERC20PresetMinterPauser collateral = ERC20PresetMinterPauser(address(collaterals[i])); collateral.mint(borrower1, depositAmount); vm.prank(borrower1); gemJoins[i].join(borrower1, depositAmount); - uint256 gemBeforeDeposit = ionPool.gem(i, borrower1); + uint256 gemBeforeDeposit = lens.gem(iIonPool, i, borrower1); uint256 vaultCollateralBeforeDeposit = ionPool.collateral(i, borrower1); assertEq(gemBeforeDeposit, depositAmount); @@ -385,7 +391,7 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv vm.prank(borrower1); ionPool.depositCollateral(i, borrower1, borrower1, depositAmount, new bytes32[](0)); - assertEq(ionPool.gem(i, borrower1), gemBeforeDeposit - depositAmount); + assertEq(lens.gem(iIonPool, i, borrower1), gemBeforeDeposit - depositAmount); assertEq(ionPool.collateral(i, borrower1), vaultCollateralBeforeDeposit + depositAmount); withdrawAmount = bound(withdrawAmount, 0, depositAmount); @@ -395,7 +401,7 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv vm.prank(borrower1); ionPool.withdrawCollateral(i, borrower1, borrower1, withdrawAmount); - assertEq(ionPool.gem(i, borrower1), gemBeforeDeposit - depositAmount + withdrawAmount); + assertEq(lens.gem(iIonPool, i, borrower1), gemBeforeDeposit - depositAmount + withdrawAmount); assertEq(ionPool.collateral(i, borrower1), vaultCollateralBeforeDeposit + depositAmount - withdrawAmount); } } @@ -403,14 +409,14 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv function testFuzz_WithdrawCollateralToDifferentAddress(uint256 depositAmount, uint256 withdrawAmount) public { vm.assume(depositAmount < type(uint128).max); - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { ERC20PresetMinterPauser collateral = ERC20PresetMinterPauser(address(collaterals[i])); collateral.mint(borrower1, depositAmount); vm.prank(borrower1); gemJoins[i].join(borrower1, depositAmount); - uint256 gemBeforeDeposit = ionPool.gem(i, borrower1); + uint256 gemBeforeDeposit = lens.gem(iIonPool, i, borrower1); uint256 vaultBeforeDeposit = ionPool.collateral(i, borrower1); assertEq(gemBeforeDeposit, depositAmount); @@ -419,7 +425,7 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv vm.prank(borrower1); ionPool.depositCollateral(i, borrower1, borrower1, depositAmount, new bytes32[](0)); - assertEq(ionPool.gem(i, borrower1), gemBeforeDeposit - depositAmount); + assertEq(lens.gem(iIonPool, i, borrower1), gemBeforeDeposit - depositAmount); assertEq(ionPool.collateral(i, borrower1), vaultBeforeDeposit + depositAmount); withdrawAmount = bound(withdrawAmount, 0, depositAmount); @@ -429,9 +435,9 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv vm.prank(borrower1); ionPool.withdrawCollateral({ ilkIndex: i, user: borrower1, recipient: borrower2, amount: withdrawAmount }); - assertEq(ionPool.gem(i, borrower1), gemBeforeDeposit - depositAmount); + assertEq(lens.gem(iIonPool, i, borrower1), gemBeforeDeposit - depositAmount); assertEq(ionPool.collateral(i, borrower1), vaultBeforeDeposit + depositAmount - withdrawAmount); - assertEq(ionPool.gem(i, borrower2), withdrawAmount); + assertEq(lens.gem(iIonPool, i, borrower2), withdrawAmount); } } @@ -443,14 +449,14 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv { vm.assume(depositAmount < type(uint128).max && depositAmount > 0); - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { ERC20PresetMinterPauser collateral = ERC20PresetMinterPauser(address(collaterals[i])); collateral.mint(borrower1, depositAmount); vm.prank(borrower1); gemJoins[i].join(borrower1, depositAmount); - uint256 gemBeforeDeposit = ionPool.gem(i, borrower1); + uint256 gemBeforeDeposit = lens.gem(iIonPool, i, borrower1); uint256 vaultBeforeDeposit = ionPool.collateral(i, borrower1); assertEq(gemBeforeDeposit, depositAmount); @@ -459,7 +465,7 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv vm.prank(borrower1); ionPool.depositCollateral(i, borrower1, borrower1, depositAmount, new bytes32[](0)); - assertEq(ionPool.gem(i, borrower1), gemBeforeDeposit - depositAmount); + assertEq(lens.gem(iIonPool, i, borrower1), gemBeforeDeposit - depositAmount); assertEq(ionPool.collateral(i, borrower1), vaultBeforeDeposit + depositAmount); withdrawAmount = bound(withdrawAmount, 1, depositAmount); @@ -480,14 +486,14 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv { vm.assume(depositAmount < type(uint128).max); - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { ERC20PresetMinterPauser collateral = ERC20PresetMinterPauser(address(collaterals[i])); collateral.mint(borrower1, depositAmount); vm.prank(borrower1); gemJoins[i].join(borrower1, depositAmount); - uint256 gemBeforeDeposit = ionPool.gem(i, borrower1); + uint256 gemBeforeDeposit = lens.gem(iIonPool, i, borrower1); uint256 vaultBeforeDeposit = ionPool.collateral(i, borrower1); assertEq(gemBeforeDeposit, depositAmount); @@ -496,7 +502,7 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv vm.prank(borrower1); ionPool.depositCollateral(i, borrower1, borrower1, depositAmount, new bytes32[](0)); - assertEq(ionPool.gem(i, borrower1), gemBeforeDeposit - depositAmount); + assertEq(lens.gem(iIonPool, i, borrower1), gemBeforeDeposit - depositAmount); assertEq(ionPool.collateral(i, borrower1), vaultBeforeDeposit + depositAmount); withdrawAmount = bound(withdrawAmount, 0, depositAmount); @@ -509,9 +515,9 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv vm.prank(borrower2); ionPool.withdrawCollateral({ ilkIndex: i, user: borrower1, recipient: borrower2, amount: withdrawAmount }); - assertEq(ionPool.gem(i, borrower1), gemBeforeDeposit - depositAmount); + assertEq(lens.gem(iIonPool, i, borrower1), gemBeforeDeposit - depositAmount); assertEq(ionPool.collateral(i, borrower1), vaultBeforeDeposit + depositAmount - withdrawAmount); - assertEq(ionPool.gem(i, borrower2), withdrawAmount); + assertEq(lens.gem(iIonPool, i, borrower2), withdrawAmount); } } @@ -522,7 +528,7 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv public { _changeRateIfNeeded(); - require(COLLATERAL_COUNT == ionPool.ilkCount(), "IonPoolFuzz: Invalid Config"); + require(COLLATERAL_COUNT == lens.ilkCount(iIonPool), "IonPoolFuzz: Invalid Config"); uint256 borrowedSoFar; for (uint8 i = 0; i < 1; i++) { @@ -530,8 +536,11 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv // This 1:1 ratio is OK since ltv is set at 100% uint256 collateralDepositAmount = bound(collateralDepositAmounts[i], 0, debtCeilings[i].scaleDownToWad(45)); - normalizedBorrowAmount = - bound(normalizedBorrowAmount, 0, collateralDepositAmount * ionPool.spot(i).getSpot() / rate); + normalizedBorrowAmount = bound( + normalizedBorrowAmount, + 0, + collateralDepositAmount * ISpotOracle(lens.spot(iIonPool, i)).getSpot() / rate + ); ERC20PresetMinterPauser collateral = ERC20PresetMinterPauser(address(collaterals[i])); collateral.mint(borrower1, collateralDepositAmount); @@ -541,7 +550,7 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv ionPool.depositCollateral(i, borrower1, borrower1, collateralDepositAmount, new bytes32[](0)); vm.stopPrank(); - uint256 liquidityBefore = ionPool.weth(); + uint256 liquidityBefore = lens.liquidity(iIonPool); uint256 liquidityRemoved = normalizedBorrowAmount.rayMulDown(rate); assertEq(ionPool.collateral(i, borrower1), collateralDepositAmount); @@ -549,7 +558,12 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv vm.expectEmit(true, true, true, true); emit Borrow( - i, borrower1, borrower1, normalizedBorrowAmount, rate, ionPool.debt() + normalizedBorrowAmount * rate + i, + borrower1, + borrower1, + normalizedBorrowAmount, + rate, + lens.debt(iIonPool) + normalizedBorrowAmount * rate ); vm.prank(borrower1); ionPool.borrow(i, borrower1, borrower1, normalizedBorrowAmount, new bytes32[](0)); @@ -557,8 +571,8 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv borrowedSoFar += liquidityRemoved; assertEq(ionPool.normalizedDebt(i, borrower1), normalizedBorrowAmount); - assertEq(ionPool.totalNormalizedDebt(i), normalizedBorrowAmount); - assertEq(ionPool.weth(), liquidityBefore - liquidityRemoved); + assertEq(lens.totalNormalizedDebt(iIonPool, i), normalizedBorrowAmount); + assertEq(lens.liquidity(iIonPool), liquidityBefore - liquidityRemoved); assertEq(underlying.balanceOf(borrower1), borrowedSoFar); } } @@ -570,16 +584,19 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv public { _changeRateIfNeeded(); - require(COLLATERAL_COUNT == ionPool.ilkCount(), "IonPoolFuzz: Invalid Config"); + require(COLLATERAL_COUNT == lens.ilkCount(iIonPool), "IonPoolFuzz: Invalid Config"); uint256 borrowedSoFar; - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { uint256 rate = ionPool.rate(i); // This 1:1 ratio is OK since ltv is set at 100% uint256 collateralDepositAmount = bound(collateralDepositAmounts[i], 0, debtCeilings[i].scaleDownToWad(45)); - normalizedBorrowAmount = - bound(normalizedBorrowAmount, 0, collateralDepositAmount * ionPool.spot(i).getSpot() / rate); + normalizedBorrowAmount = bound( + normalizedBorrowAmount, + 0, + collateralDepositAmount * ISpotOracle(lens.spot(iIonPool, i)).getSpot() / rate + ); ERC20PresetMinterPauser collateral = ERC20PresetMinterPauser(address(collaterals[i])); collateral.mint(borrower1, collateralDepositAmount); @@ -589,7 +606,7 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv ionPool.depositCollateral(i, borrower1, borrower1, collateralDepositAmount, new bytes32[](0)); vm.stopPrank(); - uint256 liquidityBefore = ionPool.weth(); + uint256 liquidityBefore = lens.liquidity(iIonPool); uint256 liquidityRemoved = normalizedBorrowAmount.rayMulDown(rate); assertEq(ionPool.collateral(i, borrower1), collateralDepositAmount); @@ -597,7 +614,12 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv vm.expectEmit(true, true, true, true); emit Borrow( - i, borrower1, borrower2, normalizedBorrowAmount, rate, ionPool.debt() + normalizedBorrowAmount * rate + i, + borrower1, + borrower2, + normalizedBorrowAmount, + rate, + lens.debt(iIonPool) + normalizedBorrowAmount * rate ); vm.prank(borrower1); ionPool.borrow({ @@ -611,8 +633,8 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv borrowedSoFar += liquidityRemoved; assertEq(ionPool.normalizedDebt(i, borrower1), normalizedBorrowAmount); - assertEq(ionPool.totalNormalizedDebt(i), normalizedBorrowAmount); - assertEq(ionPool.weth(), liquidityBefore - liquidityRemoved); + assertEq(lens.totalNormalizedDebt(iIonPool, i), normalizedBorrowAmount); + assertEq(lens.liquidity(iIonPool), liquidityBefore - liquidityRemoved); assertEq(underlying.balanceOf(borrower2), borrowedSoFar); } } @@ -623,9 +645,9 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv ) public { - require(COLLATERAL_COUNT == ionPool.ilkCount(), "IonPoolFuzz: Invalid Config"); + require(COLLATERAL_COUNT == lens.ilkCount(iIonPool), "IonPoolFuzz: Invalid Config"); - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { // This 1:1 ratio is OK since ltv is set at 100% uint256 collateralDepositAmount = bound(collateralDepositAmounts[i], 1, debtCeilings[i].scaleDownToWad(45)); normalizedBorrowAmount = bound(normalizedBorrowAmount, 1, collateralDepositAmount); @@ -662,16 +684,19 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv public { _changeRateIfNeeded(); - require(COLLATERAL_COUNT == ionPool.ilkCount(), "IonPoolFuzz: Invalid Config"); + require(COLLATERAL_COUNT == lens.ilkCount(iIonPool), "IonPoolFuzz: Invalid Config"); uint256 borrowedSoFar; - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { uint256 rate = ionPool.rate(i); // This 1:1 ratio is OK since ltv is set at 100% uint256 collateralDepositAmount = bound(collateralDepositAmounts[i], 0, debtCeilings[i].scaleDownToWad(45)); - normalizedBorrowAmount = - bound(normalizedBorrowAmount, 0, collateralDepositAmount * ionPool.spot(i).getSpot() / rate); + normalizedBorrowAmount = bound( + normalizedBorrowAmount, + 0, + collateralDepositAmount * ISpotOracle(lens.spot(iIonPool, i)).getSpot() / rate + ); ERC20PresetMinterPauser collateral = ERC20PresetMinterPauser(address(collaterals[i])); collateral.mint(borrower1, collateralDepositAmount); @@ -681,7 +706,7 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv ionPool.depositCollateral(i, borrower1, borrower1, collateralDepositAmount, new bytes32[](0)); vm.stopPrank(); - uint256 liquidityBefore = ionPool.weth(); + uint256 liquidityBefore = lens.liquidity(iIonPool); uint256 liquidityRemoved = normalizedBorrowAmount.rayMulDown(rate); assertEq(ionPool.collateral(i, borrower1), collateralDepositAmount); @@ -692,7 +717,12 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv vm.expectEmit(true, true, true, true); emit Borrow( - i, borrower1, borrower2, normalizedBorrowAmount, rate, ionPool.debt() + normalizedBorrowAmount * rate + i, + borrower1, + borrower2, + normalizedBorrowAmount, + rate, + lens.debt(iIonPool) + normalizedBorrowAmount * rate ); vm.prank(borrower2); ionPool.borrow({ @@ -706,8 +736,8 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv borrowedSoFar += liquidityRemoved; assertEq(ionPool.normalizedDebt(i, borrower1), normalizedBorrowAmount); - assertEq(ionPool.totalNormalizedDebt(i), normalizedBorrowAmount); - assertEq(ionPool.weth(), liquidityBefore - liquidityRemoved); + assertEq(lens.totalNormalizedDebt(iIonPool, i), normalizedBorrowAmount); + assertEq(lens.liquidity(iIonPool), liquidityBefore - liquidityRemoved); assertEq(underlying.balanceOf(borrower2), borrowedSoFar); } } @@ -718,9 +748,9 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv ) public { - require(COLLATERAL_COUNT == ionPool.ilkCount(), "IonPoolFuzz: Invalid Config"); + require(COLLATERAL_COUNT == lens.ilkCount(iIonPool), "IonPoolFuzz: Invalid Config"); - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { // This 1:1 ratio is OK since ltv is set at 100% uint256 collateralDepositAmount = bound(collateralDepositAmounts[i], 0, debtCeilings[i].scaleDownToWad(45) - 1); @@ -736,7 +766,7 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv vm.stopPrank(); uint256 rate = ionPool.rate(i); - uint256 spot = ionPool.spot(i).getSpot(); + uint256 spot = ISpotOracle(lens.spot(iIonPool, i)).getSpot(); vm.expectRevert( abi.encodeWithSelector( IonPool.UnsafePositionChange.selector, rate * normalizedBorrowAmount, collateralDepositAmount, spot @@ -765,7 +795,7 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv underlying.approve(address(ionPool), type(uint256).max); RepayLocs memory locs; - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { collateralDepositAmount = bound(collateralDepositAmount, 0, debtCeilings[i].scaleDownToWad(45)); normalizedBorrowAmount = bound(normalizedBorrowAmount, 0, collateralDepositAmount); locs.normalizedRepayAmount = bound(normalizedRepayAmount, 0, normalizedBorrowAmount); @@ -779,7 +809,7 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv vm.stopPrank(); uint256 rate = ionPool.rate(i); - uint256 liquidityBefore = ionPool.weth(); + uint256 liquidityBefore = lens.liquidity(iIonPool); assertEq(ionPool.collateral(i, borrower1), collateralDepositAmount); assertEq( @@ -793,8 +823,8 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv locs.borrowedSoFar += liquidityRemoved; assertEq(ionPool.normalizedDebt(i, borrower1), normalizedBorrowAmount); - assertEq(ionPool.totalNormalizedDebt(i), normalizedBorrowAmount); - assertEq(ionPool.weth(), liquidityBefore - liquidityRemoved); + assertEq(lens.totalNormalizedDebt(iIonPool, i), normalizedBorrowAmount); + assertEq(lens.liquidity(iIonPool), liquidityBefore - liquidityRemoved); assertEq( underlying.balanceOf(borrower1), locs.borrowedSoFar + locs.fundsCollectedForRepayment - locs.repaidSoFar ); @@ -824,7 +854,7 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv borrower1, locs.normalizedRepayAmount, rate + newRateIncrease, - ionPool.debtUnaccrued() + totalDebtIncrease - totalChangeInDebt + lens.debtUnaccrued(iIonPool) + totalDebtIncrease - totalChangeInDebt ); vm.prank(borrower1); ionPool.repay(i, borrower1, borrower1, locs.normalizedRepayAmount); @@ -835,8 +865,8 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv locs.repaidSoFar += trueRepayAmount; assertEq(ionPool.normalizedDebt(i, borrower1), normalizedBorrowAmount - locs.normalizedRepayAmount); - assertEq(ionPool.totalNormalizedDebt(i), normalizedBorrowAmount - locs.normalizedRepayAmount); - assertEq(ionPool.weth(), liquidityBefore - liquidityRemoved + trueRepayAmount); + assertEq(lens.totalNormalizedDebt(iIonPool, i), normalizedBorrowAmount - locs.normalizedRepayAmount); + assertEq(lens.liquidity(iIonPool), liquidityBefore - liquidityRemoved + trueRepayAmount); assertEq( underlying.balanceOf(borrower1), locs.borrowedSoFar + locs.fundsCollectedForRepayment - locs.repaidSoFar ); @@ -856,7 +886,7 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv underlying.approve(address(ionPool), type(uint256).max); RepayLocs memory locs; - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { collateralDepositAmount = bound(collateralDepositAmount, 0, debtCeilings[i].scaleDownToWad(45)); normalizedBorrowAmount = bound(normalizedBorrowAmount, 0, collateralDepositAmount); locs.normalizedRepayAmount = bound(normalizedRepayAmount, 0, normalizedBorrowAmount); @@ -870,7 +900,7 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv vm.stopPrank(); uint256 rate = ionPool.rate(i); - uint256 liquidityBefore = ionPool.weth(); + uint256 liquidityBefore = lens.liquidity(iIonPool); assertEq(ionPool.collateral(i, borrower1), collateralDepositAmount); assertEq(underlying.balanceOf(borrower1), locs.borrowedSoFar); @@ -882,8 +912,8 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv locs.borrowedSoFar += liquidityRemoved; assertEq(ionPool.normalizedDebt(i, borrower1), normalizedBorrowAmount); - assertEq(ionPool.totalNormalizedDebt(i), normalizedBorrowAmount); - assertEq(ionPool.weth(), liquidityBefore - liquidityRemoved); + assertEq(lens.totalNormalizedDebt(iIonPool, i), normalizedBorrowAmount); + assertEq(lens.liquidity(iIonPool), liquidityBefore - liquidityRemoved); assertEq(underlying.balanceOf(borrower1), locs.borrowedSoFar); _warpTimeIfNeeded(); @@ -908,7 +938,7 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv borrower2, locs.normalizedRepayAmount, rate + newRateIncrease, - ionPool.debtUnaccrued() + totalDebtIncrease - totalChangeInDebt + lens.debtUnaccrued(iIonPool) + totalDebtIncrease - totalChangeInDebt ); vm.prank(borrower2); ionPool.repay({ @@ -922,8 +952,8 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv locs.repaidSoFar += trueRepayAmount; assertEq(ionPool.normalizedDebt(i, borrower1), normalizedBorrowAmount - locs.normalizedRepayAmount); - assertEq(ionPool.totalNormalizedDebt(i), normalizedBorrowAmount - locs.normalizedRepayAmount); - assertEq(ionPool.weth(), liquidityBefore - liquidityRemoved + trueRepayAmount); + assertEq(lens.totalNormalizedDebt(iIonPool, i), normalizedBorrowAmount - locs.normalizedRepayAmount); + assertEq(lens.liquidity(iIonPool), liquidityBefore - liquidityRemoved + trueRepayAmount); assertEq(underlying.balanceOf(borrower1), locs.borrowedSoFar); assertEq(underlying.balanceOf(borrower2), 0); } @@ -942,7 +972,7 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv underlying.approve(address(ionPool), type(uint256).max); uint256 borrowedSoFar; - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { collateralDepositAmount = bound(collateralDepositAmount, 1, debtCeilings[i].scaleDownToWad(45)); normalizedBorrowAmount = bound(normalizedBorrowAmount, 1, collateralDepositAmount); normalizedRepayAmount = bound(normalizedRepayAmount, 1, normalizedBorrowAmount); @@ -956,7 +986,7 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv vm.stopPrank(); uint256 rate = ionPool.rate(i); - uint256 liquidityBefore = ionPool.weth(); + uint256 liquidityBefore = lens.liquidity(iIonPool); uint256 trueBorrowAmount = normalizedBorrowAmount.rayMulDown(rate); @@ -971,8 +1001,8 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv uint256 liquidityRemoved = normalizedBorrowAmount.rayMulDown(rate); assertEq(ionPool.normalizedDebt(i, borrower1), normalizedBorrowAmount); - assertEq(ionPool.totalNormalizedDebt(i), normalizedBorrowAmount); - assertEq(ionPool.weth(), liquidityBefore - liquidityRemoved); + assertEq(lens.totalNormalizedDebt(iIonPool, i), normalizedBorrowAmount); + assertEq(lens.liquidity(iIonPool), liquidityBefore - liquidityRemoved); assertEq(underlying.balanceOf(borrower1), borrowedSoFar); vm.expectRevert(abi.encodeWithSelector(IonPool.TakingWethWithoutConsent.selector, borrower2, borrower1)); @@ -999,7 +1029,7 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv underlying.approve(address(ionPool), type(uint256).max); RepayLocs memory locs; - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { collateralDepositAmount = bound(collateralDepositAmount, 0, debtCeilings[i].scaleDownToWad(45)); normalizedBorrowAmount = bound(normalizedBorrowAmount, 0, collateralDepositAmount); locs.normalizedRepayAmount = bound(normalizedRepayAmount, 0, normalizedBorrowAmount); @@ -1013,7 +1043,7 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv vm.stopPrank(); uint256 rate = ionPool.rate(i); - uint256 liquidityBefore = ionPool.weth(); + uint256 liquidityBefore = lens.liquidity(iIonPool); assertEq(ionPool.collateral(i, borrower1), collateralDepositAmount); assertEq(underlying.balanceOf(borrower1), locs.borrowedSoFar); @@ -1025,8 +1055,8 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv locs.borrowedSoFar += liquidityRemoved; assertEq(ionPool.normalizedDebt(i, borrower1), normalizedBorrowAmount); - assertEq(ionPool.totalNormalizedDebt(i), normalizedBorrowAmount); - assertEq(ionPool.weth(), liquidityBefore - liquidityRemoved); + assertEq(lens.totalNormalizedDebt(iIonPool, i), normalizedBorrowAmount); + assertEq(lens.liquidity(iIonPool), liquidityBefore - liquidityRemoved); assertEq(underlying.balanceOf(borrower1), locs.borrowedSoFar); _warpTimeIfNeeded(); @@ -1054,7 +1084,7 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv borrower2, locs.normalizedRepayAmount, rate + newRateIncrease, - ionPool.debtUnaccrued() + totalDebtIncrease - totalChangeInDebt + lens.debtUnaccrued(iIonPool) + totalDebtIncrease - totalChangeInDebt ); vm.prank(borrower1); ionPool.repay({ @@ -1068,8 +1098,8 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv locs.repaidSoFar += trueRepayAmount; assertEq(ionPool.normalizedDebt(i, borrower1), normalizedBorrowAmount - locs.normalizedRepayAmount); - assertEq(ionPool.totalNormalizedDebt(i), normalizedBorrowAmount - locs.normalizedRepayAmount); - assertEq(ionPool.weth(), liquidityBefore - liquidityRemoved + trueRepayAmount); + assertEq(lens.totalNormalizedDebt(iIonPool, i), normalizedBorrowAmount - locs.normalizedRepayAmount); + assertEq(lens.liquidity(iIonPool), liquidityBefore - liquidityRemoved + trueRepayAmount); assertEq(underlying.balanceOf(borrower1), locs.borrowedSoFar); assertEq(underlying.balanceOf(borrower2), 0); } @@ -1086,15 +1116,15 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv vm.prank(borrower1); gemJoins[i].join(borrower1, collateralDepositAmount); - uint256 initialGemBalance = ionPool.gem(i, borrower1); + uint256 initialGemBalance = lens.gem(iIonPool, i, borrower1); vm.expectEmit(true, true, true, true); emit TransferGem(i, borrower1, borrower2, transferAmount); vm.prank(borrower1); ionPool.transferGem(i, borrower1, borrower2, transferAmount); - assertEq(ionPool.gem(i, borrower1), initialGemBalance - transferAmount); - assertEq(ionPool.gem(i, borrower2), transferAmount); + assertEq(lens.gem(iIonPool, i, borrower1), initialGemBalance - transferAmount); + assertEq(lens.gem(iIonPool, i, borrower2), transferAmount); } } @@ -1138,15 +1168,15 @@ abstract contract IonPool_BorrowerFuzzTestBase is IonPoolSharedSetup, IIonPoolEv ionPool.addOperator(borrower2); vm.stopPrank(); - uint256 initialGemBalance = ionPool.gem(i, borrower1); + uint256 initialGemBalance = lens.gem(iIonPool, i, borrower1); vm.expectEmit(true, true, true, true); emit TransferGem(i, borrower1, borrower2, transferAmount); vm.prank(borrower2); ionPool.transferGem(i, borrower1, borrower2, transferAmount); - assertEq(ionPool.gem(i, borrower1), initialGemBalance - transferAmount); - assertEq(ionPool.gem(i, borrower2), transferAmount); + assertEq(lens.gem(iIonPool, i, borrower1), initialGemBalance - transferAmount); + assertEq(lens.gem(iIonPool, i, borrower2), transferAmount); } } } @@ -1227,7 +1257,7 @@ contract IonPool_BorrowerFuzzTest is IonPool_BorrowerFuzzTestBase { ionPool.supply(lender2, INITIAL_LENDER_UNDERLYING_BALANCE, new bytes32[](0)); vm.stopPrank(); - for (uint256 i = 0; i < ionPool.ilkCount(); i++) { + for (uint256 i = 0; i < lens.ilkCount(iIonPool); i++) { vm.prank(borrower1); collaterals[i].approve(address(gemJoins[i]), type(uint256).max); } @@ -1236,11 +1266,11 @@ contract IonPool_BorrowerFuzzTest is IonPool_BorrowerFuzzTestBase { function test_SetUp() public override { super.test_SetUp(); - assertEq(ionPool.weth(), INITIAL_LENDER_UNDERLYING_BALANCE); + assertEq(lens.liquidity(iIonPool), INITIAL_LENDER_UNDERLYING_BALANCE); assertEq(underlying.balanceOf(address(ionPool)), INITIAL_LENDER_UNDERLYING_BALANCE); - assertEq(ionPool.balanceOf(lender2), INITIAL_LENDER_UNDERLYING_BALANCE); + assertEq(ionPool.normalizedBalanceOf(lender2), INITIAL_LENDER_UNDERLYING_BALANCE); - for (uint256 i = 0; i < ionPool.ilkCount(); i++) { + for (uint256 i = 0; i < lens.ilkCount(iIonPool); i++) { assertEq(collaterals[i].allowance(borrower1, address(gemJoins[i])), type(uint256).max); } } @@ -1254,7 +1284,7 @@ contract IonPool_BorrowerFuzzTest is IonPool_BorrowerFuzzTestBase { { changeRate = true; - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { // Disable debt ceiling for this test ionPool.updateIlkDebtCeiling(i, type(uint256).max); @@ -1273,7 +1303,7 @@ contract IonPool_BorrowerFuzzTest is IonPool_BorrowerFuzzTestBase { { changeRate = true; - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { // Disable debt ceiling for this test ionPool.updateIlkDebtCeiling(i, type(uint256).max); @@ -1292,7 +1322,7 @@ contract IonPool_BorrowerFuzzTest is IonPool_BorrowerFuzzTestBase { { changeRate = true; - for (uint8 i = 0; i < ionPool.ilkCount(); i++) { + for (uint8 i = 0; i < lens.ilkCount(iIonPool); i++) { // Disable debt ceiling for this test ionPool.updateIlkDebtCeiling(i, type(uint256).max); diff --git a/test/unit/fuzz/Liquidation.t.sol b/test/unit/fuzz/Liquidation.t.sol index ae4ae907..0ccb52c2 100644 --- a/test/unit/fuzz/Liquidation.t.sol +++ b/test/unit/fuzz/Liquidation.t.sol @@ -126,7 +126,7 @@ contract LiquidationFuzzFixedConfigs is LiquidationSharedSetup { // ffi to see when this branch gets hit // vm.writeLine("fuzz_out.txt", "DUST"); assert(ionPool.normalizedDebt(ILK_INDEX, borrower1) == 0); - assert(ionPool.unbackedDebt(address(liquidation)) == 0); + assert(lens.unbackedDebt(iIonPool, address(liquidation)) == 0); } else if (results.category == 2) { // vm.writeLine("fuzz_out.txt", "PARTIAL"); uint256 actualCollateral = ionPool.collateral(ILK_INDEX, borrower1); @@ -141,7 +141,7 @@ contract LiquidationFuzzFixedConfigs is LiquidationSharedSetup { deploymentArgs.liquidationThreshold ); assert(healthRatio >= deploymentArgs.targetHealth); - assert(ionPool.unbackedDebt(address(liquidation)) == 0); + assert(lens.unbackedDebt(iIonPool, address(liquidation)) == 0); } } } diff --git a/test/unit/fuzz/RewardModule.t.sol b/test/unit/fuzz/RewardModule.t.sol deleted file mode 100644 index f822fc5b..00000000 --- a/test/unit/fuzz/RewardModule.t.sol +++ /dev/null @@ -1,138 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.21; - -import { RewardModule } from "../../../src/reward/RewardModule.sol"; -import { WadRayMath } from "../../../src/libraries/math/WadRayMath.sol"; - -import { RewardModuleSharedSetup } from "../../helpers/RewardModuleSharedSetup.sol"; - -contract RewardModule_FuzzUnitTest is RewardModuleSharedSetup { - using WadRayMath for uint256; - - function testFuzz_MintRewardBasic(uint256 amountOfRewards) external { - vm.assume(amountOfRewards != 0); - // Prevent overflow - vm.assume(amountOfRewards < 2 ** 128); - - underlying.mint(address(this), amountOfRewards); - - underlying.approve(address(rewardModule), amountOfRewards); - vm.expectRevert(abi.encodeWithSelector(RewardModule.InvalidReceiver.selector, address(0))); - rewardModule.mint(address(0), amountOfRewards); - rewardModule.mint(address(this), amountOfRewards); - - assertEq(rewardModule.balanceOf(address(this)), amountOfRewards); - assertEq(underlying.balanceOf(address(this)), 0); - assertEq(underlying.balanceOf(address(rewardModule)), amountOfRewards); - } - - function testFuzz_BurnRewardBasic(uint256 amountOfRewards) external { - vm.assume(amountOfRewards != 0); - // Prevent overflow - vm.assume(amountOfRewards < 2 ** 128); - - // Undo setup - underlying.mint(address(this), amountOfRewards); - - underlying.approve(address(rewardModule), amountOfRewards); - rewardModule.mint(address(this), amountOfRewards); - - assertEq(rewardModule.balanceOf(address(this)), amountOfRewards); - assertEq(underlying.balanceOf(address(this)), 0); - - vm.expectRevert(abi.encodeWithSelector(RewardModule.InvalidSender.selector, address(0))); - rewardModule.burn(address(0), address(this), amountOfRewards); - rewardModule.burn(address(this), address(this), amountOfRewards); - - assertEq(rewardModule.balanceOf(address(this)), 0); - } - - function testFuzz_MintRewardWithSupplyFactorChange(uint256 amountOfRewards, uint256 supplyFactorNew) external { - vm.assume(amountOfRewards != 0); - // Prevent overflow - vm.assume(amountOfRewards < 2 ** 128); - uint256 supplyFactorOld = rewardModule.supplyFactor(); - // supplyFactor greater than 10,000 is highly unlikely - supplyFactorNew = bound(supplyFactorNew, supplyFactorOld, 5000e27); - vm.assume(amountOfRewards.rayDivDown(supplyFactorNew) != 0); - - underlying.mint(address(this), amountOfRewards); - - underlying.approve(address(rewardModule), type(uint256).max); - rewardModule.mint(address(this), amountOfRewards); - - uint256 expectedNormalizedMint1 = amountOfRewards.rayDivDown(supplyFactorOld); - - assertEq(rewardModule.normalizedBalanceOf(address(this)), expectedNormalizedMint1); - assertEq(rewardModule.balanceOf(address(this)), amountOfRewards); - assertEq(underlying.balanceOf(address(this)), 0); - assertEq(underlying.balanceOf(address(rewardModule)), amountOfRewards); - - uint256 interestCreated = amountOfRewards.wadMulDown(supplyFactorNew - supplyFactorOld); - // Adds amount of underlying to the reward token contract based on how - // much the supply factor was changed - _depositInterestGains(interestCreated); - rewardModule.setSupplyFactor(supplyFactorNew); - - underlying.mint(address(this), amountOfRewards); - rewardModule.mint(address(this), amountOfRewards); - - uint256 expectedNormalizedMint2 = amountOfRewards.rayDivDown(supplyFactorNew); - uint256 totalDeposited = amountOfRewards * 2; - uint256 totalDepositsNormalized = expectedNormalizedMint1 + expectedNormalizedMint2; - uint256 totalValue = totalDepositsNormalized.rayMulDown(supplyFactorNew); - - assertEq(rewardModule.normalizedBalanceOf(address(this)), totalDepositsNormalized); - assertEq(rewardModule.balanceOf(address(this)), totalValue); - assertEq(underlying.balanceOf(address(this)), 0); - assertEq(underlying.balanceOf(address(rewardModule)), totalDeposited + interestCreated); - } - - function testFuzz_BurnRewardWithSupplyFactorChange(uint256 amountOfRewards, uint256 supplyFactorNew) external { - vm.assume(amountOfRewards != 0); - // Prevent overflow - vm.assume(amountOfRewards < 2 ** 128); - uint256 supplyFactorOld = rewardModule.supplyFactor(); - // supplyFactor greater than 5,000 is highly unlikely - supplyFactorNew = bound(supplyFactorNew, supplyFactorOld + 1, 5000e27); - vm.assume(amountOfRewards.rayDivDown(supplyFactorNew) != 0); - - underlying.mint(address(this), amountOfRewards); - - underlying.approve(address(rewardModule), type(uint256).max); - rewardModule.mint(address(this), amountOfRewards); - - uint256 expectedNormalizedMint1 = amountOfRewards.rayDivDown(supplyFactorOld); - - assertEq(rewardModule.normalizedBalanceOf(address(this)), expectedNormalizedMint1); - assertEq(rewardModule.balanceOf(address(this)), amountOfRewards); - assertEq(underlying.balanceOf(address(this)), 0); - assertEq(underlying.balanceOf(address(rewardModule)), amountOfRewards); - - uint256 interestCreated = amountOfRewards.wadMulDown(supplyFactorNew - supplyFactorOld); - // Adds amount of underlying to the reward token contract based on how - // much the supply factor was changed - _depositInterestGains(interestCreated); - rewardModule.setSupplyFactor(supplyFactorNew); - - underlying.mint(address(this), amountOfRewards); - rewardModule.mint(address(this), amountOfRewards); - - uint256 expectedNormalizedMint2 = amountOfRewards.rayDivDown(supplyFactorNew); - uint256 totalDeposited = amountOfRewards * 2; - uint256 totalDepositsNormalized = expectedNormalizedMint1 + expectedNormalizedMint2; - uint256 totalValue = totalDepositsNormalized.rayMulDown(supplyFactorNew); - - assertEq(rewardModule.normalizedBalanceOf(address(this)), totalDepositsNormalized); - assertEq(rewardModule.balanceOf(address(this)), totalValue); - assertEq(underlying.balanceOf(address(this)), 0); - assertEq(underlying.balanceOf(address(rewardModule)), totalDeposited + interestCreated); - - uint256 burnAmount = amountOfRewards; - - rewardModule.burn(address(this), address(this), burnAmount); - - assertEq(underlying.balanceOf(address(this)), burnAmount); - assertEq(underlying.balanceOf(address(rewardModule)), totalDeposited + interestCreated - burnAmount); - } -} diff --git a/test/unit/fuzz/RewardToken.t.sol b/test/unit/fuzz/RewardToken.t.sol new file mode 100644 index 00000000..e8ad4d6b --- /dev/null +++ b/test/unit/fuzz/RewardToken.t.sol @@ -0,0 +1,363 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.21; + +import { RewardToken } from "../../../src/token/RewardToken.sol"; +import { WadRayMath } from "../../../src/libraries/math/WadRayMath.sol"; +import { IERC20Errors } from "../../../src/token/IERC20Errors.sol"; + +import { RewardTokenSharedSetup } from "../../helpers/RewardTokenSharedSetup.sol"; + +import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import { MessageHashUtils } from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; + +contract RewardToken_FuzzUnitTest is RewardTokenSharedSetup { + using WadRayMath for uint256; + + bytes private constant EIP712_REVISION = bytes("1"); + bytes32 private constant EIP712_DOMAIN = + keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); + + function testFuzz_MintRewardBasic(uint256 amountOfRewards) external { + vm.assume(amountOfRewards != 0); + // Prevent overflow + vm.assume(amountOfRewards < 2 ** 128); + + underlying.mint(address(this), amountOfRewards); + + underlying.approve(address(rewardModule), amountOfRewards); + vm.expectRevert(abi.encodeWithSelector(RewardToken.InvalidReceiver.selector, address(0))); + rewardModule.mint(address(0), amountOfRewards); + rewardModule.mint(address(this), amountOfRewards); + + assertEq(rewardModule.normalizedBalanceOf(address(this)), amountOfRewards); + assertEq(underlying.balanceOf(address(this)), 0); + assertEq(underlying.balanceOf(address(rewardModule)), amountOfRewards); + } + + function testFuzz_BurnRewardBasic(uint256 amountOfRewards) external { + vm.assume(amountOfRewards != 0); + // Prevent overflow + vm.assume(amountOfRewards < 2 ** 128); + + // Undo setup + underlying.mint(address(this), amountOfRewards); + + underlying.approve(address(rewardModule), amountOfRewards); + rewardModule.mint(address(this), amountOfRewards); + + assertEq(rewardModule.normalizedBalanceOf(address(this)), amountOfRewards); + assertEq(underlying.balanceOf(address(this)), 0); + + vm.expectRevert(abi.encodeWithSelector(RewardToken.InvalidSender.selector, address(0))); + rewardModule.burn(address(0), address(this), amountOfRewards); + rewardModule.burn(address(this), address(this), amountOfRewards); + + assertEq(rewardModule.normalizedBalanceOf(address(this)), 0); + } + + function testFuzz_MintRewardWithSupplyFactorChange(uint256 amountOfRewards, uint256 supplyFactorNew) external { + vm.assume(amountOfRewards != 0); + // Prevent overflow + vm.assume(amountOfRewards < 2 ** 128); + uint256 supplyFactorOld = rewardModule.supplyFactor(); + // supplyFactor greater than 10,000 is highly unlikely + supplyFactorNew = bound(supplyFactorNew, supplyFactorOld, 5000e27); + vm.assume(amountOfRewards.rayDivDown(supplyFactorNew) != 0); + + underlying.mint(address(this), amountOfRewards); + + underlying.approve(address(rewardModule), type(uint256).max); + rewardModule.mint(address(this), amountOfRewards); + + uint256 expectedNormalizedMint1 = amountOfRewards.rayDivDown(supplyFactorOld); + + assertEq(rewardModule.normalizedBalanceOf(address(this)), expectedNormalizedMint1); + assertEq(rewardModule.balanceOf(address(this)), amountOfRewards); + assertEq(underlying.balanceOf(address(this)), 0); + assertEq(underlying.balanceOf(address(rewardModule)), amountOfRewards); + + uint256 interestCreated = amountOfRewards.wadMulDown(supplyFactorNew - supplyFactorOld); + // Adds amount of underlying to the reward token contract based on how + // much the supply factor was changed + _depositInterestGains(interestCreated); + rewardModule.setSupplyFactor(supplyFactorNew); + + underlying.mint(address(this), amountOfRewards); + rewardModule.mint(address(this), amountOfRewards); + + uint256 expectedNormalizedMint2 = amountOfRewards.rayDivDown(supplyFactorNew); + uint256 totalDeposited = amountOfRewards * 2; + uint256 totalDepositsNormalized = expectedNormalizedMint1 + expectedNormalizedMint2; + uint256 totalValue = totalDepositsNormalized.rayMulDown(supplyFactorNew); + + assertEq(rewardModule.normalizedBalanceOf(address(this)), totalDepositsNormalized); + assertEq(rewardModule.balanceOf(address(this)), totalValue); + assertEq(underlying.balanceOf(address(this)), 0); + assertEq(underlying.balanceOf(address(rewardModule)), totalDeposited + interestCreated); + } + + function testFuzz_BurnRewardWithSupplyFactorChange(uint256 amountOfRewards, uint256 supplyFactorNew) external { + vm.assume(amountOfRewards != 0); + // Prevent overflow + vm.assume(amountOfRewards < 2 ** 128); + uint256 supplyFactorOld = rewardModule.supplyFactor(); + // supplyFactor greater than 5,000 is highly unlikely + supplyFactorNew = bound(supplyFactorNew, supplyFactorOld + 1, 5000e27); + vm.assume(amountOfRewards.rayDivDown(supplyFactorNew) != 0); + + underlying.mint(address(this), amountOfRewards); + + underlying.approve(address(rewardModule), type(uint256).max); + rewardModule.mint(address(this), amountOfRewards); + + uint256 expectedNormalizedMint1 = amountOfRewards.rayDivDown(supplyFactorOld); + + assertEq(rewardModule.normalizedBalanceOf(address(this)), expectedNormalizedMint1); + assertEq(rewardModule.balanceOf(address(this)), amountOfRewards); + assertEq(underlying.balanceOf(address(this)), 0); + assertEq(underlying.balanceOf(address(rewardModule)), amountOfRewards); + + uint256 interestCreated = amountOfRewards.wadMulDown(supplyFactorNew - supplyFactorOld); + // Adds amount of underlying to the reward token contract based on how + // much the supply factor was changed + _depositInterestGains(interestCreated); + rewardModule.setSupplyFactor(supplyFactorNew); + + underlying.mint(address(this), amountOfRewards); + rewardModule.mint(address(this), amountOfRewards); + + uint256 expectedNormalizedMint2 = amountOfRewards.rayDivDown(supplyFactorNew); + uint256 totalDeposited = amountOfRewards * 2; + uint256 totalDepositsNormalized = expectedNormalizedMint1 + expectedNormalizedMint2; + uint256 totalValue = totalDepositsNormalized.rayMulDown(supplyFactorNew); + + assertEq(rewardModule.normalizedBalanceOf(address(this)), totalDepositsNormalized); + assertEq(rewardModule.balanceOf(address(this)), totalValue); + assertEq(underlying.balanceOf(address(this)), 0); + assertEq(underlying.balanceOf(address(rewardModule)), totalDeposited + interestCreated); + + uint256 burnAmount = amountOfRewards; + + rewardModule.burn(address(this), address(this), burnAmount); + + assertEq(underlying.balanceOf(address(this)), burnAmount); + assertEq(underlying.balanceOf(address(rewardModule)), totalDeposited + interestCreated - burnAmount); + } + + function testFuzz_transfer(uint256 amountOfRewardTokens) external { + vm.assume(amountOfRewardTokens != 0); + vm.assume(amountOfRewardTokens < 2 ** 128); + + underlying.mint(address(this), amountOfRewardTokens); + + underlying.approve(address(rewardModule), amountOfRewardTokens); + rewardModule.mint(address(this), amountOfRewardTokens); + + assertEq(rewardModule.normalizedBalanceOf(address(this)), amountOfRewardTokens); + assertEq(underlying.balanceOf(address(this)), 0); + assertEq(underlying.balanceOf(address(rewardModule)), amountOfRewardTokens); + + vm.expectRevert( + abi.encodeWithSelector( + IERC20Errors.ERC20InsufficientBalance.selector, + address(this), + amountOfRewardTokens, + amountOfRewardTokens + 1 + ) + ); + rewardModule.transfer(receivingUser, amountOfRewardTokens + 1); + vm.expectRevert(abi.encodeWithSelector(IERC20Errors.ERC20InvalidReceiver.selector, address(0))); + rewardModule.transfer(address(0), amountOfRewardTokens); + vm.expectRevert(abi.encodeWithSelector(RewardToken.SelfTransfer.selector, address(this))); + rewardModule.transfer(address(this), amountOfRewardTokens); + rewardModule.transfer(receivingUser, amountOfRewardTokens); + + assertEq(rewardModule.normalizedBalanceOf(address(this)), 0); + assertEq(rewardModule.normalizedBalanceOf(receivingUser), amountOfRewardTokens); + assertEq(underlying.balanceOf(address(this)), 0); + } + + function testFuzz_transferFromWithApprove(uint256 amountOfRewardTokens) external { + vm.assume(amountOfRewardTokens != 0); + vm.assume(amountOfRewardTokens < 2 ** 128); + + underlying.mint(address(this), amountOfRewardTokens); + + underlying.approve(address(rewardModule), amountOfRewardTokens); + rewardModule.mint(sendingUser, amountOfRewardTokens); + + assertEq(rewardModule.normalizedBalanceOf(sendingUser), amountOfRewardTokens); + assertEq(rewardModule.normalizedBalanceOf(receivingUser), 0); + assertEq(rewardModule.allowance(sendingUser, spender), 0); + assertEq(underlying.balanceOf(address(this)), 0); + assertEq(underlying.balanceOf(address(rewardModule)), amountOfRewardTokens); + + vm.prank(sendingUser); + rewardModule.approve(spender, amountOfRewardTokens); + + assertEq(rewardModule.allowance(sendingUser, spender), amountOfRewardTokens); + + vm.expectRevert( + abi.encodeWithSelector( + IERC20Errors.ERC20InsufficientAllowance.selector, address(this), 0, amountOfRewardTokens + ) + ); + rewardModule.transferFrom(sendingUser, receivingUser, amountOfRewardTokens); + vm.expectRevert( + abi.encodeWithSelector( + IERC20Errors.ERC20InsufficientAllowance.selector, + spender, + amountOfRewardTokens, + amountOfRewardTokens + 1 + ) + ); + vm.startPrank(spender); + rewardModule.transferFrom(sendingUser, receivingUser, amountOfRewardTokens + 1); + rewardModule.transferFrom(sendingUser, receivingUser, amountOfRewardTokens); + + assertEq(rewardModule.normalizedBalanceOf(sendingUser), 0); + assertEq(rewardModule.normalizedBalanceOf(receivingUser), amountOfRewardTokens); + assertEq(rewardModule.allowance(sendingUser, spender), 0); + } + + function testFuzz_transferFromWithPermit(uint256 amountOfRewardTokens) external { + vm.assume(amountOfRewardTokens != 0); + vm.assume(amountOfRewardTokens < 2 ** 128); + + underlying.mint(address(this), amountOfRewardTokens); + + underlying.approve(address(rewardModule), amountOfRewardTokens); + rewardModule.mint(sendingUser, amountOfRewardTokens); + + assertEq(rewardModule.normalizedBalanceOf(sendingUser), amountOfRewardTokens); + assertEq(rewardModule.normalizedBalanceOf(receivingUser), 0); + assertEq(rewardModule.allowance(sendingUser, spender), 0); + assertEq(underlying.balanceOf(address(this)), 0); + assertEq(underlying.balanceOf(address(rewardModule)), amountOfRewardTokens); + + { + bytes32 PERMIT_TYPEHASH = rewardModule.PERMIT_TYPEHASH(); + bytes32 domainSeparator = keccak256( + abi.encode( + EIP712_DOMAIN, + keccak256(bytes(rewardModule.name())), + keccak256(EIP712_REVISION), + block.chainid, + address(rewardModule) + ) + ); + uint256 deadline = block.timestamp + 30 minutes; + + bytes32 structHash = + keccak256(abi.encode(PERMIT_TYPEHASH, sendingUser, spender, amountOfRewardTokens, 0, deadline)); + MessageHashUtils.toTypedDataHash(domainSeparator, structHash); + + (uint8 v, bytes32 r, bytes32 s) = + vm.sign(sendingUserPrivateKey, MessageHashUtils.toTypedDataHash(domainSeparator, structHash)); + + rewardModule.permit(sendingUser, spender, amountOfRewardTokens, deadline, v, r, s); + } + + assertEq(rewardModule.allowance(sendingUser, spender), amountOfRewardTokens); + + vm.expectRevert( + abi.encodeWithSelector( + IERC20Errors.ERC20InsufficientAllowance.selector, address(this), 0, amountOfRewardTokens + ) + ); + rewardModule.transferFrom(sendingUser, receivingUser, amountOfRewardTokens); + vm.expectRevert( + abi.encodeWithSelector( + IERC20Errors.ERC20InsufficientAllowance.selector, + spender, + amountOfRewardTokens, + amountOfRewardTokens + 1 + ) + ); + vm.startPrank(spender); + rewardModule.transferFrom(sendingUser, receivingUser, amountOfRewardTokens + 1); + rewardModule.transferFrom(sendingUser, receivingUser, amountOfRewardTokens); + + assertEq(rewardModule.normalizedBalanceOf(sendingUser), 0); + assertEq(rewardModule.normalizedBalanceOf(receivingUser), amountOfRewardTokens); + assertEq(rewardModule.allowance(sendingUser, spender), 0); + } + + struct PermitLocals { + uint256 amountOfRewardTokens; + } + + function testFuzz_permit( + uint256 amountOfRewardTokens, + uint256 nonSenderPrivateKey, + uint256 deadlineTime + ) + external + { + vm.assume(amountOfRewardTokens != 0); + vm.assume(amountOfRewardTokens < 2 ** 128); + nonSenderPrivateKey = bound(nonSenderPrivateKey, 100, 2 ** 128); + deadlineTime = bound(deadlineTime, 1, 2 ** 128); + + PermitLocals memory locals = PermitLocals({ amountOfRewardTokens: amountOfRewardTokens }); + locals.amountOfRewardTokens = amountOfRewardTokens; + + underlying.mint(address(this), locals.amountOfRewardTokens); + + underlying.approve(address(rewardModule), locals.amountOfRewardTokens); + rewardModule.mint(sendingUser, locals.amountOfRewardTokens); + assertEq(rewardModule.normalizedBalanceOf(sendingUser), locals.amountOfRewardTokens); + assertEq(rewardModule.normalizedBalanceOf(receivingUser), 0); + assertEq(rewardModule.allowance(sendingUser, spender), 0); + assertEq(underlying.balanceOf(address(this)), 0); + assertEq(underlying.balanceOf(address(rewardModule)), locals.amountOfRewardTokens); + + { + bytes32 PERMIT_TYPEHASH = rewardModule.PERMIT_TYPEHASH(); + bytes32 domainSeparator = keccak256( + abi.encode( + EIP712_DOMAIN, + keccak256(bytes(rewardModule.name())), + keccak256(EIP712_REVISION), + block.chainid, + address(rewardModule) + ) + ); + uint256 deadline = block.timestamp + 30 minutes; + + // Have spender try to sign on behalf of sendingUser (should fail) + bytes32 structHash = + keccak256(abi.encode(PERMIT_TYPEHASH, sendingUser, spender, locals.amountOfRewardTokens, 0, deadline)); + MessageHashUtils.toTypedDataHash(domainSeparator, structHash); + + (uint8 v, bytes32 r, bytes32 s) = + vm.sign(nonSenderPrivateKey, MessageHashUtils.toTypedDataHash(domainSeparator, structHash)); + + vm.expectRevert( + abi.encodeWithSelector( + RewardToken.ERC2612InvalidSigner.selector, vm.addr(nonSenderPrivateKey), sendingUser + ) + ); + rewardModule.permit(sendingUser, spender, locals.amountOfRewardTokens, deadline, v, r, s); + + (v, r, s) = vm.sign(sendingUserPrivateKey, MessageHashUtils.toTypedDataHash(domainSeparator, structHash)); + (uint8 vMalleable, bytes32 rMalleable, bytes32 sMalleable) = _calculateMalleableSignature(v, r, s); + + // Openzeppelin ECDSA library already prevents the use of malleable signatures, even if nonce-based replay + // protection wasn't included + vm.expectRevert(abi.encodeWithSelector(ECDSA.ECDSAInvalidSignatureS.selector, sMalleable)); + rewardModule.permit( + sendingUser, spender, locals.amountOfRewardTokens, deadline, vMalleable, rMalleable, sMalleable + ); + + uint256 prevBlockTimestamp = block.timestamp; + vm.warp(deadline + 1); + vm.expectRevert(abi.encodeWithSelector(RewardToken.ERC2612ExpiredSignature.selector, deadline)); + rewardModule.permit(sendingUser, spender, locals.amountOfRewardTokens, deadline, v, r, s); + vm.warp(prevBlockTimestamp); + rewardModule.permit(sendingUser, spender, locals.amountOfRewardTokens, deadline, v, r, s); + } + + assertEq(rewardModule.allowance(sendingUser, spender), locals.amountOfRewardTokens); + } +} diff --git a/test/unit/fuzz/vault/Vault.t.sol b/test/unit/fuzz/vault/Vault.t.sol new file mode 100644 index 00000000..00aacecb --- /dev/null +++ b/test/unit/fuzz/vault/Vault.t.sol @@ -0,0 +1,458 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.21; + +import { Vault } from "./../../../../src/vault/Vault.sol"; +import { VaultFactory } from "./../../../../src/vault/VaultFactory.sol"; +import { IIonPool } from "./../../../../src/interfaces/IIonPool.sol"; +import { IonPoolExposed } from "../../../helpers/IonPoolSharedSetup.sol"; +import { VaultSharedSetup } from "../../../helpers/VaultSharedSetup.sol"; +import { Math } from "openzeppelin-contracts/contracts/utils/math/Math.sol"; +import { WadRayMath, RAY } from "./../../../../src/libraries/math/WadRayMath.sol"; +import { IERC20 } from "openzeppelin-contracts/contracts/interfaces/IERC20.sol"; + +using Math for uint256; +using WadRayMath for uint256; + +contract Vault_Fuzz is VaultSharedSetup { + function setUp() public override { + super.setUp(); + + BASE_ASSET.approve(address(weEthIonPool), type(uint256).max); + BASE_ASSET.approve(address(rsEthIonPool), type(uint256).max); + BASE_ASSET.approve(address(rswEthIonPool), type(uint256).max); + } + + /* + * Confirm rounding error max bound + * error = asset - floor[asset * RAY - (asset * RAY) % SF] / RAY) + * Considering the modulos, this error value is max bounded to + * max bound error = (SF - 2) / RAY + 1 + * NOTE: While this passes, the expression with SF - 3 also passes, so not + * yet a guarantee that this is the tightest bound possible. + */ + function testFuzz_IonPoolSupplyRoundingError(uint256 assets, uint256 supplyFactor) public { + assets = bound(assets, 1e18, type(uint128).max); + supplyFactor = bound(supplyFactor, 1e27, assets * RAY); + + setERC20Balance(address(BASE_ASSET), address(this), assets); + + IonPoolExposed(address(weEthIonPool)).setSupplyFactor(supplyFactor); + + weEthIonPool.supply(address(this), assets, new bytes32[](0)); + + uint256 expectedClaim = assets; + uint256 resultingClaim = weEthIonPool.balanceOf(address(this)); + + uint256 re = assets - ((assets * RAY - ((assets * RAY) % supplyFactor)) / RAY); + assertLe(expectedClaim - resultingClaim, (supplyFactor - 2) / RAY + 1); + } + + function testFuzz_FullyWithdrawableFromIonPool(uint256 assets) public { + uint256 supplyFactor = bound(assets, 1e27, 10e45); + uint256 normalizedAmt = bound(assets, 0, type(uint48).max); + + uint256 claim = normalizedAmt * supplyFactor / RAY; + uint256 sharesToBurn = claim * RAY / supplyFactor; + sharesToBurn = sharesToBurn * supplyFactor < claim * RAY ? sharesToBurn + 1 : sharesToBurn; + + assertEq(normalizedAmt, sharesToBurn); + } + + // NOTE Supplying the diff can revert if the normalized mint amount + // truncates to zero. Otherwise, it should be impossible to supply the + // 'diff' and end up violating the supply cap. + + function testFuzz_DepositToFillSupplyCap(uint256 assets, uint256 supplyFactor) public { + supplyFactor = bound(supplyFactor, 1e27, 10e27); + IonPoolExposed(address(weEthIonPool)).setSupplyFactor(supplyFactor); + + uint256 supplyCap = bound(assets, 100e18, type(uint128).max); + weEthIonPool.updateSupplyCap(supplyCap); + + uint256 initialDeposit = bound(assets, 1e18, supplyCap - 10e18); + supply(address(this), weEthIonPool, initialDeposit); + uint256 initialTotalNormalized = weEthIonPool.normalizedTotalSupply(); + + uint256 supplyCapDiff = _zeroFloorSub(supplyCap, weEthIonPool.totalSupply()); + + // `IonPool.supply` math + uint256 amountScaled = supplyCapDiff.rayDivDown(supplyFactor); + uint256 resultingTotalNormalized = initialTotalNormalized + amountScaled; + + uint256 resultingTotalClaim = resultingTotalNormalized.rayMulDown(supplyFactor); + + supply(address(this), weEthIonPool, supplyCapDiff); + + assertEq(resultingTotalClaim, weEthIonPool.totalSupply(), "resulting should be the same as calculated"); + + // Is it possible that depositing this supplyCapDiff results in a revert? + // `IonPool` compares `getTotalUnderlyingClaims > _supplyCap` + assertLe(resultingTotalClaim, supplyCap, "supply cap reached"); + assertLe(weEthIonPool.totalSupply(), supplyCap, "supply cap reached"); + } + + // Supplying the diff in the allocation cap should never end up violating + // the allocation cap. + // Is it possible that the `maxDeposit` returns more than the allocation cap? + function testFuzz_DepositToFillAllocationCap(uint256 assets, uint256 supplyFactor) public { + supplyFactor = bound(supplyFactor, 1e27, 9e27); + IonPoolExposed(address(weEthIonPool)).setSupplyFactor(supplyFactor); + + uint256 allocationCap = bound(assets, 100e18, type(uint128).max); + updateAllocationCaps(vault, allocationCap, type(uint128).max, 0); + + // Deposit, but leave some room below the allocation cap. + uint256 depositAmt = bound(assets, 1e18, allocationCap - 10e18); + setERC20Balance(address(BASE_ASSET), address(this), depositAmt); + vault.deposit(depositAmt, address(this)); + + // uint256 initialTotalNormalized = weEthIonPool.totalSupplyUnaccrued(); + uint256 initialTotalNormalized = weEthIonPool.normalizedTotalSupply(); + + uint256 allocationCapDiff = _zeroFloorSub(allocationCap, weEthIonPool.balanceOf(address(vault))); + + uint256 amountScaled = allocationCapDiff.rayDivDown(supplyFactor); + uint256 resultingTotalNormalized = initialTotalNormalized + amountScaled; + uint256 resultingTotalClaim = resultingTotalNormalized.rayMulDown(supplyFactor); + + // Try to deposit a little more than the first allocation cap would + // allow, then check whether it's possible to violate the first + // allocation cap. + + setERC20Balance(address(BASE_ASSET), address(this), allocationCapDiff + 123e18); + vault.deposit(allocationCapDiff + 123e18, address(this)); + + uint256 actualTotalClaim = weEthIonPool.balanceOf(address(vault)); + assertEq(resultingTotalClaim, actualTotalClaim, "expected and actual must be equal"); + + assertLe(resultingTotalClaim, allocationCap, "expected claim le to allocation cap"); + assertLe(actualTotalClaim, allocationCap, "actual claim le to allocation cap"); + } +} + +contract VaultWithYieldAndFee_Fuzz is VaultSharedSetup { + uint256 constant INITIAL_SUPPLY_AMT = 1000e18; + + function setUp() public override { + super.setUp(); + + uint256 initialSupplyAmt = 1000e18; + + weEthIonPool.updateSupplyCap(type(uint256).max); + rsEthIonPool.updateSupplyCap(type(uint256).max); + rswEthIonPool.updateSupplyCap(type(uint256).max); + + weEthIonPool.updateIlkDebtCeiling(0, type(uint256).max); + rsEthIonPool.updateIlkDebtCeiling(0, type(uint256).max); + rswEthIonPool.updateIlkDebtCeiling(0, type(uint256).max); + + supply(address(this), weEthIonPool, INITIAL_SUPPLY_AMT); + borrow(address(this), weEthIonPool, weEthGemJoin, 100e18, 70e18); + + supply(address(this), rsEthIonPool, INITIAL_SUPPLY_AMT); + borrow(address(this), rsEthIonPool, rsEthGemJoin, 100e18, 70e18); + + supply(address(this), rswEthIonPool, INITIAL_SUPPLY_AMT); + borrow(address(this), rswEthIonPool, rswEthGemJoin, 100e18, 70e18); + + uint256 weEthIonPoolCap = 10e18; + uint256 rsEthIonPoolCap = 20e18; + uint256 rswEthIonPoolCap = 30e18; + + vm.prank(OWNER); + updateAllocationCaps(vault, weEthIonPoolCap, rsEthIonPoolCap, rswEthIonPoolCap); + } + + function testFuzz_AccruedFeeShares(uint256 initialDeposit, uint256 feePerc, uint256 daysAccrued) public { + // fee percentage + feePerc = bound(feePerc, 0, RAY - 1); + + vm.prank(OWNER); + vault.updateFeePercentage(feePerc); + + // initial deposit + uint256 initialMaxDeposit = vault.maxDeposit(NULL); + initialDeposit = bound(initialDeposit, 1e18, initialMaxDeposit); + + setERC20Balance(address(BASE_ASSET), address(this), initialDeposit); + vault.deposit(initialDeposit, address(this)); + + // initial state + uint256 prevTotalAssets = vault.totalAssets(); + uint256 prevUserShares = vault.balanceOf(address(this)); + uint256 prevUserAssets = vault.previewRedeem(prevUserShares); + + // interest accrues over a year + daysAccrued = bound(daysAccrued, 1, 10_000 days); + vm.warp(block.timestamp + daysAccrued); + + (uint256 totalSupplyFactorIncrease,,,,) = weEthIonPool.calculateRewardAndDebtDistribution(); + uint256 newTotalAssets = vault.totalAssets(); + uint256 interestAccrued = newTotalAssets - prevTotalAssets; // [WAD] + + assertGt(totalSupplyFactorIncrease, 0, "total supply factor increase"); + assertGt(vault.totalAssets(), prevTotalAssets, "total assets increased"); + assertGt(interestAccrued, 0, "interest accrued"); + + // expected resulting state + + uint256 expectedFeeAssets = interestAccrued.mulDiv(feePerc, RAY); + uint256 expectedFeeShares = expectedFeeAssets.mulDiv( + vault.totalSupply() + 1, newTotalAssets - expectedFeeAssets + 1, Math.Rounding.Floor + ); + + uint256 expectedUserAssets = prevUserAssets + interestAccrued.mulDiv(RAY - feePerc, RAY); + + vm.prank(OWNER); + vault.accrueFee(); + assertEq(vault.lastTotalAssets(), vault.totalAssets(), "last total assets updated"); + + // actual resulting values + uint256 feeRecipientShares = vault.balanceOf(FEE_RECIPIENT); + uint256 feeRecipientAssets = vault.previewRedeem(feeRecipientShares); + + uint256 userShares = vault.balanceOf(address(this)); + uint256 userAssets = vault.previewRedeem(userShares); + + // fee recipient + // 1. The actual shares minted must be exactly equal to the expected + // shares calculation. + // 2. The actual claim from previewRedeem versus the expected claim to the + // underlying assets will differ due to the vault rounding in its favor + // inside the `preview` calculation. Even though the correct number of + // shares were minted, the actual 'withdrawable' amount will be rounded + // down in vault's favor. The actual must always be less than expected. + assertEq(feeRecipientShares, expectedFeeShares, "fee shares"); + assertLe(expectedFeeAssets - feeRecipientAssets, 2, "fee assets with rounding error"); + + // the diluted user + // Expected to increase their assets by (interestAccrued * (1 - feePerc)) + // 1. The shares balance for the user does not change. + // 2. The withdrawable assets after the fee should have increased by + // their portion of interest accrued. + assertEq(userShares, prevUserShares, "user shares"); + // Sometimes userAssets > expectedUserAssets, sometimes less than. + assertApproxEqAbs(userAssets, expectedUserAssets, 1, "user assets"); + + // fee recipient and user + // 1. The user and the fee recipient are the only shareholders. + // 2. The total withdrawable by the user and the fee recipient should equal total assets. + assertEq(userShares + feeRecipientShares, vault.totalSupply(), "vault total supply"); + assertLe(vault.totalAssets() - (userAssets + feeRecipientAssets), 2, "vault total assets"); + } + + function testFuzz_MaxWithdrawAndMaxRedeem(uint256 assets) public { } + + function testFuzz_MaxDepositAndMaxMint(uint256 assets) public { } +} + +contract VaultInflationAttack is VaultSharedSetup { + address immutable ATTACKER = newAddress("attacker"); + address immutable USER = newAddress("user"); + + function setUp() public override { + super.setUp(); + + IIonPool[] memory market = new IIonPool[](1); + market[0] = IDLE; + + uint256[] memory allocationCaps = new uint256[](1); + allocationCaps[0] = type(uint256).max; + + IIonPool[] memory queue = new IIonPool[](4); + queue[0] = IDLE; + queue[1] = weEthIonPool; + queue[2] = rsEthIonPool; + queue[3] = rswEthIonPool; + + vm.prank(OWNER); + vault.addSupportedMarkets(market, allocationCaps, queue, queue); + + vm.prank(ATTACKER); + IERC20(address(BASE_ASSET)).approve(address(vault), type(uint256).max); + vm.prank(USER); + IERC20(address(BASE_ASSET)).approve(address(vault), type(uint256).max); + } + + function testFuzz_InflationAttackNotProfitable(uint256 assets) public { + // 1. The vault has not been used. + // - no shares minted and no assets deposited. + // - but the initial conversion is dictated by virtual shares. + assertEq(vault.totalSupply(), 0, "initial total supply"); + assertEq(vault.totalAssets(), 0, "initial total assets"); + + // 2. The attacker makes a first deposit. + uint256 firstDepositAmt = bound(assets, 0, type(uint128).max); + setERC20Balance(address(BASE_ASSET), ATTACKER, firstDepositAmt); + + vm.prank(ATTACKER); + vault.mint(firstDepositAmt, ATTACKER); + + uint256 attackerClaimAfterMint = vault.previewRedeem(vault.balanceOf(ATTACKER)); + + // check that the mint amount and transfer amount was the same + assertEq(BASE_ASSET.balanceOf(ATTACKER), 0, "mint amount equals transfer amount"); + + // 3. The attacker donates. + // - In this case, transfers to vault to increase IDLE deposits. + // - Check that the attacker loses a portion of the donated funds. + uint256 donationAmt = bound(assets, 0, type(uint128).max); + setERC20Balance(address(BASE_ASSET), ATTACKER, donationAmt); + + vm.prank(ATTACKER); + IERC20(address(BASE_ASSET)).transfer(address(vault), donationAmt); + + uint256 attackerClaimAfterDonation = vault.previewRedeem(vault.balanceOf(ATTACKER)); + uint256 attackerLossFromDonation = donationAmt - (attackerClaimAfterDonation - attackerClaimAfterMint); + + uint256 totalAssetsBeforeDeposit = vault.totalAssets(); + uint256 totalSupplyBeforeDeposit = vault.totalSupply(); + + // 4. A user makes a deposit where the shares truncate to zero. + // - sharesToMint = depositAmt * (newTotalSupply + 1) / (newTotalAssets + 1) + // - The sharesToMint must be less than 1 to round down to zero + // - depositAmt * (newTotalSupply + 1) / (newTotalAssets + 1) < 1 + // - depositAmt < 1 * (newTotalAssets + 1) / (newTotalSupply + 1) + uint256 maxDepositAmt = (vault.totalAssets() + 1) / (vault.totalSupply() + 1); + uint256 userDepositAmt = bound(assets, 0, maxDepositAmt); + + vm.startPrank(USER); + setERC20Balance(address(BASE_ASSET), USER, userDepositAmt); + IERC20(address(BASE_ASSET)).approve(address(vault), userDepositAmt); + vault.deposit(userDepositAmt, USER); + vm.stopPrank(); + + assertEq(vault.balanceOf(USER), 0, "user minted shares must be zero"); + + uint256 attackerClaimAfterUser = vault.previewRedeem(vault.balanceOf(ATTACKER)); + uint256 attackerGainFromUser = attackerClaimAfterUser - attackerClaimAfterDonation; + + // loss = donationAmt / (1 + firstDepositAmt) + uint256 expectedAttackerLossFromDonation = donationAmt / (1 + firstDepositAmt); + assertLe( + attackerLossFromDonation - expectedAttackerLossFromDonation, + 1, + "attacker loss from donation as expected with rounding error" + ); + + // INVARIANT: The money gained from the user must be less than or equal to the attacker's loss from the + // donation. + // assertLe(attackerGainFromUser, attackerLossFromDonation, "attacker must not profit from user"); + assertLe(userDepositAmt, attackerLossFromDonation, "loss must be ge to user deposit"); + } + + // Even though virtual assets and shares makes the attack not 'profitable' + // for the attacker, the attacker may still be able to cause loss of user + // funds for a small loss of their own. For example, the attacker may try to + // cause the user to lose their 1e18 deposit by losing 0.01e18 deposit of + // their own to grief the user, regardless of economic incentives. If the + // vault is deployed through a factory that enforces a minimum deposit and a + // 1e3 shares burn, the attacker should not be able to grief a larger amount + // than they will lose from their own deposits. + function testFuzz_InflationAttackTheAttackerLosesMoreThanItCanGrief(uint256 assets) public { + // Set up factory deployment args with IDLE pool. + uint256[] memory alloCaps = new uint256[](4); + alloCaps[0] = type(uint256).max; + alloCaps[1] = type(uint256).max; + alloCaps[2] = type(uint256).max; + alloCaps[3] = type(uint256).max; + + IIonPool[] memory markets = new IIonPool[](4); + markets[0] = IDLE; + markets[1] = weEthIonPool; + markets[2] = rsEthIonPool; + markets[3] = rswEthIonPool; + + marketsArgs.marketsToAdd = markets; + marketsArgs.allocationCaps = alloCaps; + marketsArgs.newSupplyQueue = markets; + marketsArgs.newWithdrawQueue = markets; + + address deployer = newAddress("DEPLOYER"); + + // deploy using the factory which enforces minimum deposit of 1e9 assets + // and the 1e3 shares burn. + bytes32 salt = keccak256("random salt"); + + setERC20Balance(address(BASE_ASSET), deployer, MIN_INITIAL_DEPOSIT); + + VaultFactory factory = new VaultFactory(); + + vm.startPrank(deployer); + BASE_ASSET.approve(address(factory), MIN_INITIAL_DEPOSIT); + + Vault vault = factory.createVault( + BASE_ASSET, + FEE_RECIPIENT, + ZERO_FEES, + "Ion Vault Token", + "IVT", + INITIAL_DELAY, + VAULT_ADMIN, + salt, + marketsArgs, + MIN_INITIAL_DEPOSIT + ); + vm.stopPrank(); + + vm.startPrank(VAULT_ADMIN); + vault.grantRole(vault.OWNER_ROLE(), OWNER); + vm.stopPrank(); + + // 1. The vault has not been used. + // - Initial minimum deposit amt of 1e9 deposited. + // - 1e3 shares have been locked in factory. + assertEq(vault.totalSupply(), MIN_INITIAL_DEPOSIT, "initial total supply"); + assertEq(vault.totalAssets(), MIN_INITIAL_DEPOSIT, "initial total assets"); + assertEq(vault.balanceOf(address(factory)), 1e3, "initial factory shares"); + + // 2. The attacker makes a first deposit. + uint256 firstDepositAmt = bound(assets, 1, type(uint128).max); + setERC20Balance(address(BASE_ASSET), ATTACKER, firstDepositAmt); + + vm.startPrank(ATTACKER); + BASE_ASSET.approve(address(vault), type(uint256).max); + vault.mint(firstDepositAmt, ATTACKER); + vm.stopPrank(); + + uint256 attackerClaimAfterMint = vault.previewRedeem(vault.balanceOf(ATTACKER)); + + assertEq(BASE_ASSET.balanceOf(ATTACKER), 0, "mint amount equals transfer amount"); + + // 3. The attacker donates. + // - In this case, transfers to vault to increase IDLE deposits. + // - Check that the attacker loses a portion of the donated funds. + uint256 donationAmt = bound(assets, firstDepositAmt, type(uint128).max); + setERC20Balance(address(BASE_ASSET), ATTACKER, donationAmt); + + vm.prank(ATTACKER); + IERC20(address(BASE_ASSET)).transfer(address(vault), donationAmt); + + uint256 attackerClaimAfterDonation = vault.previewRedeem(vault.balanceOf(ATTACKER)); + uint256 attackerLossFromDonation = donationAmt - (attackerClaimAfterDonation - attackerClaimAfterMint); + + // 4. A user makes a deposit where the shares truncate to zero. + // - sharesToMint = depositAmt * (newTotalSupply + 1) / (newTotalAssets + 1) + // - The sharesToMint must be less than 1 to round down to zero + // - depositAmt * (newTotalSupply + 1) / (newTotalAssets + 1) < 1 + // - depositAmt < 1 * (newTotalAssets + 1) / (newTotalSupply + 1) + uint256 maxDepositAmt = (vault.totalAssets() + 1) / (vault.totalSupply() + 1); + uint256 userDepositAmt = bound(assets, 1, maxDepositAmt); + + vm.startPrank(USER); + setERC20Balance(address(BASE_ASSET), USER, userDepositAmt); + IERC20(address(BASE_ASSET)).approve(address(vault), userDepositAmt); + vault.deposit(userDepositAmt, USER); + vm.stopPrank(); + + assertEq(vault.balanceOf(USER), 0, "user minted shares must be zero"); + + uint256 attackerClaimAfterUser = vault.previewRedeem(vault.balanceOf(ATTACKER)); + uint256 attackerGainFromUser = attackerClaimAfterUser - attackerClaimAfterDonation; + + uint256 attackerNetLoss = firstDepositAmt + donationAmt - attackerClaimAfterUser; + assertLe(userDepositAmt, attackerNetLoss, "attacker net loss greater than user deposit amt"); + } + + function testFuzz_InflationAttackSmallerDegree() public { } +}