diff --git a/.env.example b/.env.example index b994bd7a7..276026670 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,4 @@ -NETWORK=eth-mainnet DEPLOYER_PRIVATE_KEY= TENDERLY_SECRET_KEY= +ETHERSCAN_API_KEY= ALCHEMY_KEY= diff --git a/.github/actions/ci-foundry/action.yml b/.github/actions/ci-foundry/action.yml index 28edbc0b2..5b10fd91a 100644 --- a/.github/actions/ci-foundry/action.yml +++ b/.github/actions/ci-foundry/action.yml @@ -11,10 +11,6 @@ inputs: network: description: The network against which to run the forge test suite. required: true - gasReport: - description: Whether to display gas reports. - default: true - required: true runs: using: composite @@ -48,28 +44,9 @@ runs: key: ${{ github.base_ref || github.ref_name }}-foundry-${{ inputs.protocol }}-${{ inputs.network }} # always keep compiled contracts from base branch - name: Run tests - run: make gas-report | tee ${{ inputs.protocol }}.${{ inputs.network }}.gasreport.ansi + run: make test shell: bash env: PROTOCOL: ${{ inputs.protocol }} NETWORK: ${{ inputs.network }} ALCHEMY_KEY: ${{ inputs.alchemyKey }} - FOUNDRY_FUZZ_SEED: 0x${{ github.event.pull_request.base.sha || github.sha }} - - - name: Compare gas reports - if: inputs.gasReport == 'true' - uses: Rubilmax/foundry-gas-diff@v3.9 - with: - report: ${{ inputs.protocol }}.${{ inputs.network }}.gasreport.ansi - ignore: test-foundry/**/* - header: | - # Morpho-${{ inputs.protocol }} gas impacts (${{ inputs.network }}) - id: gas_diff - - - name: Add gas diff to sticky comment - if: inputs.gasReport == 'true' && (github.event_name == 'pull_request' || github.event_name == 'pull_request_target') - uses: marocchino/sticky-pull-request-comment@v2 - with: - header: ${{ inputs.protocol }} (${{ inputs.network }}) - message: ${{ steps.gas_diff.outputs.markdown }} - delete: ${{ !steps.gas_diff.outputs.markdown }} # delete the comment in case changes no longer impacts gas costs diff --git a/.github/workflows/ci-foundry-aave-v3.yml b/.github/workflows/ci-foundry-aave-v3.yml index a147c8108..c14640434 100644 --- a/.github/workflows/ci-foundry-aave-v3.yml +++ b/.github/workflows/ci-foundry-aave-v3.yml @@ -34,7 +34,6 @@ jobs: # alchemyKey: ${{ secrets.ALCHEMY_KEY }} # protocol: aave-v3 # network: polygon-mainnet - # gasReport: false morpho-aave-v3-avalanche-mainnet: name: avalanche-mainnet diff --git a/.github/workflows/ci-hardhat-common.yml b/.github/workflows/ci-hardhat-common.yml index c02fcb642..9347ba45e 100644 --- a/.github/workflows/ci-hardhat-common.yml +++ b/.github/workflows/ci-hardhat-common.yml @@ -15,8 +15,6 @@ on: - foundry.toml - remappings.txt - .github/workflows/ci-hardhat-common.yml - paths-ignore: - - test/upgrades/** jobs: morpho-hardhat-tests: @@ -27,15 +25,16 @@ jobs: with: submodules: recursive - - uses: actions/setup-node@v3 - with: - node-version: 16 - cache: yarn + - uses: actions/setup-node@v3 + with: + node-version: 16 + cache: yarn - - name: Install dependencies - run: yarn install --frozen-lockfile + - name: Install dependencies + run: yarn install --frozen-lockfile - - name: Run tests - run: yarn test - env: - ALCHEMY_KEY: ${{ secrets.alchemyKey }} + - name: Run tests + run: yarn test + env: + NETWORK: eth-mainnet + ALCHEMY_KEY: ${{ secrets.ALCHEMY_KEY }} diff --git a/.github/workflows/ci-storage-check-aave-v2.yml b/.github/workflows/ci-storage-check-aave-v2.yml new file mode 100644 index 000000000..50d2e81d8 --- /dev/null +++ b/.github/workflows/ci-storage-check-aave-v2.yml @@ -0,0 +1,48 @@ +name: Storage layout checks + +on: + push: + branches: + - main + - dev + pull_request: + paths: + - lib/** + - contracts/common/** + - contracts/aave-v2/** + - "*.lock" + - remappings.txt + - .github/workflows/ci-storage-check-aave-v2.yml + +jobs: + morpho-aave-v2: + name: morpho-aave-v2 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + + - uses: actions/setup-node@v3 + with: + node-version: 16 + cache: yarn + + - name: Install dependencies + run: yarn install --frozen-lockfile + shell: bash + + - name: Install Foundry + uses: onbjerg/foundry-toolchain@v1 + with: + version: nightly + + - name: Check Morpho storage layout + uses: Rubilmax/foundry-storage-check@v2.1 + with: + contract: contracts/aave-v2/Morpho.sol:Morpho + + - name: Check RewardsManager storage layout + uses: Rubilmax/foundry-storage-check@v2.1 + with: + contract: contracts/aave-v2/RewardsManager.sol:RewardsManager diff --git a/.github/workflows/ci-storage-check-compound.yml b/.github/workflows/ci-storage-check-compound.yml new file mode 100644 index 000000000..17df43cfa --- /dev/null +++ b/.github/workflows/ci-storage-check-compound.yml @@ -0,0 +1,48 @@ +name: Storage layout checks + +on: + push: + branches: + - main + - dev + pull_request: + paths: + - lib/** + - contracts/common/** + - contracts/compound/** + - "*.lock" + - remappings.txt + - .github/workflows/ci-storage-check-compound.yml + +jobs: + morpho-compound: + name: morpho-compound + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + + - uses: actions/setup-node@v3 + with: + node-version: 16 + cache: yarn + + - name: Install dependencies + run: yarn install --frozen-lockfile + shell: bash + + - name: Install Foundry + uses: onbjerg/foundry-toolchain@v1 + with: + version: nightly + + - name: Check Morpho storage layout + uses: Rubilmax/foundry-storage-check@v2.1 + with: + contract: contracts/compound/Morpho.sol:Morpho + + - name: Check RewardsManager storage layout + uses: Rubilmax/foundry-storage-check@v2.1 + with: + contract: contracts/compound/RewardsManager.sol:RewardsManager diff --git a/.github/workflows/ci-storage-layout-aave-v2.yml b/.github/workflows/ci-storage-snapshot-check-aave-v2.yml similarity index 65% rename from .github/workflows/ci-storage-layout-aave-v2.yml rename to .github/workflows/ci-storage-snapshot-check-aave-v2.yml index 055e40d43..b8ac9a760 100644 --- a/.github/workflows/ci-storage-layout-aave-v2.yml +++ b/.github/workflows/ci-storage-snapshot-check-aave-v2.yml @@ -1,4 +1,4 @@ -name: Storage layout check (Morpho-Compound) +name: Storage layout snapshot check on: push: @@ -6,10 +6,17 @@ on: - main - dev pull_request: + paths: + - lib/** + - contracts/common/** + - contracts/aave-v2/** + - "*.lock" + - remappings.txt + - .github/workflows/ci-storage-check-aave-v2.yml jobs: check: - name: storage layout check + name: morpho-aave-v2 runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -29,14 +36,6 @@ jobs: with: version: nightly - - name: Foundry fork cache - uses: actions/cache@v3 - with: - path: | - cache - out - key: foundry-${{ hashFiles('Makefile', 'foundry.toml') }} # where fork block numbers & RPC are stored - - name: Run tests run: make storage-layout-check env: diff --git a/.github/workflows/ci-storage-layout-compound.yml b/.github/workflows/ci-storage-snapshot-check-compound.yml similarity index 65% rename from .github/workflows/ci-storage-layout-compound.yml rename to .github/workflows/ci-storage-snapshot-check-compound.yml index 51b435626..1c53f4c33 100644 --- a/.github/workflows/ci-storage-layout-compound.yml +++ b/.github/workflows/ci-storage-snapshot-check-compound.yml @@ -1,4 +1,4 @@ -name: Storage layout check (Morpho-Compound) +name: Storage layout snapshot check on: push: @@ -6,10 +6,17 @@ on: - main - dev pull_request: + paths: + - lib/** + - contracts/common/** + - contracts/compound/** + - "*.lock" + - remappings.txt + - .github/workflows/ci-storage-check-compound.yml jobs: check: - name: storage layout check + name: morpho-compound runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -29,14 +36,6 @@ jobs: with: version: nightly - - name: Foundry fork cache - uses: actions/cache@v3 - with: - path: | - cache - out - key: foundry-${{ hashFiles('Makefile', 'foundry.toml') }} # where fork block numbers & RPC are stored - - name: Run tests run: make storage-layout-check env: diff --git a/README.md b/README.md index 60f0f96be..48c51ee43 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # Morpho Core Protocol V1 -[![Test](https://github.com/morpho-labs/morpho-contracts/actions/workflows/ci-foundry.yml/badge.svg)](https://github.com/morpho-dao/morpho-v1/actions/workflows/ci-foundry.yml) +[![Morpho-Compound](https://github.com/morpho-dao/morpho-v1/actions/workflows/ci-foundry-compound.yml/badge.svg)](https://github.com/morpho-dao/morpho-v1/actions/workflows/ci-foundry-compound.yml) +[![Morpho-AaveV2](https://github.com/morpho-dao/morpho-v1/actions/workflows/ci-foundry-aave-v2.yml/badge.svg)](https://github.com/morpho-dao/morpho-v1/actions/workflows/ci-foundry-aave-v2.yml) +[![Morpho-AaveV3](https://github.com/morpho-dao/morpho-v1/actions/workflows/ci-foundry-aave-v3.yml/badge.svg)](https://github.com/morpho-dao/morpho-v1/actions/workflows/ci-foundry-aave-v3.yml) diff --git a/audits/ChainSecurity_Morpho_Aave_V3.pdf b/audits/ChainSecurity_Morpho_Labs_Morpho_Aave_v3_audit.pdf similarity index 93% rename from audits/ChainSecurity_Morpho_Aave_V3.pdf rename to audits/ChainSecurity_Morpho_Labs_Morpho_Aave_v3_audit.pdf index abab0e0b6..2f78871ce 100644 Binary files a/audits/ChainSecurity_Morpho_Aave_V3.pdf and b/audits/ChainSecurity_Morpho_Labs_Morpho_Aave_v3_audit.pdf differ diff --git a/contracts/aave-v2/EntryPositionsManager.sol b/contracts/aave-v2/EntryPositionsManager.sol index 222377708..d39855144 100644 --- a/contracts/aave-v2/EntryPositionsManager.sol +++ b/contracts/aave-v2/EntryPositionsManager.sol @@ -61,7 +61,6 @@ contract EntryPositionsManager is IEntryPositionsManager, PositionsManagerUtils // Struct to avoid stack too deep. struct SupplyVars { - bytes32 borrowMask; uint256 remainingToSupply; uint256 poolBorrowIndex; uint256 toRepay; @@ -91,17 +90,15 @@ contract EntryPositionsManager is IEntryPositionsManager, PositionsManagerUtils ) external { if (_onBehalf == address(0)) revert AddressIsZero(); if (_amount == 0) revert AmountIsZero(); - _updateIndexes(_poolToken); - SupplyVars memory vars; - vars.borrowMask = borrowMask[_poolToken]; - if (!_isSupplying(userMarkets[_onBehalf], vars.borrowMask)) - _setSupplying(_onBehalf, vars.borrowMask, true); + _updateIndexes(_poolToken); + _setSupplying(_onBehalf, borrowMask[_poolToken], true); ERC20 underlyingToken = ERC20(market[_poolToken].underlyingToken); underlyingToken.safeTransferFrom(_from, address(this), _amount); Types.Delta storage delta = deltas[_poolToken]; + SupplyVars memory vars; vars.poolBorrowIndex = poolIndexes[_poolToken].poolBorrowIndex; vars.remainingToSupply = _amount; @@ -191,10 +188,7 @@ contract EntryPositionsManager is IEntryPositionsManager, PositionsManagerUtils revert BorrowingNotEnabled(); _updateIndexes(_poolToken); - - bytes32 borrowMask = borrowMask[_poolToken]; - if (!_isBorrowing(userMarkets[msg.sender], borrowMask)) - _setBorrowing(msg.sender, borrowMask, true); + _setBorrowing(msg.sender, borrowMask[_poolToken], true); if (!_borrowAllowed(msg.sender, _poolToken, _amount)) revert UnauthorisedBorrow(); diff --git a/contracts/aave-v2/ExitPositionsManager.sol b/contracts/aave-v2/ExitPositionsManager.sol index 2aaf21504..32b450092 100644 --- a/contracts/aave-v2/ExitPositionsManager.sol +++ b/contracts/aave-v2/ExitPositionsManager.sol @@ -143,7 +143,7 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils { if (!_withdrawAllowed(_supplier, _poolToken, toWithdraw)) revert UnauthorisedWithdraw(); - _safeWithdrawLogic(_poolToken, toWithdraw, _supplier, _receiver, _maxGasForMatching); + _unsafeWithdrawLogic(_poolToken, toWithdraw, _supplier, _receiver, _maxGasForMatching); } /// @dev Implements repay logic with security checks. @@ -165,7 +165,7 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils { uint256 toRepay = Math.min(_getUserBorrowBalanceInOf(_poolToken, _onBehalf), _amount); if (toRepay == 0) revert UserNotMemberOfMarket(); - _safeRepayLogic(_poolToken, _repayer, _onBehalf, toRepay, _maxGasForMatching); + _unsafeRepayLogic(_poolToken, _repayer, _onBehalf, toRepay, _maxGasForMatching); } /// @notice Liquidates a position. @@ -237,8 +237,8 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils { .percentDiv(vars.liquidationBonus); } - _safeRepayLogic(_poolTokenBorrowed, msg.sender, _borrower, amountToLiquidate, 0); - _safeWithdrawLogic(_poolTokenCollateral, amountToSeize, _borrower, msg.sender, 0); + _unsafeRepayLogic(_poolTokenBorrowed, msg.sender, _borrower, amountToLiquidate, 0); + _unsafeWithdrawLogic(_poolTokenCollateral, amountToSeize, _borrower, msg.sender, 0); emit Liquidated( msg.sender, @@ -258,7 +258,7 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils { /// @param _supplier The address of the supplier. /// @param _receiver The address of the user who will receive the tokens. /// @param _maxGasForMatching The maximum amount of gas to consume within a matching engine loop. - function _safeWithdrawLogic( + function _unsafeWithdrawLogic( address _poolToken, uint256 _amount, address _supplier, @@ -412,7 +412,7 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils { /// @param _onBehalf The address of the account whose debt is repaid. /// @param _amount The amount of token (in underlying). /// @param _maxGasForMatching The maximum amount of gas to consume within a matching engine loop. - function _safeRepayLogic( + function _unsafeRepayLogic( address _poolToken, address _repayer, address _onBehalf, diff --git a/contracts/aave-v2/InterestRatesManager.sol b/contracts/aave-v2/InterestRatesManager.sol index 2cd6a8219..1f6e7f67e 100644 --- a/contracts/aave-v2/InterestRatesManager.sol +++ b/contracts/aave-v2/InterestRatesManager.sol @@ -147,8 +147,9 @@ contract InterestRatesManager is IInterestRatesManager, MorphoStorage { p2pGrowthFactor + _params.reserveFactor.percentMul(poolBorrowGrowthFactor - p2pGrowthFactor); } else { - // The case poolSupplyGrowthFactor > poolBorrowGrowthFactor happens because someone has done a flashloan on Aave: - // the peer-to-peer growth factors are set to the pool borrow growth factor. + // The case poolSupplyGrowthFactor > poolBorrowGrowthFactor happens because someone has done a flashloan on Aave, or the interests + // generated by the stable rate borrowing are high (making the supply rate higher than the variable borrow rate): the peer-to-peer + // growth factors are set to the pool borrow growth factor. p2pSupplyGrowthFactor = poolBorrowGrowthFactor; p2pBorrowGrowthFactor = poolBorrowGrowthFactor; } diff --git a/contracts/aave-v2/interfaces/IEntryPositionsManager.sol b/contracts/aave-v2/interfaces/IEntryPositionsManager.sol index 88f5519c5..404f2fffc 100644 --- a/contracts/aave-v2/interfaces/IEntryPositionsManager.sol +++ b/contracts/aave-v2/interfaces/IEntryPositionsManager.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity ^0.8.0; +pragma solidity >=0.5.0; interface IEntryPositionsManager { function supplyLogic( diff --git a/contracts/aave-v2/interfaces/IExitPositionsManager.sol b/contracts/aave-v2/interfaces/IExitPositionsManager.sol index 419e0dcbd..a5e2415fb 100644 --- a/contracts/aave-v2/interfaces/IExitPositionsManager.sol +++ b/contracts/aave-v2/interfaces/IExitPositionsManager.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity ^0.8.0; +pragma solidity >=0.5.0; interface IExitPositionsManager { function withdrawLogic( diff --git a/contracts/aave-v2/interfaces/IGetterUnderlyingAsset.sol b/contracts/aave-v2/interfaces/IGetterUnderlyingAsset.sol index 1b18c16d2..b6fa1fd16 100644 --- a/contracts/aave-v2/interfaces/IGetterUnderlyingAsset.sol +++ b/contracts/aave-v2/interfaces/IGetterUnderlyingAsset.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity ^0.8.0; +pragma solidity >=0.5.0; interface IGetterUnderlyingAsset { function UNDERLYING_ASSET_ADDRESS() external view returns (address); diff --git a/contracts/aave-v2/interfaces/IIncentivesVault.sol b/contracts/aave-v2/interfaces/IIncentivesVault.sol index febeba642..dfab50516 100644 --- a/contracts/aave-v2/interfaces/IIncentivesVault.sol +++ b/contracts/aave-v2/interfaces/IIncentivesVault.sol @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity ^0.8.0; - +pragma solidity >=0.5.0; import "./IOracle.sol"; interface IIncentivesVault { diff --git a/contracts/aave-v2/interfaces/IInterestRatesManager.sol b/contracts/aave-v2/interfaces/IInterestRatesManager.sol index 406b43da0..dfc7713b0 100644 --- a/contracts/aave-v2/interfaces/IInterestRatesManager.sol +++ b/contracts/aave-v2/interfaces/IInterestRatesManager.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity ^0.8.0; +pragma solidity >=0.5.0; interface IInterestRatesManager { function ST_ETH() external view returns (address); diff --git a/contracts/aave-v2/interfaces/ILens.sol b/contracts/aave-v2/interfaces/ILens.sol index 20eaf0698..080db01a0 100644 --- a/contracts/aave-v2/interfaces/ILens.sol +++ b/contracts/aave-v2/interfaces/ILens.sol @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity ^0.8.0; - +pragma solidity >=0.5.0; import "./aave/IPriceOracleGetter.sol"; import "./aave/ILendingPool.sol"; import "./IMorpho.sol"; diff --git a/contracts/aave-v2/interfaces/IMorpho.sol b/contracts/aave-v2/interfaces/IMorpho.sol index d85b72af2..511cd213a 100644 --- a/contracts/aave-v2/interfaces/IMorpho.sol +++ b/contracts/aave-v2/interfaces/IMorpho.sol @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity ^0.8.0; - +pragma solidity >=0.5.0; import "./aave/ILendingPoolAddressesProvider.sol"; import "./aave/ILendingPool.sol"; import "./IEntryPositionsManager.sol"; diff --git a/contracts/aave-v2/interfaces/IOracle.sol b/contracts/aave-v2/interfaces/IOracle.sol index 22f465867..5025c0f44 100644 --- a/contracts/aave-v2/interfaces/IOracle.sol +++ b/contracts/aave-v2/interfaces/IOracle.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity ^0.8.0; +pragma solidity >=0.5.0; interface IOracle { function consult(uint256 _amountIn) external returns (uint256); diff --git a/contracts/aave-v2/interfaces/IRewardsManager.sol b/contracts/aave-v2/interfaces/IRewardsManager.sol index 34b520879..4804b2508 100644 --- a/contracts/aave-v2/interfaces/IRewardsManager.sol +++ b/contracts/aave-v2/interfaces/IRewardsManager.sol @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity ^0.8.0; - +pragma solidity >=0.5.0; import "./aave/IAaveIncentivesController.sol"; interface IRewardsManager { diff --git a/contracts/aave-v2/interfaces/aave/IAToken.sol b/contracts/aave-v2/interfaces/aave/IAToken.sol index 38aaad6a4..3ef1be664 100644 --- a/contracts/aave-v2/interfaces/aave/IAToken.sol +++ b/contracts/aave-v2/interfaces/aave/IAToken.sol @@ -1,5 +1,5 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity ^0.8.0; +// SPDX-License-Identifier: GNU AGPLv3 +pragma solidity >=0.5.0; import {IERC20} from "./IERC20.sol"; import {IScaledBalanceToken} from "./IScaledBalanceToken.sol"; diff --git a/contracts/aave-v2/interfaces/aave/IAaveIncentivesController.sol b/contracts/aave-v2/interfaces/aave/IAaveIncentivesController.sol index bc61009b2..16b52d17d 100644 --- a/contracts/aave-v2/interfaces/aave/IAaveIncentivesController.sol +++ b/contracts/aave-v2/interfaces/aave/IAaveIncentivesController.sol @@ -1,5 +1,5 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity ^0.8.0; +// SPDX-License-Identifier: GNU AGPLv3 +pragma solidity >=0.5.0; interface IAaveDistributionManager { event AssetConfigUpdated(address indexed asset, uint256 emission); diff --git a/contracts/aave-v2/interfaces/aave/IERC20.sol b/contracts/aave-v2/interfaces/aave/IERC20.sol index f68ed2bce..d0b0d3f09 100644 --- a/contracts/aave-v2/interfaces/aave/IERC20.sol +++ b/contracts/aave-v2/interfaces/aave/IERC20.sol @@ -1,5 +1,5 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity ^0.8.0; +// SPDX-License-Identifier: GNU AGPLv3 +pragma solidity >=0.5.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. diff --git a/contracts/aave-v2/interfaces/aave/ILendingPool.sol b/contracts/aave-v2/interfaces/aave/ILendingPool.sol index 0d8f56d86..51007b6e6 100644 --- a/contracts/aave-v2/interfaces/aave/ILendingPool.sol +++ b/contracts/aave-v2/interfaces/aave/ILendingPool.sol @@ -1,5 +1,5 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity ^0.8.0; +// SPDX-License-Identifier: GNU AGPLv3 +pragma solidity >=0.5.0; pragma experimental ABIEncoderV2; import {ILendingPoolAddressesProvider} from "./ILendingPoolAddressesProvider.sol"; diff --git a/contracts/aave-v2/interfaces/aave/ILendingPoolAddressesProvider.sol b/contracts/aave-v2/interfaces/aave/ILendingPoolAddressesProvider.sol index daab1180c..47db3a410 100644 --- a/contracts/aave-v2/interfaces/aave/ILendingPoolAddressesProvider.sol +++ b/contracts/aave-v2/interfaces/aave/ILendingPoolAddressesProvider.sol @@ -1,5 +1,5 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity ^0.8.0; +// SPDX-License-Identifier: GNU AGPLv3 +pragma solidity >=0.5.0; /** * @title LendingPoolAddressesProvider contract diff --git a/contracts/aave-v2/interfaces/aave/IPriceOracleGetter.sol b/contracts/aave-v2/interfaces/aave/IPriceOracleGetter.sol index 572a1e147..0204edb5b 100644 --- a/contracts/aave-v2/interfaces/aave/IPriceOracleGetter.sol +++ b/contracts/aave-v2/interfaces/aave/IPriceOracleGetter.sol @@ -1,5 +1,5 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.0; +// SPDX-License-Identifier: GNU AGPLv3 +pragma solidity >=0.5.0; /************ @title IPriceOracleGetter interface diff --git a/contracts/aave-v2/interfaces/aave/IScaledBalanceToken.sol b/contracts/aave-v2/interfaces/aave/IScaledBalanceToken.sol index 8ba23e0b3..e42aafa52 100644 --- a/contracts/aave-v2/interfaces/aave/IScaledBalanceToken.sol +++ b/contracts/aave-v2/interfaces/aave/IScaledBalanceToken.sol @@ -1,5 +1,5 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity ^0.8.0; +// SPDX-License-Identifier: GNU AGPLv3 +pragma solidity >=0.5.0; interface IScaledBalanceToken { /** diff --git a/contracts/aave-v2/interfaces/aave/IVariableDebtToken.sol b/contracts/aave-v2/interfaces/aave/IVariableDebtToken.sol index f6bd7322e..5eee30748 100644 --- a/contracts/aave-v2/interfaces/aave/IVariableDebtToken.sol +++ b/contracts/aave-v2/interfaces/aave/IVariableDebtToken.sol @@ -1,5 +1,5 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity ^0.8.0; +// SPDX-License-Identifier: GNU AGPLv3 +pragma solidity >=0.5.0; import {IScaledBalanceToken} from "./IScaledBalanceToken.sol"; diff --git a/contracts/aave-v2/interfaces/lido/ILido.sol b/contracts/aave-v2/interfaces/lido/ILido.sol index 89c68df51..10ce2aac2 100644 --- a/contracts/aave-v2/interfaces/lido/ILido.sol +++ b/contracts/aave-v2/interfaces/lido/ILido.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity ^0.8.0; +pragma solidity >=0.5.0; interface ILido { function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256); diff --git a/contracts/aave-v2/lens/Lens.sol b/contracts/aave-v2/lens/Lens.sol index b291a1b76..9c22fcf93 100644 --- a/contracts/aave-v2/lens/Lens.sol +++ b/contracts/aave-v2/lens/Lens.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity ^0.8.0; +pragma solidity 0.8.13; import "./MarketsLens.sol"; diff --git a/contracts/aave-v2/lens/LensStorage.sol b/contracts/aave-v2/lens/LensStorage.sol index 2a72f8cc2..c4cffd533 100644 --- a/contracts/aave-v2/lens/LensStorage.sol +++ b/contracts/aave-v2/lens/LensStorage.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity ^0.8.0; +pragma solidity 0.8.13; import "../interfaces/aave/IPriceOracleGetter.sol"; import "../interfaces/aave/ILendingPool.sol"; diff --git a/contracts/aave-v2/lens/MarketsLens.sol b/contracts/aave-v2/lens/MarketsLens.sol index aac42901e..6319d4374 100644 --- a/contracts/aave-v2/lens/MarketsLens.sol +++ b/contracts/aave-v2/lens/MarketsLens.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity ^0.8.0; +pragma solidity 0.8.13; import "./RatesLens.sol"; diff --git a/contracts/aave-v2/lens/RatesLens.sol b/contracts/aave-v2/lens/RatesLens.sol index 4ccfd6784..f33a7634b 100644 --- a/contracts/aave-v2/lens/RatesLens.sol +++ b/contracts/aave-v2/lens/RatesLens.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity ^0.8.0; +pragma solidity 0.8.13; import "../interfaces/aave/IVariableDebtToken.sol"; diff --git a/contracts/aave-v2/lens/UsersLens.sol b/contracts/aave-v2/lens/UsersLens.sol index f08d19aa9..044825b56 100644 --- a/contracts/aave-v2/lens/UsersLens.sol +++ b/contracts/aave-v2/lens/UsersLens.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity ^0.8.0; +pragma solidity 0.8.13; import {ERC20} from "@rari-capital/solmate/src/utils/SafeTransferLib.sol"; diff --git a/contracts/aave-v2/libraries/Types.sol b/contracts/aave-v2/libraries/Types.sol index 112569381..fe26ad712 100644 --- a/contracts/aave-v2/libraries/Types.sol +++ b/contracts/aave-v2/libraries/Types.sol @@ -62,8 +62,8 @@ library Types { // Variables are packed together to save gas (will not exceed their limit during Morpho's lifetime). struct PoolIndexes { uint32 lastUpdateTimestamp; // The last time the local pool and peer-to-peer indexes were updated. - uint112 poolSupplyIndex; // Last pool supply index. - uint112 poolBorrowIndex; // Last pool borrow index. + uint112 poolSupplyIndex; // Last pool supply index. Note that for the stEth market, the pool supply index is tweaked to take into account the staking rewards. + uint112 poolBorrowIndex; // Last pool borrow index. Note that for the stEth market, the pool borrow index is tweaked to take into account the staking rewards. } struct Market { diff --git a/contracts/aave-v2/libraries/aave/DataTypes.sol b/contracts/aave-v2/libraries/aave/DataTypes.sol index 8f9354a18..0e3bd739c 100644 --- a/contracts/aave-v2/libraries/aave/DataTypes.sol +++ b/contracts/aave-v2/libraries/aave/DataTypes.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: agpl-3.0 +// SPDX-License-Identifier: GNU AGPLv3 pragma solidity ^0.8.0; library DataTypes { diff --git a/contracts/aave-v2/libraries/aave/Errors.sol b/contracts/aave-v2/libraries/aave/Errors.sol index 36fde0f80..44573ab0a 100644 --- a/contracts/aave-v2/libraries/aave/Errors.sol +++ b/contracts/aave-v2/libraries/aave/Errors.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: agpl-3.0 +// SPDX-License-Identifier: GNU AGPLv3 pragma solidity ^0.8.0; /** diff --git a/contracts/aave-v2/libraries/aave/ReserveConfiguration.sol b/contracts/aave-v2/libraries/aave/ReserveConfiguration.sol index 6c5659720..063a8740b 100644 --- a/contracts/aave-v2/libraries/aave/ReserveConfiguration.sol +++ b/contracts/aave-v2/libraries/aave/ReserveConfiguration.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: agpl-3.0 +// SPDX-License-Identifier: GNU AGPLv3 pragma solidity ^0.8.0; import {Errors} from "./Errors.sol"; diff --git a/contracts/aave-v3/EntryPositionsManager.sol b/contracts/aave-v3/EntryPositionsManager.sol index 2eebabe95..548b5464b 100644 --- a/contracts/aave-v3/EntryPositionsManager.sol +++ b/contracts/aave-v3/EntryPositionsManager.sol @@ -68,7 +68,6 @@ contract EntryPositionsManager is IEntryPositionsManager, PositionsManagerUtils // Struct to avoid stack too deep. struct SupplyVars { - bytes32 borrowMask; uint256 remainingToSupply; uint256 poolBorrowIndex; uint256 toRepay; @@ -101,17 +100,15 @@ contract EntryPositionsManager is IEntryPositionsManager, PositionsManagerUtils Types.Market memory market = market[_poolToken]; if (!market.isCreatedMemory()) revert MarketNotCreated(); if (market.isSupplyPaused) revert SupplyPaused(); - _updateIndexes(_poolToken); - SupplyVars memory vars; - vars.borrowMask = borrowMask[_poolToken]; - if (!_isSupplying(userMarkets[_onBehalf], vars.borrowMask)) - _setSupplying(_onBehalf, vars.borrowMask, true); + _updateIndexes(_poolToken); + _setSupplying(_onBehalf, borrowMask[_poolToken], true); ERC20 underlyingToken = ERC20(market.underlyingToken); underlyingToken.safeTransferFrom(_from, address(this), _amount); Types.Delta storage delta = deltas[_poolToken]; + SupplyVars memory vars; vars.poolBorrowIndex = poolIndexes[_poolToken].poolBorrowIndex; vars.remainingToSupply = _amount; diff --git a/contracts/aave-v3/ExitPositionsManager.sol b/contracts/aave-v3/ExitPositionsManager.sol index 34f444333..a9adcf761 100644 --- a/contracts/aave-v3/ExitPositionsManager.sol +++ b/contracts/aave-v3/ExitPositionsManager.sol @@ -171,7 +171,7 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils { if (!_withdrawAllowed(_supplier, _poolToken, toWithdraw)) revert UnauthorisedWithdraw(); - _safeWithdrawLogic(_poolToken, toWithdraw, _supplier, _receiver, _maxGasForMatching); + _unsafeWithdrawLogic(_poolToken, toWithdraw, _supplier, _receiver, _maxGasForMatching); } /// @dev Implements repay logic with security checks. @@ -196,7 +196,7 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils { uint256 toRepay = Math.min(_getUserBorrowBalanceInOf(_poolToken, _onBehalf), _amount); if (toRepay == 0) revert UserNotMemberOfMarket(); - _safeRepayLogic(_poolToken, _repayer, _onBehalf, toRepay, _maxGasForMatching); + _unsafeRepayLogic(_poolToken, _repayer, _onBehalf, toRepay, _maxGasForMatching); } /// @notice Liquidates a position. @@ -272,8 +272,8 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils { .percentDiv(vars.liquidationBonus); } - _safeRepayLogic(_poolTokenBorrowed, msg.sender, _borrower, vars.amountToLiquidate, 0); - _safeWithdrawLogic(_poolTokenCollateral, vars.amountToSeize, _borrower, msg.sender, 0); + _unsafeRepayLogic(_poolTokenBorrowed, msg.sender, _borrower, vars.amountToLiquidate, 0); + _unsafeWithdrawLogic(_poolTokenCollateral, vars.amountToSeize, _borrower, msg.sender, 0); emit Liquidated( msg.sender, @@ -333,7 +333,7 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils { /// @param _supplier The address of the supplier. /// @param _receiver The address of the user who will receive the tokens. /// @param _maxGasForMatching The maximum amount of gas to consume within a matching engine loop. - function _safeWithdrawLogic( + function _unsafeWithdrawLogic( address _poolToken, uint256 _amount, address _supplier, @@ -487,7 +487,7 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils { /// @param _onBehalf The address of the account whose debt is repaid. /// @param _amount The amount of token (in underlying). /// @param _maxGasForMatching The maximum amount of gas to consume within a matching engine loop. - function _safeRepayLogic( + function _unsafeRepayLogic( address _poolToken, address _repayer, address _onBehalf, diff --git a/contracts/aave-v3/RewardsManager.sol b/contracts/aave-v3/RewardsManager.sol index 754d43056..83c12628f 100644 --- a/contracts/aave-v3/RewardsManager.sol +++ b/contracts/aave-v3/RewardsManager.sol @@ -107,10 +107,10 @@ contract RewardsManager is IRewardsManager, OwnableUpgradeable { _updateDataMultiple(_rewardsController, _user, _getUserAssetBalances(_assets, _user)); - for (uint256 i; i < _assets.length; ) { + for (uint256 i; i < _assets.length; ++i) { address asset = _assets[i]; - for (uint256 j; j < rewardsList.length; ) { + for (uint256 j; j < rewardsList.length; ++j) { uint256 rewardAmount = localAssetData[asset][rewardsList[j]] .usersData[_user] .accrued; @@ -119,14 +119,6 @@ contract RewardsManager is IRewardsManager, OwnableUpgradeable { claimedAmounts[j] += rewardAmount; localAssetData[asset][rewardsList[j]].usersData[_user].accrued = 0; } - - unchecked { - ++j; - } - } - - unchecked { - ++i; } } } @@ -159,12 +151,8 @@ contract RewardsManager is IRewardsManager, OwnableUpgradeable { ) external view returns (uint256 totalAccrued) { uint256 assetsLength = _assets.length; - for (uint256 i; i < assetsLength; ) { + for (uint256 i; i < assetsLength; ++i) { totalAccrued += localAssetData[_assets[i]][_reward].usersData[_user].accrued; - - unchecked { - ++i; - } } } @@ -184,8 +172,8 @@ contract RewardsManager is IRewardsManager, OwnableUpgradeable { unclaimedAmounts = new uint256[](rewardsListLength); // Add unrealized rewards from user to unclaimed rewards. - for (uint256 i; i < userAssetBalances.length; ) { - for (uint256 j; j < rewardsListLength; ) { + for (uint256 i; i < userAssetBalances.length; ++i) { + for (uint256 j; j < rewardsListLength; ++j) { unclaimedAmounts[j] += localAssetData[userAssetBalances[i].asset][rewardsList[j]] .usersData[_user] .accrued; @@ -197,14 +185,6 @@ contract RewardsManager is IRewardsManager, OwnableUpgradeable { rewardsList[j], userAssetBalances[i] ); - - unchecked { - ++j; - } - } - - unchecked { - ++i; } } } @@ -358,7 +338,7 @@ contract RewardsManager is IRewardsManager, OwnableUpgradeable { address _user, UserAssetBalance[] memory _userAssetBalances ) internal { - for (uint256 i; i < _userAssetBalances.length; ) { + for (uint256 i; i < _userAssetBalances.length; ++i) { _updateData( _rewardsController, _user, @@ -366,10 +346,6 @@ contract RewardsManager is IRewardsManager, OwnableUpgradeable { _userAssetBalances[i].balance, _userAssetBalances[i].totalSupply ); - - unchecked { - ++i; - } } } @@ -386,16 +362,14 @@ contract RewardsManager is IRewardsManager, OwnableUpgradeable { uint256 userAssetBalancesLength = _userAssetBalances.length; // Add unrealized rewards. - for (uint256 i; i < userAssetBalancesLength; ) { - if (_userAssetBalances[i].balance == 0) continue; + for (uint256 i; i < userAssetBalancesLength; ++i) { + unclaimedRewards += localAssetData[_userAssetBalances[i].asset][_reward] + .usersData[_user] + .accrued; - unclaimedRewards += - _getPendingRewards(_user, _reward, _userAssetBalances[i]) + - localAssetData[_userAssetBalances[i].asset][_reward].usersData[_user].accrued; + if (_userAssetBalances[i].balance == 0) continue; - unchecked { - ++i; - } + unclaimedRewards += _getPendingRewards(_user, _reward, _userAssetBalances[i]); } } @@ -506,7 +480,7 @@ contract RewardsManager is IRewardsManager, OwnableUpgradeable { uint256 assetsLength = _assets.length; userAssetBalances = new UserAssetBalance[](assetsLength); - for (uint256 i; i < assetsLength; ) { + for (uint256 i; i < assetsLength; ++i) { address asset = _assets[i]; userAssetBalances[i].asset = asset; @@ -525,10 +499,6 @@ contract RewardsManager is IRewardsManager, OwnableUpgradeable { else revert InvalidAsset(); userAssetBalances[i].totalSupply = IScaledBalanceToken(asset).scaledTotalSupply(); - - unchecked { - ++i; - } } } } diff --git a/contracts/aave-v3/interfaces/IEntryPositionsManager.sol b/contracts/aave-v3/interfaces/IEntryPositionsManager.sol index c5478af7f..404f2fffc 100644 --- a/contracts/aave-v3/interfaces/IEntryPositionsManager.sol +++ b/contracts/aave-v3/interfaces/IEntryPositionsManager.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity >=0.8.0; +pragma solidity >=0.5.0; interface IEntryPositionsManager { function supplyLogic( diff --git a/contracts/aave-v3/interfaces/IExitPositionsManager.sol b/contracts/aave-v3/interfaces/IExitPositionsManager.sol index 62bcbe1a8..f834cef76 100644 --- a/contracts/aave-v3/interfaces/IExitPositionsManager.sol +++ b/contracts/aave-v3/interfaces/IExitPositionsManager.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity >=0.8.0; +pragma solidity >=0.5.0; interface IExitPositionsManager { function withdrawLogic( diff --git a/contracts/aave-v3/interfaces/IIncentivesVault.sol b/contracts/aave-v3/interfaces/IIncentivesVault.sol index cc211649b..2b14c88f4 100644 --- a/contracts/aave-v3/interfaces/IIncentivesVault.sol +++ b/contracts/aave-v3/interfaces/IIncentivesVault.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity >=0.8.0; +pragma solidity >=0.5.0; import "./IOracle.sol"; diff --git a/contracts/aave-v3/interfaces/IInterestRatesManager.sol b/contracts/aave-v3/interfaces/IInterestRatesManager.sol index 311fd42ec..baa6fac64 100644 --- a/contracts/aave-v3/interfaces/IInterestRatesManager.sol +++ b/contracts/aave-v3/interfaces/IInterestRatesManager.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity >=0.8.0; +pragma solidity >=0.5.0; interface IInterestRatesManager { function updateIndexes(address _marketAddress) external; diff --git a/contracts/aave-v3/interfaces/IMorpho.sol b/contracts/aave-v3/interfaces/IMorpho.sol index bf253999b..4aa7a2e00 100644 --- a/contracts/aave-v3/interfaces/IMorpho.sol +++ b/contracts/aave-v3/interfaces/IMorpho.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity >=0.8.0; +pragma solidity >=0.5.0; import "@aave/periphery-v3/contracts/rewards/interfaces/IRewardsController.sol"; import "./aave/IPool.sol"; diff --git a/contracts/aave-v3/interfaces/IOracle.sol b/contracts/aave-v3/interfaces/IOracle.sol index 4221923ec..45a0f1978 100644 --- a/contracts/aave-v3/interfaces/IOracle.sol +++ b/contracts/aave-v3/interfaces/IOracle.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity >=0.8.0; +pragma solidity >=0.5.0; interface IOracle { function consult(uint256 _amountIn, address _tokenIn) external returns (uint256); diff --git a/contracts/aave-v3/interfaces/IRewardsManager.sol b/contracts/aave-v3/interfaces/IRewardsManager.sol index 09f64bd6d..734bfd56b 100644 --- a/contracts/aave-v3/interfaces/IRewardsManager.sol +++ b/contracts/aave-v3/interfaces/IRewardsManager.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity >=0.8.0; +pragma solidity >=0.5.0; import "@aave/periphery-v3/contracts/rewards/interfaces/IRewardsController.sol"; diff --git a/contracts/aave-v3/interfaces/aave/IPool.sol b/contracts/aave-v3/interfaces/aave/IPool.sol index d6077716a..a9acd52d1 100644 --- a/contracts/aave-v3/interfaces/aave/IPool.sol +++ b/contracts/aave-v3/interfaces/aave/IPool.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity >=0.8.0; +pragma solidity >=0.5.0; import {IPoolAddressesProvider} from "./IPoolAddressesProvider.sol"; import {DataTypes} from "../../libraries/aave/DataTypes.sol"; diff --git a/contracts/aave-v3/interfaces/aave/IPoolAddressesProvider.sol b/contracts/aave-v3/interfaces/aave/IPoolAddressesProvider.sol index 5232ee055..247d2e959 100644 --- a/contracts/aave-v3/interfaces/aave/IPoolAddressesProvider.sol +++ b/contracts/aave-v3/interfaces/aave/IPoolAddressesProvider.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity >=0.8.0; +pragma solidity >=0.5.0; interface IPoolAddressesProvider { function getPool() external view returns (address); diff --git a/contracts/aave-v3/interfaces/aave/IPoolToken.sol b/contracts/aave-v3/interfaces/aave/IPoolToken.sol index 622b79c51..77190b6da 100644 --- a/contracts/aave-v3/interfaces/aave/IPoolToken.sol +++ b/contracts/aave-v3/interfaces/aave/IPoolToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity >=0.8.0; +pragma solidity >=0.5.0; interface IPoolToken { function UNDERLYING_ASSET_ADDRESS() external view returns (address); diff --git a/contracts/compound/PositionsManager.sol b/contracts/compound/PositionsManager.sol index 5436931ed..92cdf6511 100644 --- a/contracts/compound/PositionsManager.sol +++ b/contracts/compound/PositionsManager.sol @@ -414,7 +414,7 @@ contract PositionsManager is IPositionsManager, MatchingEngine { if (_isLiquidatable(_supplier, _poolToken, toWithdraw, 0)) revert UnauthorisedWithdraw(); - _safeWithdrawLogic(_poolToken, toWithdraw, _supplier, _receiver, _maxGasForMatching); + _unsafeWithdrawLogic(_poolToken, toWithdraw, _supplier, _receiver, _maxGasForMatching); } /// @dev Implements repay logic with security checks. @@ -436,7 +436,7 @@ contract PositionsManager is IPositionsManager, MatchingEngine { _updateP2PIndexes(_poolToken); uint256 toRepay = Math.min(_getUserBorrowBalanceInOf(_poolToken, _onBehalf), _amount); - _safeRepayLogic(_poolToken, _repayer, _onBehalf, toRepay, _maxGasForMatching); + _unsafeRepayLogic(_poolToken, _repayer, _onBehalf, toRepay, _maxGasForMatching); } /// @notice Liquidates a position. @@ -466,7 +466,7 @@ contract PositionsManager is IPositionsManager, MatchingEngine { if (_amount > vars.borrowBalance.mul(comptroller.closeFactorMantissa())) revert AmountAboveWhatAllowedToRepay(); // Same mechanism as Compound. Liquidator cannot repay more than part of the debt (cf close factor on Compound). - _safeRepayLogic(_poolTokenBorrowed, msg.sender, _borrower, _amount, 0); + _unsafeRepayLogic(_poolTokenBorrowed, msg.sender, _borrower, _amount, 0); ICompoundOracle compoundOracle = ICompoundOracle(comptroller.oracle()); vars.collateralPrice = compoundOracle.getUnderlyingPrice(_poolTokenCollateral); @@ -481,7 +481,7 @@ contract PositionsManager is IPositionsManager, MatchingEngine { _getUserSupplyBalanceInOf(_poolTokenCollateral, _borrower) ); - _safeWithdrawLogic(_poolTokenCollateral, vars.amountToSeize, _borrower, msg.sender, 0); + _unsafeWithdrawLogic(_poolTokenCollateral, vars.amountToSeize, _borrower, msg.sender, 0); emit Liquidated( msg.sender, @@ -501,7 +501,7 @@ contract PositionsManager is IPositionsManager, MatchingEngine { /// @param _supplier The address of the supplier. /// @param _receiver The address of the user who will receive the tokens. /// @param _maxGasForMatching The maximum amount of gas to consume within a matching engine loop. - function _safeWithdrawLogic( + function _unsafeWithdrawLogic( address _poolToken, uint256 _amount, address _supplier, @@ -661,7 +661,7 @@ contract PositionsManager is IPositionsManager, MatchingEngine { /// @param _onBehalf The address of the account whose debt is repaid. /// @param _amount The amount of token (in underlying). /// @param _maxGasForMatching The maximum amount of gas to consume within a matching engine loop. - function _safeRepayLogic( + function _unsafeRepayLogic( address _poolToken, address _repayer, address _onBehalf, diff --git a/contracts/compound/interfaces/IIncentivesVault.sol b/contracts/compound/interfaces/IIncentivesVault.sol index faa7ced89..b1f06f298 100644 --- a/contracts/compound/interfaces/IIncentivesVault.sol +++ b/contracts/compound/interfaces/IIncentivesVault.sol @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity ^0.8.0; - +pragma solidity >=0.5.0; import "./IOracle.sol"; interface IIncentivesVault { diff --git a/contracts/compound/interfaces/IInterestRatesManager.sol b/contracts/compound/interfaces/IInterestRatesManager.sol index c429048e6..36e3e22f1 100644 --- a/contracts/compound/interfaces/IInterestRatesManager.sol +++ b/contracts/compound/interfaces/IInterestRatesManager.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity ^0.8.0; +pragma solidity >=0.5.0; interface IInterestRatesManager { function updateP2PIndexes(address _marketAddress) external; diff --git a/contracts/compound/interfaces/ILens.sol b/contracts/compound/interfaces/ILens.sol index eeb03697b..aeb59263e 100644 --- a/contracts/compound/interfaces/ILens.sol +++ b/contracts/compound/interfaces/ILens.sol @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity ^0.8.0; - +pragma solidity >=0.5.0; import "./compound/ICompound.sol"; import "./IRewardsManager.sol"; import "./IMorpho.sol"; diff --git a/contracts/compound/interfaces/IMorpho.sol b/contracts/compound/interfaces/IMorpho.sol index 63181f2d5..0456814c0 100644 --- a/contracts/compound/interfaces/IMorpho.sol +++ b/contracts/compound/interfaces/IMorpho.sol @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity ^0.8.0; - +pragma solidity >=0.5.0; import "./IInterestRatesManager.sol"; import "./IPositionsManager.sol"; import "./IRewardsManager.sol"; diff --git a/contracts/compound/interfaces/IOracle.sol b/contracts/compound/interfaces/IOracle.sol index 22f465867..5025c0f44 100644 --- a/contracts/compound/interfaces/IOracle.sol +++ b/contracts/compound/interfaces/IOracle.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity ^0.8.0; +pragma solidity >=0.5.0; interface IOracle { function consult(uint256 _amountIn) external returns (uint256); diff --git a/contracts/compound/interfaces/IPositionsManager.sol b/contracts/compound/interfaces/IPositionsManager.sol index 448dc1466..60491dbb4 100644 --- a/contracts/compound/interfaces/IPositionsManager.sol +++ b/contracts/compound/interfaces/IPositionsManager.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity ^0.8.0; +pragma solidity >=0.5.0; interface IPositionsManager { function supplyLogic( diff --git a/contracts/compound/interfaces/IRewardsManager.sol b/contracts/compound/interfaces/IRewardsManager.sol index 261078b18..a2321a50c 100644 --- a/contracts/compound/interfaces/IRewardsManager.sol +++ b/contracts/compound/interfaces/IRewardsManager.sol @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity ^0.8.0; - +pragma solidity >=0.5.0; import "./compound/ICompound.sol"; interface IRewardsManager { diff --git a/contracts/compound/interfaces/IWETH.sol b/contracts/compound/interfaces/IWETH.sol index e82bff47e..e52ad177c 100644 --- a/contracts/compound/interfaces/IWETH.sol +++ b/contracts/compound/interfaces/IWETH.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity ^0.8.0; +pragma solidity >=0.5.0; interface IWETH { function deposit() external payable; diff --git a/contracts/compound/interfaces/compound/ICompound.sol b/contracts/compound/interfaces/compound/ICompound.sol index 6f7678880..92154b81e 100644 --- a/contracts/compound/interfaces/compound/ICompound.sol +++ b/contracts/compound/interfaces/compound/ICompound.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity ^0.8.0; +pragma solidity >=0.5.0; interface ICEth { function accrueInterest() external returns (uint256); diff --git a/hardhat.config.ts b/hardhat.config.ts index 05393d5fd..6fa27321b 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -22,11 +22,14 @@ const config: HardhatUserConfig = { networks: { hardhat: { forking: { - enabled: true, - url: `https://${process.env.NETWORK}.g.alchemy.com/v2/${process.env.ALCHEMY_KEY}`, - blockNumber: Number(process.env.BLOCK_NUMBER ?? 15_500_000), + url: `https://${process.env.NETWORK || "eth-mainnet"}.g.alchemy.com/v2/${process.env.ALCHEMY_KEY}`, + blockNumber: Number(process.env.BLOCK_NUMBER || 15_500_000), }, }, + mainnet: { + url: `https://eth-mainnet.g.alchemy.com/v2/${process.env.ALCHEMY_KEY}`, + chainId: 1, + }, }, preprocess: { eachLine: () => ({ @@ -37,9 +40,6 @@ const config: HardhatUserConfig = { }, }), }, - paths: { - sources: "./contracts/", - }, solidity: { compilers: [ { @@ -62,6 +62,9 @@ const config: HardhatUserConfig = { }, ], }, + etherscan: { + apiKey: process.env.ETHERSCAN_API_KEY, + }, }; export default config; diff --git a/package.json b/package.json index c2dac63aa..14da167f1 100644 --- a/package.json +++ b/package.json @@ -3,8 +3,8 @@ "version": "1.0.0", "description": "Core contracts of the Morpho Protocol V1.", "scripts": { - "test": "NETWORK=eth-mainnet hardhat test test/*.spec.ts", - "test:upgrade:stEth": "NETWORK=eth-mainnet BLOCK_NUMBER=15580517 hardhat test test/upgrades/stEth.spec.ts", + "test": "hardhat test test/*.spec.ts", + "test:upgrade:stEth": "BLOCK_NUMBER=15580517 hardhat test test/upgrades/stEth.spec.ts", "lint": "yarn lint:sol && yarn lint:ts", "lint:ts": "eslint . --ext .ts", "lint:sol": "solhint 'contracts/**/*.sol'", diff --git a/scripts/storage-layout.sh b/scripts/storage-layout.sh index ea55ee815..9ccf908f0 100755 --- a/scripts/storage-layout.sh +++ b/scripts/storage-layout.sh @@ -47,4 +47,4 @@ elif [[ $func == "generate" ]]; then else echo "Unknown command. Use 'generate' or 'check' as the first argument." exit 1 -fi \ No newline at end of file +fi diff --git a/test-foundry/aave-v2/TestBitmask.t.sol b/test-foundry/aave-v2/TestBitmask.t.sol index bfe443124..322f1e934 100644 --- a/test-foundry/aave-v2/TestBitmask.t.sol +++ b/test-foundry/aave-v2/TestBitmask.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/aave-v2/TestBorrow.t.sol b/test-foundry/aave-v2/TestBorrow.t.sol index cade0955d..581cb6e7a 100644 --- a/test-foundry/aave-v2/TestBorrow.t.sol +++ b/test-foundry/aave-v2/TestBorrow.t.sol @@ -1,10 +1,11 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; contract TestBorrow is TestSetup { using ReserveConfiguration for DataTypes.ReserveConfigurationMap; + using WadRayMath for uint256; // The borrower tries to borrow more than his collateral allows, the transaction reverts. function testBorrow1() public { @@ -29,8 +30,7 @@ contract TestBorrow is TestSetup { (uint256 inP2P, uint256 onPool) = morpho.borrowBalanceInOf(aDai, address(borrower1)); - uint256 normalizedVariableDebt = pool.getReserveNormalizedVariableDebt(dai); - uint256 expectedOnPool = underlyingToAdUnit(amount, normalizedVariableDebt); + uint256 expectedOnPool = amount.rayDiv(pool.getReserveNormalizedVariableDebt(dai)); testEquality(onPool, expectedOnPool); testEquality(inP2P, 0); @@ -50,9 +50,9 @@ contract TestBorrow is TestSetup { (uint256 supplyInP2P, ) = morpho.supplyBalanceInOf(aDai, address(supplier1)); uint256 p2pBorrowIndex = morpho.p2pBorrowIndex(aDai); - uint256 expectedInP2P = p2pUnitToUnderlying(supplyInP2P, p2pBorrowIndex); + uint256 expectedInP2PInUnderlying = supplyInP2P.rayMul(p2pBorrowIndex); - testEquality(expectedInP2P, amount); + testEquality(amount, expectedInP2PInUnderlying); (uint256 inP2P, uint256 onPool) = morpho.borrowBalanceInOf(aDai, address(borrower1)); @@ -78,8 +78,7 @@ contract TestBorrow is TestSetup { testEquality(inP2P, supplyInP2P, "in P2P"); - uint256 normalizedVariableDebt = pool.getReserveNormalizedVariableDebt(dai); - uint256 expectedOnPool = underlyingToAdUnit(amount, normalizedVariableDebt); + uint256 expectedOnPool = amount.rayDiv(pool.getReserveNormalizedVariableDebt(dai)); testEquality(onPool, expectedOnPool, "on pool"); } @@ -121,7 +120,7 @@ contract TestBorrow is TestSetup { for (uint256 i = 0; i < NMAX; i++) { (inP2P, onPool) = morpho.supplyBalanceInOf(aDai, address(suppliers[i])); - expectedInP2P = p2pUnitToUnderlying(inP2P, p2pSupplyIndex); + expectedInP2P = inP2P.rayMul(p2pSupplyIndex); testEquality(expectedInP2P, amountPerSupplier); testEquality(onPool, 0); @@ -131,7 +130,7 @@ contract TestBorrow is TestSetup { testEquality( inP2P, - underlyingToP2PUnit(amount, morpho.p2pBorrowIndex(aDai)), + amount.rayDiv(morpho.p2pBorrowIndex(aDai)), "Borrower1 in peer-to-peer" ); testEquality(onPool, 0, "Borrower1 on pool"); @@ -175,7 +174,7 @@ contract TestBorrow is TestSetup { for (uint256 i = 0; i < NMAX; i++) { (inP2P, onPool) = morpho.supplyBalanceInOf(aDai, address(suppliers[i])); - expectedInP2P = p2pUnitToUnderlying(inP2P, p2pSupplyIndex); + expectedInP2P = inP2P.rayMul(p2pSupplyIndex); testEquality(expectedInP2P, amountPerSupplier, "on pool"); testEquality(onPool, 0); @@ -183,8 +182,8 @@ contract TestBorrow is TestSetup { (inP2P, onPool) = morpho.borrowBalanceInOf(aDai, address(borrower1)); - expectedInP2P = underlyingToP2PUnit(amount / 2, morpho.p2pBorrowIndex(aDai)); - uint256 expectedOnPool = underlyingToAdUnit(amount / 2, normalizedVariableDebt); + expectedInP2P = (amount / 2).rayDiv(morpho.p2pBorrowIndex(aDai)); + uint256 expectedOnPool = (amount / 2).rayDiv(normalizedVariableDebt); testEquality(inP2P, expectedInP2P, "Borrower1 in peer-to-peer"); testEquality(onPool, expectedOnPool, "Borrower1 on pool"); @@ -202,7 +201,7 @@ contract TestBorrow is TestSetup { (, uint256 onPool) = morpho.borrowBalanceInOf(aDai, address(borrower1)); uint256 normalizedVariableDebt = pool.getReserveNormalizedVariableDebt(dai); - uint256 expectedOnPool = underlyingToAdUnit(2 * amount, normalizedVariableDebt); + uint256 expectedOnPool = (2 * amount).rayDiv(normalizedVariableDebt); testEquality(onPool, expectedOnPool); } diff --git a/test-foundry/aave-v2/TestFees.t.sol b/test-foundry/aave-v2/TestFees.t.sol index 72cc5771b..d6496bc22 100644 --- a/test-foundry/aave-v2/TestFees.t.sol +++ b/test-foundry/aave-v2/TestFees.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/aave-v2/TestGovernance.t.sol b/test-foundry/aave-v2/TestGovernance.t.sol index a53713658..017367573 100644 --- a/test-foundry/aave-v2/TestGovernance.t.sol +++ b/test-foundry/aave-v2/TestGovernance.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/aave-v2/TestIncentivesVault.t.sol b/test-foundry/aave-v2/TestIncentivesVault.t.sol index 7f31fb83a..5f6b9ef8a 100644 --- a/test-foundry/aave-v2/TestIncentivesVault.t.sol +++ b/test-foundry/aave-v2/TestIncentivesVault.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/aave-v2/TestInterestRates.t.sol b/test-foundry/aave-v2/TestInterestRates.t.sol index b4244ef36..15e28af24 100644 --- a/test-foundry/aave-v2/TestInterestRates.t.sol +++ b/test-foundry/aave-v2/TestInterestRates.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "@contracts/aave-v2/InterestRatesManager.sol"; import "@forge-std/Test.sol"; diff --git a/test-foundry/aave-v2/TestLens.t.sol b/test-foundry/aave-v2/TestLens.t.sol index c87e48b40..af22e8f0d 100644 --- a/test-foundry/aave-v2/TestLens.t.sol +++ b/test-foundry/aave-v2/TestLens.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "@contracts/aave-v2/interfaces/lido/ILido.sol"; diff --git a/test-foundry/aave-v2/TestLiquidate.t.sol b/test-foundry/aave-v2/TestLiquidate.t.sol index 11e945c02..ed38f1b57 100644 --- a/test-foundry/aave-v2/TestLiquidate.t.sol +++ b/test-foundry/aave-v2/TestLiquidate.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; @@ -53,8 +53,7 @@ contract TestLiquidate is TestSetup { aDai, address(borrower1) ); - uint256 expectedBorrowBalanceOnPool = aDUnitToUnderlying( - onPoolBorrower, + uint256 expectedBorrowBalanceOnPool = onPoolBorrower.rayMul( pool.getReserveNormalizedVariableDebt(dai) ); testEquality(expectedBorrowBalanceOnPool, toRepay); @@ -82,8 +81,7 @@ contract TestLiquidate is TestSetup { vars.liquidationBonus) / (vars.borrowedTokenUnit * collateralPrice * 10_000); uint256 normalizedIncome = pool.getReserveNormalizedIncome(usdc); - uint256 expectedOnPool = collateralOnPool - - underlyingToScaledBalance(amountToSeize, normalizedIncome); + uint256 expectedOnPool = collateralOnPool - amountToSeize.rayDiv(normalizedIncome); testEquality(onPoolBorrower, expectedOnPool); assertEq(inP2PBorrower, 0); @@ -128,16 +126,15 @@ contract TestLiquidate is TestSetup { address(borrower1) ); - uint256 expectedBorrowBalanceInP2P = aDUnitToUnderlying( - onPoolUsdc, + uint256 expectedBorrowBalanceInP2P = onPoolUsdc.rayMul( pool.getReserveNormalizedVariableDebt(usdc) ) + - p2pUnitToUnderlying(inP2PUsdc, morpho.p2pBorrowIndex(aUsdc)) - + inP2PUsdc.rayMul(morpho.p2pBorrowIndex(aUsdc)) - toRepay; assertApproxEqAbs(onPoolBorrower, 0, 1, "borrower borrow on pool"); assertApproxEqAbs( - p2pUnitToUnderlying(inP2PBorrower, morpho.p2pBorrowIndex(aUsdc)), + inP2PBorrower.rayMul(morpho.p2pBorrowIndex(aUsdc)), expectedBorrowBalanceInP2P, 1, "borrower borrow in peer-to-peer" @@ -164,8 +161,7 @@ contract TestLiquidate is TestSetup { assertApproxEqAbs( onPoolBorrower, - onPoolDai - - underlyingToScaledBalance(amountToSeize, pool.getReserveNormalizedIncome(dai)), + onPoolDai - amountToSeize.rayDiv(pool.getReserveNormalizedIncome(dai)), 1, "borrower supply on pool" ); @@ -210,13 +206,12 @@ contract TestLiquidate is TestSetup { address(borrower1) ); - uint256 expectedBorrowBalanceOnPool = aDUnitToUnderlying( - onPoolUsdc, + uint256 expectedBorrowBalanceOnPool = onPoolUsdc.rayMul( pool.getReserveNormalizedVariableDebt(usdc) ) - toRepay; assertApproxEqAbs( - aDUnitToUnderlying(onPoolBorrower, pool.getReserveNormalizedVariableDebt(usdc)), + onPoolBorrower.rayMul(pool.getReserveNormalizedVariableDebt(usdc)), expectedBorrowBalanceOnPool, 1, "borrower borrow on pool" @@ -245,8 +240,7 @@ contract TestLiquidate is TestSetup { testEquality( onPoolBorrower, - onPoolDai - - underlyingToScaledBalance(amountToSeize, pool.getReserveNormalizedIncome(dai)), + onPoolDai - amountToSeize.rayDiv(pool.getReserveNormalizedIncome(dai)), "borrower supply on pool" ); assertEq(inP2PBorrower, inP2PDai, "borrower supply in peer-to-peer"); diff --git a/test-foundry/aave-v2/TestMarketMember.t.sol b/test-foundry/aave-v2/TestMarketMember.t.sol index e0ef96642..0d1813d6f 100644 --- a/test-foundry/aave-v2/TestMarketMember.t.sol +++ b/test-foundry/aave-v2/TestMarketMember.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/aave-v2/TestMarketStrategy.t.sol b/test-foundry/aave-v2/TestMarketStrategy.t.sol index 55cd20409..8cdc1bcea 100644 --- a/test-foundry/aave-v2/TestMarketStrategy.t.sol +++ b/test-foundry/aave-v2/TestMarketStrategy.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/aave-v2/TestMorphoGetters.t.sol b/test-foundry/aave-v2/TestMorphoGetters.t.sol index 46774c701..3b1bc811b 100644 --- a/test-foundry/aave-v2/TestMorphoGetters.t.sol +++ b/test-foundry/aave-v2/TestMorphoGetters.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/aave-v2/TestP2PDisable.t.sol b/test-foundry/aave-v2/TestP2PDisable.t.sol index f2689b2c3..fd145dfe5 100644 --- a/test-foundry/aave-v2/TestP2PDisable.t.sol +++ b/test-foundry/aave-v2/TestP2PDisable.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/aave-v2/TestPausableMarket.t.sol b/test-foundry/aave-v2/TestPausableMarket.t.sol index eb6b9aa3c..a7d177a6c 100644 --- a/test-foundry/aave-v2/TestPausableMarket.t.sol +++ b/test-foundry/aave-v2/TestPausableMarket.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/aave-v2/TestPublicFunctions.t.sol b/test-foundry/aave-v2/TestPublicFunctions.t.sol index e99c0c9e7..b4ff843cb 100644 --- a/test-foundry/aave-v2/TestPublicFunctions.t.sol +++ b/test-foundry/aave-v2/TestPublicFunctions.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/aave-v2/TestRepay.t.sol b/test-foundry/aave-v2/TestRepay.t.sol index 08d6111b5..38b15f709 100644 --- a/test-foundry/aave-v2/TestRepay.t.sol +++ b/test-foundry/aave-v2/TestRepay.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; @@ -69,10 +69,7 @@ contract TestRepay is TestSetup { address(supplier1) ); - uint256 expectedOnPool = underlyingToAdUnit( - suppliedAmount, - pool.getReserveNormalizedVariableDebt(dai) - ); + uint256 expectedOnPool = suppliedAmount.rayDiv(pool.getReserveNormalizedVariableDebt(dai)); testEquality(onPoolSupplier, 0, "supplier on pool"); testEquality(onPoolBorrower1, expectedOnPool, "borrower on pool"); @@ -94,10 +91,7 @@ contract TestRepay is TestSetup { (uint256 inP2PAvailableBorrower, uint256 onPoolAvailableBorrower) = morpho .borrowBalanceInOf(aDai, address(borrower2)); uint256 p2pBorrowIndex = morpho.p2pBorrowIndex(aDai); - uint256 expectedBorrowBalanceInP2P = underlyingToP2PUnit( - (25 * borrowedAmount) / 100, - p2pBorrowIndex - ); + uint256 expectedBorrowBalanceInP2P = ((25 * borrowedAmount) / 100).rayDiv(p2pBorrowIndex); testEquality(inP2PBorrower1, inP2PAvailableBorrower); testEquality(inP2PBorrower1, expectedBorrowBalanceInP2P); @@ -142,37 +136,32 @@ contract TestRepay is TestSetup { address(supplier1) ); - uint256 expectedOnPool = underlyingToAdUnit( - suppliedAmount, - pool.getReserveNormalizedVariableDebt(dai) - ); - testEquality(onPoolSupplier, 0); - testEquality(onPoolBorrower1, expectedOnPool); + testEquality( + onPoolBorrower1, + suppliedAmount.rayDiv(pool.getReserveNormalizedVariableDebt(dai)) + ); testEquality(inP2PSupplier, inP2PBorrower1); // NMAX borrowers have debt waiting on pool uint256 NMAX = 20; createSigners(NMAX); - uint256 inP2P; - uint256 onPool; uint256 normalizedVariableDebt = pool.getReserveNormalizedVariableDebt(dai); - + // Minus because borrower1 must not be counted twice ! uint256 amountPerBorrower = (borrowedAmount - suppliedAmount) / (NMAX - 1); - // minus because borrower1 must not be counted twice ! - for (uint256 i = 0; i < NMAX; i++) { + + for (uint256 i; i < NMAX; i++) { if (borrowers[i] == borrower1) continue; borrowers[i].approve(usdc, to6Decimals(collateral)); borrowers[i].supply(aUsdc, to6Decimals(collateral)); borrowers[i].borrow(aDai, amountPerBorrower); - (inP2P, onPool) = morpho.borrowBalanceInOf(aDai, address(borrowers[i])); - expectedOnPool = underlyingToAdUnit(amountPerBorrower, normalizedVariableDebt); + (uint256 inP2P, uint256 onPool) = morpho.borrowBalanceInOf(aDai, address(borrowers[i])); testEquality(inP2P, 0); - testEquality(onPool, expectedOnPool); + testEquality(onPool, amountPerBorrower.rayDiv(normalizedVariableDebt)); } // Borrower1 repays all of his debt @@ -189,19 +178,17 @@ contract TestRepay is TestSetup { (inP2PSupplier, onPoolSupplier) = morpho.supplyBalanceInOf(aDai, address(supplier1)); uint256 p2pBorrowIndex = morpho.p2pBorrowIndex(aDai); - uint256 expectedSupplyBalanceInP2P = underlyingToP2PUnit(suppliedAmount, p2pBorrowIndex); - testEquality(inP2PSupplier, expectedSupplyBalanceInP2P); + testEquality(inP2PSupplier, suppliedAmount.rayDiv(p2pBorrowIndex)); testEquality(onPoolSupplier, 0); // Now test for each individual borrower that replaced the original - for (uint256 i = 0; i < borrowers.length; i++) { + for (uint256 i; i < borrowers.length; i++) { if (borrowers[i] == borrower1) continue; - (inP2P, onPool) = morpho.borrowBalanceInOf(aDai, address(borrowers[i])); - uint256 expectedInP2P = p2pUnitToUnderlying(inP2P, p2pBorrowIndex); + (uint256 inP2P, uint256 onPool) = morpho.borrowBalanceInOf(aDai, address(borrowers[i])); - testEquality(expectedInP2P, amountPerBorrower); + testEquality(amountPerBorrower, inP2P.rayMul(p2pBorrowIndex)); testEquality(onPool, 0); } } @@ -231,10 +218,7 @@ contract TestRepay is TestSetup { address(supplier1) ); - uint256 expectedOnPool = underlyingToAdUnit( - suppliedAmount, - pool.getReserveNormalizedVariableDebt(dai) - ); + uint256 expectedOnPool = suppliedAmount.rayDiv(pool.getReserveNormalizedVariableDebt(dai)); testEquality(onPoolSupplier, 0); testEquality(onPoolBorrower1, expectedOnPool); @@ -250,10 +234,7 @@ contract TestRepay is TestSetup { uint256 normalizedIncome = pool.getReserveNormalizedIncome(dai); uint256 p2pBorrowIndex = morpho.p2pBorrowIndex(aDai); - uint256 expectedBorrowBalanceInP2P = underlyingToP2PUnit( - (25 * borrowedAmount) / 100, - p2pBorrowIndex - ); + uint256 expectedBorrowBalanceInP2P = ((25 * borrowedAmount) / 100).rayDiv(p2pBorrowIndex); testEquality(inP2PBorrower1, expectedBorrowBalanceInP2P); testEquality(onPoolBorrower1, 0); @@ -261,14 +242,8 @@ contract TestRepay is TestSetup { // Check balances for supplier (inP2PSupplier, onPoolSupplier) = morpho.supplyBalanceInOf(aDai, address(supplier1)); - uint256 expectedSupplyBalanceInP2P = underlyingToP2PUnit( - suppliedAmount / 2, - p2pBorrowIndex - ); - uint256 expectedSupplyBalanceOnPool = underlyingToAdUnit( - suppliedAmount / 2, - normalizedIncome - ); + uint256 expectedSupplyBalanceInP2P = (suppliedAmount / 2).rayDiv(p2pBorrowIndex); + uint256 expectedSupplyBalanceOnPool = (suppliedAmount / 2).rayDiv(normalizedIncome); testEquality(inP2PSupplier, expectedSupplyBalanceInP2P); testEquality(onPoolSupplier, expectedSupplyBalanceOnPool); @@ -306,13 +281,11 @@ contract TestRepay is TestSetup { address(supplier1) ); - uint256 expectedOnPool = underlyingToAdUnit( - suppliedAmount, - pool.getReserveNormalizedVariableDebt(dai) - ); - testEquality(onPoolSupplier, 0); - testEquality(onPoolBorrower1, expectedOnPool); + testEquality( + onPoolBorrower1, + suppliedAmount.rayDiv(pool.getReserveNormalizedVariableDebt(dai)) + ); testEquality(inP2PSupplier, inP2PBorrower1); // NMAX borrowers have borrowerAmount/2 (cumulated) of debt waiting on pool @@ -343,28 +316,21 @@ contract TestRepay is TestSetup { (inP2PSupplier, onPoolSupplier) = morpho.supplyBalanceInOf(aDai, address(supplier1)); uint256 p2pBorrowIndex = morpho.p2pBorrowIndex(aDai); - uint256 normalizedIncome = pool.getReserveNormalizedIncome(dai); - uint256 expectedSupplyBalanceOnPool = underlyingToP2PUnit( - suppliedAmount / 2, - normalizedIncome + testEquality(inP2PSupplier, (suppliedAmount / 2).rayDiv(p2pBorrowIndex)); + testEquality( + onPoolSupplier, + (suppliedAmount / 2).rayDiv(pool.getReserveNormalizedIncome(dai)) ); - uint256 expectedSupplyBalanceInP2P = underlyingToAdUnit(suppliedAmount / 2, p2pBorrowIndex); - - testEquality(inP2PSupplier, expectedSupplyBalanceInP2P); - testEquality(onPoolSupplier, expectedSupplyBalanceOnPool); - - uint256 inP2P; - uint256 onPool; // Now test for each individual borrower that replaced the original - for (uint256 i = 0; i < borrowers.length; i++) { + for (uint256 i; i < borrowers.length; i++) { if (borrowers[i] == borrower1) continue; - (inP2P, onPool) = morpho.borrowBalanceInOf(aDai, address(borrowers[i])); - uint256 expectedInP2P = p2pUnitToUnderlying(inP2P, p2pBorrowIndex); + (uint256 inP2P, uint256 onPool) = morpho.borrowBalanceInOf(aDai, address(borrowers[i])); + uint256 expectedInP2P = inP2P.rayMul(p2pBorrowIndex); - testEquality(expectedInP2P, amountPerBorrower); + testEquality(amountPerBorrower, expectedInP2P); testEquality(onPool, 0); } } @@ -403,7 +369,7 @@ contract TestRepay is TestSetup { { uint256 p2pBorrowIndex = morpho.p2pBorrowIndex(aDai); - expectedBorrowBalanceInP2P = underlyingToP2PUnit(borrowedAmount, p2pBorrowIndex); + expectedBorrowBalanceInP2P = borrowedAmount.rayDiv(p2pBorrowIndex); // Check balances after match of supplier1 (uint256 inP2PBorrower, uint256 onPoolBorrower) = morpho.borrowBalanceInOf( @@ -414,10 +380,7 @@ contract TestRepay is TestSetup { assertApproxEqAbs(inP2PBorrower, expectedBorrowBalanceInP2P, 1e3); uint256 p2pSupplyIndex = morpho.p2pSupplyIndex(aDai); - uint256 expectedSupplyBalanceInP2P = underlyingToP2PUnit( - suppliedAmount, - p2pSupplyIndex - ); + uint256 expectedSupplyBalanceInP2P = suppliedAmount.rayDiv(p2pSupplyIndex); for (uint256 i = 0; i < 20; i++) { (uint256 inP2PSupplier, uint256 onPoolSupplier) = morpho.supplyBalanceInOf( @@ -443,8 +406,7 @@ contract TestRepay is TestSetup { // There should be a delta uint256 expectedSupplyP2PDeltaInUnderlying = 10 * suppliedAmount; - uint256 expectedSupplyP2PDelta = underlyingToScaledBalance( - expectedSupplyP2PDeltaInUnderlying, + uint256 expectedSupplyP2PDelta = expectedSupplyP2PDeltaInUnderlying.rayDiv( pool.getReserveNormalizedIncome(dai) ); (uint256 supplyP2PDelta, , , ) = morpho.deltas(aDai); @@ -456,8 +418,7 @@ contract TestRepay is TestSetup { borrower2.borrow(aDai, expectedSupplyP2PDeltaInUnderlying / 2); (inP2PBorrower, onPoolBorrower) = morpho.borrowBalanceInOf(aDai, address(borrower2)); - expectedBorrowBalanceInP2P = underlyingToP2PUnit( - expectedSupplyP2PDeltaInUnderlying / 2, + expectedBorrowBalanceInP2P = (expectedSupplyP2PDeltaInUnderlying / 2).rayDiv( p2pBorrowIndex ); @@ -519,7 +480,7 @@ contract TestRepay is TestSetup { address(suppliers[i]) ); assertApproxEqAbs( - p2pUnitToUnderlying(inP2PSupplier, newVars.SP2PER), + inP2PSupplier.rayMul(newVars.SP2PER), expectedSupplyBalanceInUnderlying, (expectedSupplyBalanceInUnderlying * 2) / 100, "not expected balance peer-to-peer" diff --git a/test-foundry/aave-v2/TestRewards.t.sol b/test-foundry/aave-v2/TestRewards.t.sol index 8007a9fd3..a318c37df 100644 --- a/test-foundry/aave-v2/TestRewards.t.sol +++ b/test-foundry/aave-v2/TestRewards.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/aave-v2/TestSupply.t.sol b/test-foundry/aave-v2/TestSupply.t.sol index 2bb82d17a..c5125b841 100644 --- a/test-foundry/aave-v2/TestSupply.t.sol +++ b/test-foundry/aave-v2/TestSupply.t.sol @@ -1,11 +1,12 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; import "./helpers/FlashLoan.sol"; contract TestSupply is TestSetup { using stdStorage for StdStorage; + using WadRayMath for uint256; // There are no available borrowers: all of the supplied amount is supplied to the pool and set `onPool`. function testSupply1() public { @@ -15,7 +16,7 @@ contract TestSupply is TestSetup { supplier1.supply(aDai, amount); uint256 normalizedIncome = pool.getReserveNormalizedIncome(dai); - uint256 expectedOnPool = underlyingToScaledBalance(amount, normalizedIncome); + uint256 expectedOnPool = amount.rayDiv(normalizedIncome); testEquality(IERC20(aDai).balanceOf(address(morpho)), amount); @@ -43,7 +44,7 @@ contract TestSupply is TestSetup { testEquality(daiBalanceAfter, expectedDaiBalanceAfter); uint256 p2pSupplyIndex = morpho.p2pSupplyIndex(aDai); - uint256 expectedSupplyBalanceInP2P = underlyingToP2PUnit(amount, p2pSupplyIndex); + uint256 expectedSupplyBalanceInP2P = amount.rayDiv(p2pSupplyIndex); (uint256 inP2PSupplier, uint256 onPoolSupplier) = morpho.supplyBalanceInOf( aDai, @@ -74,10 +75,10 @@ contract TestSupply is TestSetup { supplier1.supply(aDai, 2 * amount); uint256 p2pSupplyIndex = morpho.p2pSupplyIndex(aDai); - uint256 expectedSupplyBalanceInP2P = underlyingToP2PUnit(amount, p2pSupplyIndex); + uint256 expectedSupplyBalanceInP2P = amount.rayDiv(p2pSupplyIndex); uint256 normalizedIncome = pool.getReserveNormalizedIncome(dai); - uint256 expectedSupplyBalanceOnPool = underlyingToScaledBalance(amount, normalizedIncome); + uint256 expectedSupplyBalanceOnPool = amount.rayDiv(normalizedIncome); (uint256 inP2PSupplier, uint256 onPoolSupplier) = morpho.supplyBalanceInOf( aDai, @@ -129,14 +130,14 @@ contract TestSupply is TestSetup { for (uint256 i = 0; i < NMAX; i++) { (inP2P, onPool) = morpho.borrowBalanceInOf(aDai, address(borrowers[i])); - expectedInP2PInUnderlying = p2pUnitToUnderlying(inP2P, p2pSupplyIndex); + expectedInP2PInUnderlying = inP2P.rayMul(p2pSupplyIndex); testEquality(expectedInP2PInUnderlying, amountPerBorrower, "amount per borrower"); testEquality(onPool, 0, "on pool per borrower"); } (inP2P, onPool) = morpho.supplyBalanceInOf(aDai, address(supplier1)); - uint256 expectedInP2P = underlyingToP2PUnit(amount, morpho.p2pBorrowIndex(aDai)); + uint256 expectedInP2P = amount.rayDiv(morpho.p2pBorrowIndex(aDai)); testEquality(inP2P, expectedInP2P); testEquality(onPool, 0); @@ -178,7 +179,7 @@ contract TestSupply is TestSetup { for (uint256 i = 0; i < NMAX; i++) { (inP2P, onPool) = morpho.borrowBalanceInOf(aDai, address(borrowers[i])); - expectedInP2PInUnderlying = p2pUnitToUnderlying(inP2P, p2pBorrowIndex); + expectedInP2PInUnderlying = inP2P.rayMul(p2pBorrowIndex); testEquality(expectedInP2PInUnderlying, amountPerBorrower, "borrower in peer-to-peer"); testEquality(onPool, 0); @@ -186,8 +187,8 @@ contract TestSupply is TestSetup { (inP2P, onPool) = morpho.supplyBalanceInOf(aDai, address(supplier1)); - uint256 expectedInP2P = underlyingToP2PUnit(amount / 2, morpho.p2pSupplyIndex(aDai)); - uint256 expectedOnPool = underlyingToAdUnit(amount / 2, normalizedIncome); + uint256 expectedInP2P = (amount / 2).rayDiv(morpho.p2pSupplyIndex(aDai)); + uint256 expectedOnPool = (amount / 2).rayDiv(normalizedIncome); testEquality(inP2P, expectedInP2P, "in peer-to-peer"); testEquality(onPool, expectedOnPool, "in pool"); @@ -202,7 +203,7 @@ contract TestSupply is TestSetup { supplier1.supply(aDai, amount); uint256 normalizedIncome = pool.getReserveNormalizedIncome(dai); - uint256 expectedOnPool = underlyingToScaledBalance(2 * amount, normalizedIncome); + uint256 expectedOnPool = (2 * amount).rayDiv(normalizedIncome); (, uint256 onPool) = morpho.supplyBalanceInOf(aDai, address(supplier1)); testEquality(onPool, expectedOnPool); @@ -238,7 +239,7 @@ contract TestSupply is TestSetup { morpho.supply(aDai, address(supplier2), amount); uint256 poolSupplyIndex = pool.getReserveNormalizedIncome(dai); - uint256 expectedOnPool = underlyingToScaledBalance(amount, poolSupplyIndex); + uint256 expectedOnPool = amount.rayDiv(poolSupplyIndex); assertEq(ERC20(aDai).balanceOf(address(morpho)), amount, "balance of aToken"); @@ -262,4 +263,47 @@ contract TestSupply is TestSetup { vm.warp(block.timestamp + 1); supplier1.supply(aDai, amount); } + + function testAStakedEthShouldAccrueInterest() public { + createMarket(aStEth); + + deal(address(supplier1), 1_000 ether); + uint256 totalEthBalance = address(supplier1).balance; + uint256 totalBalance = totalEthBalance / 2; + vm.prank(address(supplier1)); + ILido(stEth).submit{value: totalBalance}(address(0)); + totalBalance = ERC20(stEth).balanceOf(address(supplier1)); + + // Handle roundings. + vm.prank(address(supplier1)); + ERC20(stEth).transfer(address(morpho), 100); + + uint256 deposited = totalBalance / 2; + supplier1.approve(stEth, type(uint256).max); + supplier1.supply(aStEth, deposited); + + // Update the beacon balance to accrue rewards on the stETH token. + // bytes32 internal constant BEACON_BALANCE_POSITION = keccak256("lido.Lido.beaconBalance"); + uint256 beaconBalanceBefore = uint256(vm.load(stEth, keccak256("lido.Lido.beaconBalance"))); + vm.store( + stEth, + keccak256("lido.Lido.beaconBalance"), + bytes32(beaconBalanceBefore + 10_000 ether) + ); + uint256 beaconBalanceAfter = uint256(vm.load(stEth, keccak256("lido.Lido.beaconBalance"))); + assertGt(beaconBalanceAfter, beaconBalanceBefore); + + // Update timestamp to update indexes. + vm.warp(block.timestamp + 1); + + uint256 balanceBeforeWithdraw = ERC20(stEth).balanceOf(address(supplier1)); + uint256 aTokenBalance = ERC20(aStEth).balanceOf(address(morpho)); + supplier1.withdraw(aStEth, type(uint256).max); + uint256 balanceAfterWithdraw = ERC20(stEth).balanceOf(address(supplier1)); + uint256 withdrawn = balanceAfterWithdraw - balanceBeforeWithdraw; + + // Rewards should accrue on stETH even if there's is no supply interest rate on Aave. + assertGt(withdrawn, deposited); + assertApproxEqAbs(withdrawn, aTokenBalance, 1); + } } diff --git a/test-foundry/aave-v2/TestUpgradeable.t.sol b/test-foundry/aave-v2/TestUpgradeable.t.sol index a7bbb509f..9a5b926cc 100644 --- a/test-foundry/aave-v2/TestUpgradeable.t.sol +++ b/test-foundry/aave-v2/TestUpgradeable.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/aave-v2/TestWithdraw.t.sol b/test-foundry/aave-v2/TestWithdraw.t.sol index 32e4cb96a..861c8998d 100644 --- a/test-foundry/aave-v2/TestWithdraw.t.sol +++ b/test-foundry/aave-v2/TestWithdraw.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import {Attacker} from "./helpers/Attacker.sol"; import "./setup/TestSetup.sol"; @@ -31,7 +31,7 @@ contract TestWithdraw is TestSetup { (uint256 inP2P, uint256 onPool) = morpho.supplyBalanceInOf(aUsdc, address(supplier1)); uint256 expectedOnPool = to6Decimals( - underlyingToScaledBalance(2 * amount, pool.getReserveNormalizedIncome(usdc)) + (2 * amount).rayDiv(pool.getReserveNormalizedIncome(usdc)) ); testEquality(inP2P, 0); @@ -55,9 +55,7 @@ contract TestWithdraw is TestSetup { uint256 balanceBefore = supplier1.balanceOf(usdc); (uint256 inP2P, uint256 onPool) = morpho.supplyBalanceInOf(aUsdc, address(supplier1)); - uint256 expectedOnPool = to6Decimals( - underlyingToScaledBalance(amount, pool.getReserveNormalizedIncome(usdc)) - ); + uint256 expectedOnPool = to6Decimals(amount.rayDiv(pool.getReserveNormalizedIncome(usdc))); testEquality(inP2P, 0); testEquality(onPool, expectedOnPool); @@ -96,10 +94,7 @@ contract TestWithdraw is TestSetup { address(supplier1) ); - uint256 expectedOnPool = underlyingToScaledBalance( - suppliedAmount / 2, - pool.getReserveNormalizedIncome(dai) - ); + uint256 expectedOnPool = (suppliedAmount / 2).rayDiv(pool.getReserveNormalizedIncome(dai)); testEquality(onPoolSupplier, expectedOnPool, "supplier on pool 0"); testEquality(onPoolBorrower1, 0, "borrower on pool 0"); @@ -120,7 +115,7 @@ contract TestWithdraw is TestSetup { // Check balances for supplier2 (inP2PSupplier, onPoolSupplier) = morpho.supplyBalanceInOf(aDai, address(supplier2)); uint256 p2pSupplyIndex = morpho.p2pSupplyIndex(aDai); - uint256 expectedInP2P = underlyingToP2PUnit(suppliedAmount / 2, p2pSupplyIndex); + uint256 expectedInP2P = (suppliedAmount / 2).rayDiv(p2pSupplyIndex); testEquality(onPoolSupplier, expectedOnPool, "supplier on pool 2"); testEquality(inP2PSupplier, expectedInP2P, "supplier in P2P 2"); @@ -165,10 +160,7 @@ contract TestWithdraw is TestSetup { address(supplier1) ); - uint256 expectedOnPool = underlyingToScaledBalance( - suppliedAmount / 2, - pool.getReserveNormalizedIncome(dai) - ); + uint256 expectedOnPool = (suppliedAmount / 2).rayDiv(pool.getReserveNormalizedIncome(dai)); testEquality(onPoolSupplier, expectedOnPool, "supplier on pool"); testEquality(onPoolBorrower, 0, "borrower on pool"); @@ -199,10 +191,7 @@ contract TestWithdraw is TestSetup { (inP2PBorrower, onPoolBorrower) = morpho.borrowBalanceInOf(aDai, address(borrower1)); uint256 p2pSupplyIndex = morpho.p2pSupplyIndex(aDai); - uint256 expectedBorrowBalanceInP2P = underlyingToP2PUnit( - borrowedAmount, - morpho.p2pBorrowIndex(aDai) - ); + uint256 expectedBorrowBalanceInP2P = borrowedAmount.rayDiv(morpho.p2pBorrowIndex(aDai)); testEquality(inP2PBorrower, expectedBorrowBalanceInP2P, "borrower in P2P"); testEquality(onPoolBorrower, 0, "borrower on pool"); @@ -215,7 +204,7 @@ contract TestWithdraw is TestSetup { if (suppliers[i] == supplier1) continue; (inP2P, onPool) = morpho.supplyBalanceInOf(aDai, address(suppliers[i])); - uint256 expectedInP2P = p2pUnitToUnderlying(inP2P, p2pSupplyIndex); + uint256 expectedInP2P = inP2P.rayMul(p2pSupplyIndex); testEquality(expectedInP2P, amountPerSupplier, "new supplier in P2P"); testEquality(onPool, 0, "new supplier on pool"); @@ -247,10 +236,7 @@ contract TestWithdraw is TestSetup { address(supplier1) ); - uint256 expectedOnPool = underlyingToScaledBalance( - suppliedAmount / 2, - pool.getReserveNormalizedIncome(dai) - ); + uint256 expectedOnPool = (suppliedAmount / 2).rayDiv(pool.getReserveNormalizedIncome(dai)); testEquality(onPoolSupplier, expectedOnPool, "supplier on pool"); testEquality(onPoolBorrower, 0, "borrower on pool"); @@ -263,12 +249,8 @@ contract TestWithdraw is TestSetup { (inP2PBorrower, onPoolBorrower) = morpho.borrowBalanceInOf(aDai, address(borrower1)); uint256 p2pSupplyIndex = morpho.p2pSupplyIndex(aDai); - uint256 expectedBorrowBalanceInP2P = underlyingToP2PUnit( - borrowedAmount / 2, - p2pSupplyIndex - ); - uint256 expectedBorrowBalanceOnPool = underlyingToAdUnit( - borrowedAmount / 2, + uint256 expectedBorrowBalanceInP2P = (borrowedAmount / 2).rayDiv(p2pSupplyIndex); + uint256 expectedBorrowBalanceOnPool = (borrowedAmount / 2).rayDiv( pool.getReserveNormalizedVariableDebt(dai) ); @@ -278,10 +260,7 @@ contract TestWithdraw is TestSetup { // Check balances for supplier (inP2PSupplier, onPoolSupplier) = morpho.supplyBalanceInOf(aDai, address(supplier1)); - uint256 expectedSupplyBalanceInP2P = underlyingToP2PUnit( - (25 * suppliedAmount) / 100, - p2pSupplyIndex - ); + uint256 expectedSupplyBalanceInP2P = ((25 * suppliedAmount) / 100).rayDiv(p2pSupplyIndex); testEquality(inP2PSupplier, expectedSupplyBalanceInP2P); testEquality(onPoolSupplier, 0); @@ -322,10 +301,7 @@ contract TestWithdraw is TestSetup { address(supplier1) ); - uint256 expectedOnPool = underlyingToScaledBalance( - suppliedAmount / 2, - pool.getReserveNormalizedIncome(dai) - ); + uint256 expectedOnPool = (suppliedAmount / 2).rayDiv(pool.getReserveNormalizedIncome(dai)); testEquality(onPoolSupplier, expectedOnPool); testEquality(onPoolBorrower, 0); @@ -356,12 +332,8 @@ contract TestWithdraw is TestSetup { (inP2PBorrower, onPoolBorrower) = morpho.borrowBalanceInOf(aDai, address(borrower1)); uint256 p2pSupplyIndex = morpho.p2pSupplyIndex(aDai); - uint256 expectedBorrowBalanceInP2P = underlyingToP2PUnit( - borrowedAmount / 2, - p2pSupplyIndex - ); - uint256 expectedBorrowBalanceOnPool = underlyingToAdUnit( - borrowedAmount / 2, + uint256 expectedBorrowBalanceInP2P = (borrowedAmount / 2).rayDiv(p2pSupplyIndex); + uint256 expectedBorrowBalanceOnPool = (borrowedAmount / 2).rayDiv( pool.getReserveNormalizedVariableDebt(dai) ); @@ -376,7 +348,7 @@ contract TestWithdraw is TestSetup { if (suppliers[i] == supplier1) continue; (inP2P, onPool) = morpho.supplyBalanceInOf(aDai, address(suppliers[i])); - uint256 expectedInP2P = p2pUnitToUnderlying(inP2P, p2pSupplyIndex); + uint256 expectedInP2P = inP2P.rayMul(p2pSupplyIndex); testEquality(expectedInP2P, amountPerSupplier); testEquality(onPool, 0); @@ -420,7 +392,7 @@ contract TestWithdraw is TestSetup { { uint256 p2pSupplyIndex = morpho.p2pSupplyIndex(aDai); - expectedSupplyBalanceInP2P = underlyingToP2PUnit(suppliedAmount, p2pSupplyIndex); + expectedSupplyBalanceInP2P = suppliedAmount.rayDiv(p2pSupplyIndex); // Check balances after match of supplier1 and borrowers (uint256 inP2PSupplier, uint256 onPoolSupplier) = morpho.supplyBalanceInOf( @@ -431,10 +403,7 @@ contract TestWithdraw is TestSetup { testEquality(inP2PSupplier, expectedSupplyBalanceInP2P); uint256 p2pBorrowIndex = morpho.p2pBorrowIndex(aDai); - uint256 expectedBorrowBalanceInP2P = underlyingToP2PUnit( - borrowedAmount, - p2pBorrowIndex - ); + uint256 expectedBorrowBalanceInP2P = borrowedAmount.rayDiv(p2pBorrowIndex); for (uint256 i = 10; i < 20; i++) { (uint256 inP2PBorrower, uint256 onPoolBorrower) = morpho.borrowBalanceInOf( @@ -456,8 +425,7 @@ contract TestWithdraw is TestSetup { // There should be a delta uint256 expectedBorrowP2PDeltaInUnderlying = 10 * borrowedAmount; - uint256 expectedBorrowP2PDelta = underlyingToAdUnit( - expectedBorrowP2PDeltaInUnderlying, + uint256 expectedBorrowP2PDelta = expectedBorrowP2PDeltaInUnderlying.rayDiv( pool.getReserveNormalizedVariableDebt(dai) ); @@ -469,8 +437,7 @@ contract TestWithdraw is TestSetup { supplier2.supply(aDai, expectedBorrowP2PDeltaInUnderlying / 2); (inP2PSupplier, onPoolSupplier) = morpho.supplyBalanceInOf(aDai, address(supplier2)); - expectedSupplyBalanceInP2P = underlyingToP2PUnit( - expectedBorrowP2PDeltaInUnderlying / 2, + expectedSupplyBalanceInP2P = (expectedBorrowP2PDeltaInUnderlying / 2).rayDiv( p2pSupplyIndex ); @@ -530,7 +497,7 @@ contract TestWithdraw is TestSetup { address(borrowers[i]) ); assertApproxEqAbs( - p2pUnitToUnderlying(inP2PBorrower, newVars.BP2PER), + inP2PBorrower.rayMul(newVars.BP2PER), expectedBorrowBalanceInUnderlying, (expectedBorrowBalanceInUnderlying * 2) / 100, "not expected underlying balance" diff --git a/test-foundry/aave-v2/helpers/Attacker.sol b/test-foundry/aave-v2/helpers/Attacker.sol index 205127317..406a77382 100644 --- a/test-foundry/aave-v2/helpers/Attacker.sol +++ b/test-foundry/aave-v2/helpers/Attacker.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "@contracts/aave-v2/interfaces/aave/ILendingPool.sol"; diff --git a/test-foundry/aave-v2/helpers/DumbOracle.sol b/test-foundry/aave-v2/helpers/DumbOracle.sol index e5371f1d5..480299d54 100644 --- a/test-foundry/aave-v2/helpers/DumbOracle.sol +++ b/test-foundry/aave-v2/helpers/DumbOracle.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "@contracts/aave-v2/interfaces/IOracle.sol"; diff --git a/test-foundry/aave-v2/helpers/FlashLoan.sol b/test-foundry/aave-v2/helpers/FlashLoan.sol index 9e6c48e41..71cfe6fb9 100644 --- a/test-foundry/aave-v2/helpers/FlashLoan.sol +++ b/test-foundry/aave-v2/helpers/FlashLoan.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "@contracts/aave-v2/interfaces/aave/ILendingPool.sol"; import "@rari-capital/solmate/src/utils/SafeTransferLib.sol"; diff --git a/test-foundry/aave-v2/helpers/SimplePriceOracle.sol b/test-foundry/aave-v2/helpers/SimplePriceOracle.sol index 0efa3d77f..d47b22aa6 100644 --- a/test-foundry/aave-v2/helpers/SimplePriceOracle.sol +++ b/test-foundry/aave-v2/helpers/SimplePriceOracle.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; /// Price Oracle for liquidation tests contract SimplePriceOracle { diff --git a/test-foundry/aave-v2/helpers/User.sol b/test-foundry/aave-v2/helpers/User.sol index c99c0262a..6bb9253b8 100644 --- a/test-foundry/aave-v2/helpers/User.sol +++ b/test-foundry/aave-v2/helpers/User.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "@contracts/aave-v2/interfaces/aave/ILendingPool.sol"; import "@contracts/aave-v2/interfaces/IRewardsManager.sol"; diff --git a/test-foundry/aave-v2/setup/TestSetup.sol b/test-foundry/aave-v2/setup/TestSetup.sol index 009d0d493..c23ebab64 100644 --- a/test-foundry/aave-v2/setup/TestSetup.sol +++ b/test-foundry/aave-v2/setup/TestSetup.sol @@ -1,10 +1,11 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "@contracts/aave-v2/interfaces/aave/IAaveIncentivesController.sol"; import "@contracts/aave-v2/interfaces/aave/IVariableDebtToken.sol"; import "@contracts/aave-v2/interfaces/aave/IAToken.sol"; import "@contracts/aave-v2/interfaces/IMorpho.sol"; +import "@contracts/aave-v2/interfaces/lido/ILido.sol"; import {ReserveConfiguration} from "@contracts/aave-v2/libraries/aave/ReserveConfiguration.sol"; import "@rari-capital/solmate/src/utils/SafeTransferLib.sol"; diff --git a/test-foundry/aave-v2/setup/Utils.sol b/test-foundry/aave-v2/setup/Utils.sol index f5a9a08d2..40955c100 100644 --- a/test-foundry/aave-v2/setup/Utils.sol +++ b/test-foundry/aave-v2/setup/Utils.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "@morpho-dao/morpho-utils/math/WadRayMath.sol"; @@ -24,62 +24,6 @@ contract Utils is Test { return value / 1e10; } - function underlyingToScaledBalance(uint256 _scaledBalance, uint256 _normalizedIncome) - internal - pure - returns (uint256) - { - return (_scaledBalance * RAY) / _normalizedIncome; - } - - function scaledBalanceToUnderlying(uint256 _scaledBalance, uint256 _normalizedIncome) - internal - pure - returns (uint256) - { - return (_scaledBalance * _normalizedIncome) / RAY; - } - - function underlyingToAdUnit(uint256 _underlyingAmount, uint256 _normalizedVariableDebt) - internal - pure - returns (uint256) - { - return (_underlyingAmount * RAY) / _normalizedVariableDebt; - } - - function aDUnitToUnderlying(uint256 _aDUnitAmount, uint256 _normalizedVariableDebt) - internal - pure - returns (uint256) - { - return (_aDUnitAmount * _normalizedVariableDebt) / RAY; - } - - function underlyingToP2PUnit(uint256 _underlyingAmount, uint256 _p2pExchangeRate) - internal - pure - returns (uint256) - { - return (_underlyingAmount * RAY) / _p2pExchangeRate; - } - - function p2pUnitToUnderlying(uint256 _p2pUnitAmount, uint256 _p2pExchangeRate) - internal - pure - returns (uint256) - { - return (_p2pUnitAmount * _p2pExchangeRate) / RAY; - } - - function getAbsDiff(uint256 a, uint256 b) internal pure returns (uint256) { - if (a > b) { - return a - b; - } - - return b - a; - } - function testEquality(uint256 _firstValue, uint256 _secondValue) internal { assertApproxEqAbs(_firstValue, _secondValue, 20); } diff --git a/test-foundry/aave-v3/TestBitmask.t.sol b/test-foundry/aave-v3/TestBitmask.t.sol index c7f2b031e..9b6bde831 100644 --- a/test-foundry/aave-v3/TestBitmask.t.sol +++ b/test-foundry/aave-v3/TestBitmask.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.10; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/aave-v3/TestBorrow.t.sol b/test-foundry/aave-v3/TestBorrow.t.sol index c4de8a34a..a4339624e 100644 --- a/test-foundry/aave-v3/TestBorrow.t.sol +++ b/test-foundry/aave-v3/TestBorrow.t.sol @@ -1,10 +1,11 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.10; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; contract TestBorrow is TestSetup { using ReserveConfiguration for DataTypes.ReserveConfigurationMap; + using WadRayMath for uint256; // The borrower tries to borrow more than his collateral allows, the transaction reverts. function testBorrow1() public { @@ -30,7 +31,7 @@ contract TestBorrow is TestSetup { (uint256 inP2P, uint256 onPool) = morpho.borrowBalanceInOf(aDai, address(borrower1)); uint256 normalizedVariableDebt = pool.getReserveNormalizedVariableDebt(dai); - uint256 expectedOnPool = underlyingToAdUnit(amount, normalizedVariableDebt); + uint256 expectedOnPool = amount.rayDiv(normalizedVariableDebt); testEquality(onPool, expectedOnPool); testEquality(inP2P, 0); @@ -49,10 +50,7 @@ contract TestBorrow is TestSetup { (uint256 supplyInP2P, ) = morpho.supplyBalanceInOf(aDai, address(supplier1)); - uint256 p2pBorrowIndex = morpho.p2pBorrowIndex(aDai); - uint256 expectedInP2P = p2pUnitToUnderlying(supplyInP2P, p2pBorrowIndex); - - testEquality(expectedInP2P, amount); + testEquality(supplyInP2P, amount.rayDiv(morpho.p2pSupplyIndex(aDai))); (uint256 inP2P, uint256 onPool) = morpho.borrowBalanceInOf(aDai, address(borrower1)); @@ -79,7 +77,7 @@ contract TestBorrow is TestSetup { testEquality(inP2P, supplyInP2P, "in P2P"); uint256 normalizedVariableDebt = pool.getReserveNormalizedVariableDebt(dai); - uint256 expectedOnPool = underlyingToAdUnit(amount, normalizedVariableDebt); + uint256 expectedOnPool = amount.rayDiv(normalizedVariableDebt); assertApproxEqAbs(onPool, expectedOnPool, 1e15, "on pool"); } @@ -113,14 +111,11 @@ contract TestBorrow is TestSetup { uint256 inP2P; uint256 onPool; uint256 p2pSupplyIndex = morpho.p2pSupplyIndex(aDai); - uint256 expectedInP2P; for (uint256 i = 0; i < NMAX; i++) { (inP2P, onPool) = morpho.supplyBalanceInOf(aDai, address(suppliers[i])); - expectedInP2P = p2pUnitToUnderlying(inP2P, p2pSupplyIndex); - - testEqualityLarge(expectedInP2P, amountPerSupplier); + testEqualityLarge(amountPerSupplier, inP2P.rayMul(p2pSupplyIndex)); testEqualityLarge(onPool, 0); } @@ -128,7 +123,7 @@ contract TestBorrow is TestSetup { testEquality( inP2P, - underlyingToP2PUnit(amount, morpho.p2pBorrowIndex(aDai)), + amount.rayDiv(morpho.p2pBorrowIndex(aDai)), "Borrower1 in peer-to-peer" ); testEqualityLarge(onPool, 0, "Borrower1 on pool"); @@ -172,7 +167,7 @@ contract TestBorrow is TestSetup { for (uint256 i = 0; i < NMAX; i++) { (inP2P, onPool) = morpho.supplyBalanceInOf(aDai, address(suppliers[i])); - expectedInP2P = p2pUnitToUnderlying(inP2P, p2pSupplyIndex); + expectedInP2P = inP2P.rayMul(p2pSupplyIndex); testEqualityLarge(expectedInP2P, amountPerSupplier, "on pool"); testEqualityLarge(onPool, 0, "in P2P"); @@ -180,8 +175,8 @@ contract TestBorrow is TestSetup { (inP2P, onPool) = morpho.borrowBalanceInOf(aDai, address(borrower1)); - expectedInP2P = underlyingToP2PUnit(amount / 2, morpho.p2pBorrowIndex(aDai)); - uint256 expectedOnPool = underlyingToAdUnit(amount / 2, normalizedVariableDebt); + expectedInP2P = (amount / 2).rayDiv(morpho.p2pBorrowIndex(aDai)); + uint256 expectedOnPool = (amount / 2).rayDiv(normalizedVariableDebt); testEqualityLarge(inP2P, expectedInP2P, "Borrower1 in peer-to-peer"); testEqualityLarge(onPool, expectedOnPool, "Borrower1 on pool"); @@ -199,7 +194,7 @@ contract TestBorrow is TestSetup { (, uint256 onPool) = morpho.borrowBalanceInOf(aDai, address(borrower1)); uint256 normalizedVariableDebt = pool.getReserveNormalizedVariableDebt(dai); - uint256 expectedOnPool = underlyingToAdUnit(2 * amount, normalizedVariableDebt); + uint256 expectedOnPool = (2 * amount).rayDiv(normalizedVariableDebt); testEquality(onPool, expectedOnPool); } diff --git a/test-foundry/aave-v3/TestFees.t.sol b/test-foundry/aave-v3/TestFees.t.sol index 3d49afe25..33db51345 100644 --- a/test-foundry/aave-v3/TestFees.t.sol +++ b/test-foundry/aave-v3/TestFees.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.10; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/aave-v3/TestGovernance.t.sol b/test-foundry/aave-v3/TestGovernance.t.sol index 79854fb78..62d9644e4 100644 --- a/test-foundry/aave-v3/TestGovernance.t.sol +++ b/test-foundry/aave-v3/TestGovernance.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.10; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/aave-v3/TestIncentivesVault.t.sol b/test-foundry/aave-v3/TestIncentivesVault.t.sol index 177f0f0a2..973e7e7e8 100644 --- a/test-foundry/aave-v3/TestIncentivesVault.t.sol +++ b/test-foundry/aave-v3/TestIncentivesVault.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.10; +pragma solidity ^0.8.0; import "@aave/periphery-v3/contracts/rewards/interfaces/IRewardsController.sol"; diff --git a/test-foundry/aave-v3/TestInterestRates.t.sol b/test-foundry/aave-v3/TestInterestRates.t.sol index d5334dc87..88c5baabc 100644 --- a/test-foundry/aave-v3/TestInterestRates.t.sol +++ b/test-foundry/aave-v3/TestInterestRates.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.10; +pragma solidity ^0.8.0; import "@contracts/aave-v3/InterestRatesManager.sol"; import "@forge-std/Test.sol"; diff --git a/test-foundry/aave-v3/TestLens.t.sol b/test-foundry/aave-v3/TestLens.t.sol index f078ab9c2..a91c3e60e 100644 --- a/test-foundry/aave-v3/TestLens.t.sol +++ b/test-foundry/aave-v3/TestLens.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.10; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/aave-v3/TestLiquidate.t.sol b/test-foundry/aave-v3/TestLiquidate.t.sol index 99e64a518..572cde80a 100644 --- a/test-foundry/aave-v3/TestLiquidate.t.sol +++ b/test-foundry/aave-v3/TestLiquidate.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.10; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; @@ -99,11 +99,10 @@ contract TestLiquidate is TestSetup { aDai, address(borrower1) ); - uint256 expectedBorrowBalanceOnPool = aDUnitToUnderlying( - onPoolBorrower, + uint256 borrowOnPoolInUnderlying = onPoolBorrower.rayMul( pool.getReserveNormalizedVariableDebt(dai) ); - testEqualityLarge(expectedBorrowBalanceOnPool, toRepay); + testEqualityLarge(borrowOnPoolInUnderlying, toRepay); assertEq(inP2PBorrower, 0); // Check borrower1 supply balance @@ -127,8 +126,7 @@ contract TestLiquidate is TestSetup { vars.liquidationBonus) / (vars.borrowedTokenUnit * collateralPrice * 10_000); uint256 normalizedIncome = pool.getReserveNormalizedIncome(usdc); - uint256 expectedOnPool = collateralOnPool - - underlyingToScaledBalance(amountToSeize, normalizedIncome); + uint256 expectedOnPool = collateralOnPool - amountToSeize.rayDiv(normalizedIncome); testEqualityLarge(onPoolBorrower, expectedOnPool); assertEq(inP2PBorrower, 0); @@ -173,17 +171,16 @@ contract TestLiquidate is TestSetup { address(borrower1) ); - uint256 expectedBorrowBalanceInP2P = aDUnitToUnderlying( - onPoolUsdc, + uint256 expectedBorrowBalanceInP2PInUnderlying = onPoolUsdc.rayMul( pool.getReserveNormalizedVariableDebt(usdc) ) + - p2pUnitToUnderlying(inP2PUsdc, morpho.p2pBorrowIndex(aUsdc)) - + inP2PUsdc.rayMul(morpho.p2pBorrowIndex(aUsdc)) - toRepay; assertApproxEqAbs(onPoolBorrower, 0, 1, "borrower borrow on pool"); assertApproxEqAbs( - p2pUnitToUnderlying(inP2PBorrower, morpho.p2pBorrowIndex(aUsdc)), - expectedBorrowBalanceInP2P, + inP2PBorrower.rayMul(morpho.p2pBorrowIndex(aUsdc)), + expectedBorrowBalanceInP2PInUnderlying, 1, "borrower borrow in peer-to-peer" ); @@ -208,8 +205,7 @@ contract TestLiquidate is TestSetup { testEqualityLarge( onPoolBorrower, - onPoolDai - - underlyingToScaledBalance(amountToSeize, pool.getReserveNormalizedIncome(dai)), + onPoolDai - amountToSeize.rayDiv(pool.getReserveNormalizedIncome(dai)), "borrower supply on pool" ); assertEq(inP2PBorrower, inP2PDai, "borrower supply in peer-to-peer"); @@ -253,13 +249,12 @@ contract TestLiquidate is TestSetup { address(borrower1) ); - uint256 expectedBorrowBalanceOnPool = aDUnitToUnderlying( - onPoolUsdc, + uint256 expectedBorrowBalanceOnPool = onPoolUsdc.rayMul( pool.getReserveNormalizedVariableDebt(usdc) ) - toRepay; assertApproxEqAbs( - aDUnitToUnderlying(onPoolBorrower, pool.getReserveNormalizedVariableDebt(usdc)), + onPoolBorrower.rayMul(pool.getReserveNormalizedVariableDebt(usdc)), expectedBorrowBalanceOnPool, 1, "borrower borrow on pool" @@ -287,8 +282,7 @@ contract TestLiquidate is TestSetup { testEquality( onPoolBorrower, - onPoolDai - - underlyingToScaledBalance(amountToSeize, pool.getReserveNormalizedIncome(dai)), + onPoolDai - amountToSeize.rayDiv(pool.getReserveNormalizedIncome(dai)), "borrower supply on pool" ); assertEq(inP2PBorrower, inP2PDai, "borrower supply in peer-to-peer"); diff --git a/test-foundry/aave-v3/TestMarketMember.t.sol b/test-foundry/aave-v3/TestMarketMember.t.sol index e94444534..0d1813d6f 100644 --- a/test-foundry/aave-v3/TestMarketMember.t.sol +++ b/test-foundry/aave-v3/TestMarketMember.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.10; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/aave-v3/TestMarketStrategy.t.sol b/test-foundry/aave-v3/TestMarketStrategy.t.sol index d00f2bcbb..ebb4122d7 100644 --- a/test-foundry/aave-v3/TestMarketStrategy.t.sol +++ b/test-foundry/aave-v3/TestMarketStrategy.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.10; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/aave-v3/TestMorphoGetters.t.sol b/test-foundry/aave-v3/TestMorphoGetters.t.sol index f1d8258cd..3b1bc811b 100644 --- a/test-foundry/aave-v3/TestMorphoGetters.t.sol +++ b/test-foundry/aave-v3/TestMorphoGetters.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.10; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/aave-v3/TestP2PDisable.t.sol b/test-foundry/aave-v3/TestP2PDisable.t.sol index bc9c8b45e..e550bc146 100644 --- a/test-foundry/aave-v3/TestP2PDisable.t.sol +++ b/test-foundry/aave-v3/TestP2PDisable.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.10; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/aave-v3/TestPausableMarket.t.sol b/test-foundry/aave-v3/TestPausableMarket.t.sol index 29b62e881..98ce1dc92 100644 --- a/test-foundry/aave-v3/TestPausableMarket.t.sol +++ b/test-foundry/aave-v3/TestPausableMarket.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.10; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/aave-v3/TestPublicFunctions.t.sol b/test-foundry/aave-v3/TestPublicFunctions.t.sol index da896f4b1..b4ff843cb 100644 --- a/test-foundry/aave-v3/TestPublicFunctions.t.sol +++ b/test-foundry/aave-v3/TestPublicFunctions.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.10; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/aave-v3/TestRepay.t.sol b/test-foundry/aave-v3/TestRepay.t.sol index 60e4671ef..d60c92a72 100644 --- a/test-foundry/aave-v3/TestRepay.t.sol +++ b/test-foundry/aave-v3/TestRepay.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.10; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; @@ -69,10 +69,7 @@ contract TestRepay is TestSetup { address(supplier1) ); - uint256 expectedOnPool = underlyingToAdUnit( - suppliedAmount, - pool.getReserveNormalizedVariableDebt(dai) - ); + uint256 expectedOnPool = suppliedAmount.rayDiv(pool.getReserveNormalizedVariableDebt(dai)); testEquality(onPoolSupplier, 0, "supplier on pool"); testEqualityLarge(onPoolBorrower1, expectedOnPool, "borrower on pool"); @@ -94,10 +91,7 @@ contract TestRepay is TestSetup { (uint256 inP2PAvailableBorrower, uint256 onPoolAvailableBorrower) = morpho .borrowBalanceInOf(aDai, address(borrower2)); uint256 p2pBorrowIndex = morpho.p2pBorrowIndex(aDai); - uint256 expectedBorrowBalanceInP2P = underlyingToP2PUnit( - (25 * borrowedAmount) / 100, - p2pBorrowIndex - ); + uint256 expectedBorrowBalanceInP2P = ((25 * borrowedAmount) / 100).rayDiv(p2pBorrowIndex); testEqualityLarge(inP2PBorrower1, inP2PAvailableBorrower, "borrower in P2P 1"); testEqualityLarge(inP2PBorrower1, expectedBorrowBalanceInP2P, "borrower in P2P 2"); @@ -142,10 +136,7 @@ contract TestRepay is TestSetup { address(supplier1) ); - uint256 expectedOnPool = underlyingToAdUnit( - suppliedAmount, - pool.getReserveNormalizedVariableDebt(dai) - ); + uint256 expectedOnPool = suppliedAmount.rayDiv(pool.getReserveNormalizedVariableDebt(dai)); testEquality(onPoolSupplier, 0); testEqualityLarge(onPoolBorrower1, expectedOnPool); @@ -155,21 +146,19 @@ contract TestRepay is TestSetup { uint256 NMAX = 20; createSigners(NMAX); - uint256 inP2P; - uint256 onPool; uint256 normalizedVariableDebt = pool.getReserveNormalizedVariableDebt(dai); uint256 amountPerBorrower = (borrowedAmount - suppliedAmount) / (NMAX - 1); // minus because borrower1 must not be counted twice ! - for (uint256 i = 0; i < NMAX; i++) { + for (uint256 i; i < NMAX; i++) { if (borrowers[i] == borrower1) continue; borrowers[i].approve(usdc, to6Decimals(collateral)); borrowers[i].supply(aUsdc, to6Decimals(collateral)); borrowers[i].borrow(aDai, amountPerBorrower); - (inP2P, onPool) = morpho.borrowBalanceInOf(aDai, address(borrowers[i])); - expectedOnPool = underlyingToAdUnit(amountPerBorrower, normalizedVariableDebt); + (uint256 inP2P, uint256 onPool) = morpho.borrowBalanceInOf(aDai, address(borrowers[i])); + expectedOnPool = amountPerBorrower.rayDiv(normalizedVariableDebt); testEqualityLarge(inP2P, 0); testEqualityLarge(onPool, expectedOnPool); @@ -189,19 +178,18 @@ contract TestRepay is TestSetup { (inP2PSupplier, onPoolSupplier) = morpho.supplyBalanceInOf(aDai, address(supplier1)); uint256 p2pBorrowIndex = morpho.p2pBorrowIndex(aDai); - uint256 expectedSupplyBalanceInP2P = underlyingToP2PUnit(suppliedAmount, p2pBorrowIndex); - testEqualityLarge(inP2PSupplier, expectedSupplyBalanceInP2P); + testEqualityLarge(inP2PSupplier, suppliedAmount.rayDiv(p2pBorrowIndex)); testEqualityLarge(onPoolSupplier, 0); // Now test for each individual borrower that replaced the original - for (uint256 i = 0; i < borrowers.length; i++) { + for (uint256 i; i < borrowers.length; i++) { if (borrowers[i] == borrower1) continue; - (inP2P, onPool) = morpho.borrowBalanceInOf(aDai, address(borrowers[i])); - uint256 expectedInP2P = p2pUnitToUnderlying(inP2P, p2pBorrowIndex); + (uint256 inP2P, uint256 onPool) = morpho.borrowBalanceInOf(aDai, address(borrowers[i])); + uint256 inPP2InUnderlying = inP2P.rayMul(p2pBorrowIndex); - testEqualityLarge(expectedInP2P, amountPerBorrower); + testEqualityLarge(inPP2InUnderlying, amountPerBorrower); testEqualityLarge(onPool, 0); } } @@ -231,10 +219,7 @@ contract TestRepay is TestSetup { address(supplier1) ); - uint256 expectedOnPool = underlyingToAdUnit( - suppliedAmount, - pool.getReserveNormalizedVariableDebt(dai) - ); + uint256 expectedOnPool = suppliedAmount.rayDiv(pool.getReserveNormalizedVariableDebt(dai)); testEquality(onPoolSupplier, 0); testEqualityLarge(onPoolBorrower1, expectedOnPool); @@ -250,10 +235,7 @@ contract TestRepay is TestSetup { uint256 normalizedIncome = pool.getReserveNormalizedIncome(dai); uint256 p2pBorrowIndex = morpho.p2pBorrowIndex(aDai); - uint256 expectedBorrowBalanceInP2P = underlyingToP2PUnit( - (25 * borrowedAmount) / 100, - p2pBorrowIndex - ); + uint256 expectedBorrowBalanceInP2P = ((25 * borrowedAmount) / 100).rayDiv(p2pBorrowIndex); testEqualityLarge(inP2PBorrower1, expectedBorrowBalanceInP2P); testEqualityLarge(onPoolBorrower1, 0); @@ -261,14 +243,8 @@ contract TestRepay is TestSetup { // Check balances for supplier (inP2PSupplier, onPoolSupplier) = morpho.supplyBalanceInOf(aDai, address(supplier1)); - uint256 expectedSupplyBalanceInP2P = underlyingToP2PUnit( - suppliedAmount / 2, - p2pBorrowIndex - ); - uint256 expectedSupplyBalanceOnPool = underlyingToAdUnit( - suppliedAmount / 2, - normalizedIncome - ); + uint256 expectedSupplyBalanceInP2P = (suppliedAmount / 2).rayDiv(p2pBorrowIndex); + uint256 expectedSupplyBalanceOnPool = (suppliedAmount / 2).rayDiv(normalizedIncome); testEqualityLarge(inP2PSupplier, expectedSupplyBalanceInP2P); testEqualityLarge(onPoolSupplier, expectedSupplyBalanceOnPool); @@ -306,13 +282,11 @@ contract TestRepay is TestSetup { address(supplier1) ); - uint256 expectedOnPool = underlyingToAdUnit( - suppliedAmount, - pool.getReserveNormalizedVariableDebt(dai) - ); - testEquality(onPoolSupplier, 0); - testEqualityLarge(onPoolBorrower1, expectedOnPool); + testEqualityLarge( + onPoolBorrower1, + suppliedAmount.rayDiv(pool.getReserveNormalizedVariableDebt(dai)) + ); testEqualityLarge(inP2PSupplier, inP2PBorrower1); // NMAX borrowers have borrowerAmount/2 (cumulated) of debt waiting on pool @@ -343,28 +317,21 @@ contract TestRepay is TestSetup { (inP2PSupplier, onPoolSupplier) = morpho.supplyBalanceInOf(aDai, address(supplier1)); uint256 p2pBorrowIndex = morpho.p2pBorrowIndex(aDai); - uint256 normalizedIncome = pool.getReserveNormalizedIncome(dai); - uint256 expectedSupplyBalanceOnPool = underlyingToP2PUnit( - suppliedAmount / 2, - normalizedIncome + testEqualityLarge(inP2PSupplier, (suppliedAmount / 2).rayDiv(p2pBorrowIndex)); + testEqualityLarge( + onPoolSupplier, + (suppliedAmount / 2).rayDiv(pool.getReserveNormalizedIncome(dai)) ); - uint256 expectedSupplyBalanceInP2P = underlyingToAdUnit(suppliedAmount / 2, p2pBorrowIndex); - - testEqualityLarge(inP2PSupplier, expectedSupplyBalanceInP2P); - testEqualityLarge(onPoolSupplier, expectedSupplyBalanceOnPool); - - uint256 inP2P; - uint256 onPool; // Now test for each individual borrower that replaced the original - for (uint256 i = 0; i < borrowers.length; i++) { + for (uint256 i; i < borrowers.length; i++) { if (borrowers[i] == borrower1) continue; - (inP2P, onPool) = morpho.borrowBalanceInOf(aDai, address(borrowers[i])); - uint256 expectedInP2P = p2pUnitToUnderlying(inP2P, p2pBorrowIndex); + (uint256 inP2P, uint256 onPool) = morpho.borrowBalanceInOf(aDai, address(borrowers[i])); + uint256 inP2PInUnderlying = inP2P.rayMul(p2pBorrowIndex); - testEqualityLarge(expectedInP2P, amountPerBorrower); + testEqualityLarge(inP2PInUnderlying, amountPerBorrower); testEquality(onPool, 0); } } @@ -405,7 +372,7 @@ contract TestRepay is TestSetup { { uint256 p2pBorrowIndex = morpho.p2pBorrowIndex(aDai); - expectedBorrowBalanceInP2P = underlyingToP2PUnit(borrowedAmount, p2pBorrowIndex); + expectedBorrowBalanceInP2P = borrowedAmount.rayDiv(p2pBorrowIndex); // Check balances after match of supplier1 (uint256 inP2PBorrower, uint256 onPoolBorrower) = morpho.borrowBalanceInOf( @@ -416,10 +383,7 @@ contract TestRepay is TestSetup { testEqualityLarge(inP2PBorrower, expectedBorrowBalanceInP2P); uint256 p2pSupplyIndex = morpho.p2pSupplyIndex(aDai); - uint256 expectedSupplyBalanceInP2P = underlyingToP2PUnit( - suppliedAmount, - p2pSupplyIndex - ); + uint256 expectedSupplyBalanceInP2P = suppliedAmount.rayDiv(p2pSupplyIndex); for (uint256 i = 0; i < 20; i++) { (uint256 inP2PSupplier, uint256 onPoolSupplier) = morpho.supplyBalanceInOf( @@ -445,8 +409,7 @@ contract TestRepay is TestSetup { // There should be a delta uint256 expectedSupplyP2PDeltaInUnderlying = 10 * suppliedAmount; - uint256 expectedSupplyP2PDelta = underlyingToScaledBalance( - expectedSupplyP2PDeltaInUnderlying, + uint256 expectedSupplyP2PDelta = expectedSupplyP2PDeltaInUnderlying.rayDiv( pool.getReserveNormalizedIncome(dai) ); (uint256 supplyP2PDelta, , , ) = morpho.deltas(aDai); @@ -458,8 +421,7 @@ contract TestRepay is TestSetup { borrower2.borrow(aDai, expectedSupplyP2PDeltaInUnderlying / 2); (inP2PBorrower, onPoolBorrower) = morpho.borrowBalanceInOf(aDai, address(borrower2)); - expectedBorrowBalanceInP2P = underlyingToP2PUnit( - expectedSupplyP2PDeltaInUnderlying / 2, + expectedBorrowBalanceInP2P = (expectedSupplyP2PDeltaInUnderlying / 2).rayDiv( p2pBorrowIndex ); @@ -524,7 +486,7 @@ contract TestRepay is TestSetup { address(suppliers[i]) ); assertApproxEqAbs( - p2pUnitToUnderlying(inP2PSupplier, newVars.SP2PER), + inP2PSupplier.rayMul(newVars.SP2PER), expectedSupplyBalanceInUnderlying, (expectedSupplyBalanceInUnderlying * 2) / 100, "not expected balance peer-to-peer" diff --git a/test-foundry/aave-v3/TestRewards.t.sol b/test-foundry/aave-v3/TestRewards.t.sol index f327c02d7..7f7067b3a 100644 --- a/test-foundry/aave-v3/TestRewards.t.sol +++ b/test-foundry/aave-v3/TestRewards.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.10; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; @@ -373,7 +373,7 @@ contract TestRewards is TestSetup { supplier3.borrow(aUsdc, toBorrow); } - function testShouldClaimRewardsAndTradeForMorpkoTokens() public { + function testShouldClaimRewardsAndTradeForMorphoTokens() public { // 10% bonus. incentivesVault.setBonus(1_000); @@ -422,4 +422,93 @@ contract TestRewards is TestSetup { // User tries to claim its rewards on Morpho. supplier1.claimRewards(markets, false); } + + function testGetUserRewards() public { + uint256 toSupply = 100 ether; + supplier1.approve(dai, toSupply); + supplier1.supply(aDai, toSupply); + + address[] memory aDaiInArray = new address[](1); + aDaiInArray[0] = aDai; + + hevm.warp(block.timestamp + 365 days); + + uint256 unclaimedRewards = rewardsManager.getUserRewards( + aDaiInArray, + address(supplier1), + rewardToken + ); + + supplier1.withdraw(aDai, type(uint256).max); + uint256 balanceBefore = ERC20(rewardToken).balanceOf(address(supplier1)); + supplier1.claimRewards(aDaiInArray, false); + uint256 balanceAfter = ERC20(rewardToken).balanceOf(address(supplier1)); + + assertEq(unclaimedRewards, balanceAfter - balanceBefore); + } + + function testGetAllUserRewards() public { + uint256 toSupply = 100 ether; + supplier1.approve(dai, toSupply); + supplier1.supply(aDai, toSupply); + + address[] memory aDaiInArray = new address[](1); + aDaiInArray[0] = aDai; + + hevm.warp(block.timestamp + 365 days); + + (address[] memory rewardsList, uint256[] memory unclaimedAmounts) = rewardsManager + .getAllUserRewards(aDaiInArray, address(supplier1)); + + supplier1.withdraw(aDai, type(uint256).max); + + uint256 balanceBefore = ERC20(rewardsList[0]).balanceOf(address(supplier1)); + supplier1.claimRewards(aDaiInArray, false); + uint256 balanceAfter = ERC20(rewardsList[0]).balanceOf(address(supplier1)); + + assertEq(unclaimedAmounts[0], balanceAfter - balanceBefore); + } + + function testCanCallGetUserRewardsWithZeroBalance() public { + uint256 toSupply = 100 ether; + supplier1.approve(dai, toSupply); + supplier1.supply(aDai, toSupply); + + address[] memory aDaiInArray = new address[](1); + aDaiInArray[0] = aDai; + + hevm.warp(block.timestamp + 365 days); + + supplier1.withdraw(aDai, type(uint256).max); + + uint256 unclaimedRewards = rewardsManager.getUserRewards( + aDaiInArray, + address(supplier1), + rewardToken + ); + + assertGt(unclaimedRewards, 0); + } + + function testCanCallGetAllUserRewardsWithZeroBalance() public { + uint256 toSupply = 100 ether; + supplier1.approve(dai, toSupply); + supplier1.supply(aDai, toSupply); + + address[] memory aDaiInArray = new address[](1); + aDaiInArray[0] = aDai; + + hevm.warp(block.timestamp + 365 days); + + supplier1.withdraw(aDai, type(uint256).max); + + (, uint256[] memory unclaimedAmounts) = rewardsManager.getAllUserRewards( + aDaiInArray, + address(supplier1) + ); + + for (uint256 i; i < unclaimedAmounts.length; ++i) { + assertGt(unclaimedAmounts[i], 0); + } + } } diff --git a/test-foundry/aave-v3/TestSupply.t.sol b/test-foundry/aave-v3/TestSupply.t.sol index 43a686db7..8f196a7bd 100644 --- a/test-foundry/aave-v3/TestSupply.t.sol +++ b/test-foundry/aave-v3/TestSupply.t.sol @@ -1,10 +1,12 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.10; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; import "./helpers/FlashLoan.sol"; contract TestSupply is TestSetup { + using WadRayMath for uint256; + // There are no available borrowers: all of the supplied amount is supplied to the pool and set `onPool`. function testSupply1() public { uint256 amount = 10_000 ether; @@ -13,7 +15,7 @@ contract TestSupply is TestSetup { supplier1.supply(aDai, amount); uint256 normalizedIncome = pool.getReserveNormalizedIncome(dai); - uint256 expectedOnPool = underlyingToScaledBalance(amount, normalizedIncome); + uint256 expectedOnPool = amount.rayDiv(normalizedIncome); testEquality(IERC20(aDai).balanceOf(address(morpho)), amount); @@ -41,7 +43,7 @@ contract TestSupply is TestSetup { testEquality(daiBalanceAfter, expectedDaiBalanceAfter); uint256 p2pSupplyIndex = lens.getUpdatedP2PSupplyIndex(aDai); - uint256 expectedSupplyBalanceInP2P = underlyingToP2PUnit(amount, p2pSupplyIndex); + uint256 expectedSupplyBalanceInP2P = amount.rayDiv(p2pSupplyIndex); (uint256 inP2PSupplier, uint256 onPoolSupplier) = morpho.supplyBalanceInOf( aDai, @@ -72,10 +74,10 @@ contract TestSupply is TestSetup { supplier1.supply(aDai, 2 * amount); uint256 p2pSupplyIndex = lens.getUpdatedP2PSupplyIndex(aDai); - uint256 expectedSupplyBalanceInP2P = underlyingToP2PUnit(amount, p2pSupplyIndex); + uint256 expectedSupplyBalanceInP2P = amount.rayDiv(p2pSupplyIndex); uint256 normalizedIncome = pool.getReserveNormalizedIncome(dai); - uint256 expectedSupplyBalanceOnPool = underlyingToScaledBalance(amount, normalizedIncome); + uint256 expectedSupplyBalanceOnPool = amount.rayDiv(normalizedIncome); (uint256 inP2PSupplier, uint256 onPoolSupplier) = morpho.supplyBalanceInOf( aDai, @@ -127,14 +129,14 @@ contract TestSupply is TestSetup { for (uint256 i = 0; i < NMAX; i++) { (inP2P, onPool) = morpho.borrowBalanceInOf(aDai, address(borrowers[i])); - expectedInP2PInUnderlying = p2pUnitToUnderlying(inP2P, p2pSupplyIndex); + expectedInP2PInUnderlying = inP2P.rayMul(p2pSupplyIndex); testEqualityLarge(expectedInP2PInUnderlying, amountPerBorrower, "amount per borrower"); testEqualityLarge(onPool, 0, "on pool per borrower"); } (inP2P, onPool) = morpho.supplyBalanceInOf(aDai, address(supplier1)); - uint256 expectedInP2P = underlyingToP2PUnit(amount, morpho.p2pBorrowIndex(aDai)); + uint256 expectedInP2P = amount.rayDiv(morpho.p2pBorrowIndex(aDai)); testEquality(inP2P, expectedInP2P); testEquality(onPool, 0); @@ -169,27 +171,23 @@ contract TestSupply is TestSetup { uint256 inP2P; uint256 onPool; - uint256 expectedInP2PInUnderlying; + uint256 inP2PInUnderlying; uint256 p2pBorrowIndex = morpho.p2pBorrowIndex(aDai); uint256 normalizedIncome = pool.getReserveNormalizedIncome(dai); - for (uint256 i = 0; i < NMAX; i++) { + for (uint256 i; i < NMAX; i++) { (inP2P, onPool) = morpho.borrowBalanceInOf(aDai, address(borrowers[i])); - expectedInP2PInUnderlying = p2pUnitToUnderlying(inP2P, p2pBorrowIndex); + inP2PInUnderlying = inP2P.rayMul(p2pBorrowIndex); - testEqualityLarge( - expectedInP2PInUnderlying, - amountPerBorrower, - "borrower in peer-to-peer" - ); + testEqualityLarge(inP2PInUnderlying, amountPerBorrower, "borrower in peer-to-peer"); testEqualityLarge(onPool, 0); } (inP2P, onPool) = morpho.supplyBalanceInOf(aDai, address(supplier1)); - uint256 expectedInP2P = underlyingToP2PUnit(amount / 2, morpho.p2pSupplyIndex(aDai)); - uint256 expectedOnPool = underlyingToAdUnit(amount / 2, normalizedIncome); + uint256 expectedInP2P = (amount / 2).rayDiv(morpho.p2pSupplyIndex(aDai)); + uint256 expectedOnPool = (amount / 2).rayDiv(normalizedIncome); testEqualityLarge(inP2P, expectedInP2P, "in peer-to-peer"); testEqualityLarge(onPool, expectedOnPool, "in pool"); @@ -204,7 +202,7 @@ contract TestSupply is TestSetup { supplier1.supply(aDai, amount); uint256 normalizedIncome = pool.getReserveNormalizedIncome(dai); - uint256 expectedOnPool = underlyingToScaledBalance(2 * amount, normalizedIncome); + uint256 expectedOnPool = (2 * amount).rayDiv(normalizedIncome); (, uint256 onPool) = morpho.supplyBalanceInOf(aDai, address(supplier1)); testEqualityLarge(onPool, expectedOnPool); @@ -241,7 +239,7 @@ contract TestSupply is TestSetup { morpho.supply(aDai, address(supplier2), amount); uint256 poolSupplyIndex = pool.getReserveNormalizedIncome(dai); - uint256 expectedOnPool = underlyingToScaledBalance(amount, poolSupplyIndex); + uint256 expectedOnPool = amount.rayDiv(poolSupplyIndex); assertEq(ERC20(aDai).balanceOf(address(morpho)), amount, "balance of aToken"); diff --git a/test-foundry/aave-v3/TestUpgradeable.t.sol b/test-foundry/aave-v3/TestUpgradeable.t.sol index 7f4165cde..14c75eef9 100644 --- a/test-foundry/aave-v3/TestUpgradeable.t.sol +++ b/test-foundry/aave-v3/TestUpgradeable.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.10; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/aave-v3/TestWithdraw.t.sol b/test-foundry/aave-v3/TestWithdraw.t.sol index 150a3a31c..260c688f8 100644 --- a/test-foundry/aave-v3/TestWithdraw.t.sol +++ b/test-foundry/aave-v3/TestWithdraw.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.10; +pragma solidity ^0.8.0; import {Attacker} from "./helpers/Attacker.sol"; import "./setup/TestSetup.sol"; @@ -31,7 +31,7 @@ contract TestWithdraw is TestSetup { (uint256 inP2P, uint256 onPool) = morpho.supplyBalanceInOf(aUsdc, address(supplier1)); uint256 expectedOnPool = to6Decimals( - underlyingToScaledBalance(2 * amount, pool.getReserveNormalizedIncome(usdc)) + (2 * amount).rayDiv(pool.getReserveNormalizedIncome(usdc)) ); testEquality(inP2P, 0); @@ -55,9 +55,7 @@ contract TestWithdraw is TestSetup { uint256 balanceBefore = supplier1.balanceOf(usdc); (uint256 inP2P, uint256 onPool) = morpho.supplyBalanceInOf(aUsdc, address(supplier1)); - uint256 expectedOnPool = to6Decimals( - underlyingToScaledBalance(amount, pool.getReserveNormalizedIncome(usdc)) - ); + uint256 expectedOnPool = to6Decimals(amount.rayDiv(pool.getReserveNormalizedIncome(usdc))); testEquality(inP2P, 0); testEquality(onPool, expectedOnPool); @@ -96,10 +94,7 @@ contract TestWithdraw is TestSetup { address(supplier1) ); - uint256 expectedOnPool = underlyingToScaledBalance( - suppliedAmount / 2, - pool.getReserveNormalizedIncome(dai) - ); + uint256 expectedOnPool = (suppliedAmount / 2).rayDiv(pool.getReserveNormalizedIncome(dai)); testEqualityLarge(onPoolSupplier, expectedOnPool, "supplier on pool 0"); testEquality(onPoolBorrower1, 0, "borrower on pool 0"); @@ -120,7 +115,7 @@ contract TestWithdraw is TestSetup { // Check balances for supplier2 (inP2PSupplier, onPoolSupplier) = morpho.supplyBalanceInOf(aDai, address(supplier2)); uint256 p2pSupplyIndex = morpho.p2pSupplyIndex(aDai); - uint256 expectedInP2P = underlyingToP2PUnit(suppliedAmount / 2, p2pSupplyIndex); + uint256 expectedInP2P = (suppliedAmount / 2).rayDiv(p2pSupplyIndex); testEqualityLarge(onPoolSupplier, expectedOnPool, "supplier on pool 2"); testEqualityLarge(inP2PSupplier, expectedInP2P, "supplier in P2P 2"); @@ -162,10 +157,7 @@ contract TestWithdraw is TestSetup { address(supplier1) ); - uint256 expectedOnPool = underlyingToScaledBalance( - suppliedAmount / 2, - pool.getReserveNormalizedIncome(dai) - ); + uint256 expectedOnPool = (suppliedAmount / 2).rayDiv(pool.getReserveNormalizedIncome(dai)); testEqualityLarge(onPoolSupplier, expectedOnPool, "supplier on pool"); testEqualityLarge(onPoolBorrower, 0, "borrower on pool"); @@ -196,10 +188,7 @@ contract TestWithdraw is TestSetup { (inP2PBorrower, onPoolBorrower) = morpho.borrowBalanceInOf(aDai, address(borrower1)); uint256 p2pSupplyIndex = morpho.p2pSupplyIndex(aDai); - uint256 expectedBorrowBalanceInP2P = underlyingToP2PUnit( - borrowedAmount, - morpho.p2pBorrowIndex(aDai) - ); + uint256 expectedBorrowBalanceInP2P = borrowedAmount.rayDiv(morpho.p2pBorrowIndex(aDai)); testEqualityLarge(inP2PBorrower, expectedBorrowBalanceInP2P, "borrower in P2P"); testEqualityLarge(onPoolBorrower, 0, "borrower on pool"); @@ -212,7 +201,7 @@ contract TestWithdraw is TestSetup { if (suppliers[i] == supplier1) continue; (inP2P, onPool) = morpho.supplyBalanceInOf(aDai, address(suppliers[i])); - uint256 expectedInP2P = p2pUnitToUnderlying(inP2P, p2pSupplyIndex); + uint256 expectedInP2P = inP2P.rayMul(p2pSupplyIndex); testEqualityLarge(expectedInP2P, amountPerSupplier, "new supplier in P2P"); testEqualityLarge(onPool, 0, "new supplier on pool"); @@ -244,10 +233,7 @@ contract TestWithdraw is TestSetup { address(supplier1) ); - uint256 expectedOnPool = underlyingToScaledBalance( - suppliedAmount / 2, - pool.getReserveNormalizedIncome(dai) - ); + uint256 expectedOnPool = (suppliedAmount / 2).rayDiv(pool.getReserveNormalizedIncome(dai)); testEqualityLarge(onPoolSupplier, expectedOnPool, "supplier on pool"); testEquality(onPoolBorrower, 0, "borrower on pool"); @@ -260,12 +246,8 @@ contract TestWithdraw is TestSetup { (inP2PBorrower, onPoolBorrower) = morpho.borrowBalanceInOf(aDai, address(borrower1)); uint256 p2pSupplyIndex = morpho.p2pSupplyIndex(aDai); - uint256 expectedBorrowBalanceInP2P = underlyingToP2PUnit( - borrowedAmount / 2, - p2pSupplyIndex - ); - uint256 expectedBorrowBalanceOnPool = underlyingToAdUnit( - borrowedAmount / 2, + uint256 expectedBorrowBalanceInP2P = (borrowedAmount / 2).rayDiv(p2pSupplyIndex); + uint256 expectedBorrowBalanceOnPool = (borrowedAmount / 2).rayDiv( pool.getReserveNormalizedVariableDebt(dai) ); @@ -275,10 +257,7 @@ contract TestWithdraw is TestSetup { // Check balances for supplier (inP2PSupplier, onPoolSupplier) = morpho.supplyBalanceInOf(aDai, address(supplier1)); - uint256 expectedSupplyBalanceInP2P = underlyingToP2PUnit( - (25 * suppliedAmount) / 100, - p2pSupplyIndex - ); + uint256 expectedSupplyBalanceInP2P = ((25 * suppliedAmount) / 100).rayDiv(p2pSupplyIndex); testEquality(inP2PSupplier, expectedSupplyBalanceInP2P); testEquality(onPoolSupplier, 0); @@ -319,10 +298,7 @@ contract TestWithdraw is TestSetup { address(supplier1) ); - uint256 expectedOnPool = underlyingToScaledBalance( - suppliedAmount / 2, - pool.getReserveNormalizedIncome(dai) - ); + uint256 expectedOnPool = (suppliedAmount / 2).rayDiv(pool.getReserveNormalizedIncome(dai)); testEqualityLarge(onPoolSupplier, expectedOnPool, "supplier on pool"); testEquality(onPoolBorrower, 0, "borrower on pool"); @@ -353,12 +329,8 @@ contract TestWithdraw is TestSetup { (inP2PBorrower, onPoolBorrower) = morpho.borrowBalanceInOf(aDai, address(borrower1)); uint256 p2pSupplyIndex = morpho.p2pSupplyIndex(aDai); - uint256 expectedBorrowBalanceInP2P = underlyingToP2PUnit( - borrowedAmount / 2, - p2pSupplyIndex - ); - uint256 expectedBorrowBalanceOnPool = underlyingToAdUnit( - borrowedAmount / 2, + uint256 expectedBorrowBalanceInP2P = (borrowedAmount / 2).rayDiv(p2pSupplyIndex); + uint256 expectedBorrowBalanceOnPool = (borrowedAmount / 2).rayDiv( pool.getReserveNormalizedVariableDebt(dai) ); @@ -373,7 +345,7 @@ contract TestWithdraw is TestSetup { if (suppliers[i] == supplier1) continue; (inP2P, onPool) = morpho.supplyBalanceInOf(aDai, address(suppliers[i])); - uint256 expectedInP2P = p2pUnitToUnderlying(inP2P, p2pSupplyIndex); + uint256 expectedInP2P = inP2P.rayMul(p2pSupplyIndex); testEqualityLarge(expectedInP2P, amountPerSupplier); testEqualityLarge(onPool, 0); @@ -419,7 +391,7 @@ contract TestWithdraw is TestSetup { { uint256 p2pSupplyIndex = morpho.p2pSupplyIndex(aDai); - expectedSupplyBalanceInP2P = underlyingToP2PUnit(suppliedAmount, p2pSupplyIndex); + expectedSupplyBalanceInP2P = suppliedAmount.rayDiv(p2pSupplyIndex); // Check balances after match of supplier1 and borrowers (uint256 inP2PSupplier, uint256 onPoolSupplier) = morpho.supplyBalanceInOf( @@ -430,10 +402,7 @@ contract TestWithdraw is TestSetup { testEqualityLarge(inP2PSupplier, expectedSupplyBalanceInP2P); uint256 p2pBorrowIndex = morpho.p2pBorrowIndex(aDai); - uint256 expectedBorrowBalanceInP2P = underlyingToP2PUnit( - borrowedAmount, - p2pBorrowIndex - ); + uint256 expectedBorrowBalanceInP2P = borrowedAmount.rayDiv(p2pBorrowIndex); for (uint256 i = 10; i < 20; i++) { (uint256 inP2PBorrower, uint256 onPoolBorrower) = morpho.borrowBalanceInOf( @@ -455,8 +424,7 @@ contract TestWithdraw is TestSetup { // There should be a delta uint256 expectedBorrowP2PDeltaInUnderlying = 10 * borrowedAmount; - uint256 expectedBorrowP2PDelta = underlyingToAdUnit( - expectedBorrowP2PDeltaInUnderlying, + uint256 expectedBorrowP2PDelta = expectedBorrowP2PDeltaInUnderlying.rayDiv( pool.getReserveNormalizedVariableDebt(dai) ); @@ -472,8 +440,7 @@ contract TestWithdraw is TestSetup { supplier2.supply(aDai, expectedBorrowP2PDeltaInUnderlying / 2); (inP2PSupplier, onPoolSupplier) = morpho.supplyBalanceInOf(aDai, address(supplier2)); - expectedSupplyBalanceInP2P = underlyingToP2PUnit( - expectedBorrowP2PDeltaInUnderlying / 2, + expectedSupplyBalanceInP2P = (expectedBorrowP2PDeltaInUnderlying / 2).rayDiv( p2pSupplyIndex ); @@ -537,7 +504,7 @@ contract TestWithdraw is TestSetup { address(borrowers[i]) ); assertApproxEqAbs( - p2pUnitToUnderlying(inP2PBorrower, newVars.BP2PER), + inP2PBorrower.rayMul(newVars.BP2PER), expectedBorrowBalanceInUnderlying, (expectedBorrowBalanceInUnderlying * 2) / 100, "not expected underlying balance" diff --git a/test-foundry/aave-v3/helpers/Attacker.sol b/test-foundry/aave-v3/helpers/Attacker.sol index 4526aa812..af53209ea 100644 --- a/test-foundry/aave-v3/helpers/Attacker.sol +++ b/test-foundry/aave-v3/helpers/Attacker.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.10; +pragma solidity ^0.8.0; import "@contracts/aave-v3/interfaces/aave/IPool.sol"; diff --git a/test-foundry/aave-v3/helpers/DumbOracle.sol b/test-foundry/aave-v3/helpers/DumbOracle.sol index c53c39bc6..06e33b7d4 100644 --- a/test-foundry/aave-v3/helpers/DumbOracle.sol +++ b/test-foundry/aave-v3/helpers/DumbOracle.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.10; +pragma solidity ^0.8.0; import "@contracts/aave-v3/interfaces/IOracle.sol"; diff --git a/test-foundry/aave-v3/helpers/FlashLoan.sol b/test-foundry/aave-v3/helpers/FlashLoan.sol index e69e130ee..9cbd19e78 100644 --- a/test-foundry/aave-v3/helpers/FlashLoan.sol +++ b/test-foundry/aave-v3/helpers/FlashLoan.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.10; +pragma solidity ^0.8.0; import "@contracts/aave-v3/interfaces/aave/IPool.sol"; import "@rari-capital/solmate/src/utils/SafeTransferLib.sol"; diff --git a/test-foundry/aave-v3/helpers/IVariableDebtTokenExtended.sol b/test-foundry/aave-v3/helpers/IVariableDebtTokenExtended.sol index 2cd789993..944210cc9 100644 --- a/test-foundry/aave-v3/helpers/IVariableDebtTokenExtended.sol +++ b/test-foundry/aave-v3/helpers/IVariableDebtTokenExtended.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.10; +pragma solidity ^0.8.0; import {IVariableDebtToken} from "@aave/core-v3/contracts/interfaces/IVariableDebtToken.sol"; diff --git a/test-foundry/aave-v3/helpers/SimplePriceOracle.sol b/test-foundry/aave-v3/helpers/SimplePriceOracle.sol index d77260b9f..d47b22aa6 100644 --- a/test-foundry/aave-v3/helpers/SimplePriceOracle.sol +++ b/test-foundry/aave-v3/helpers/SimplePriceOracle.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.10; +pragma solidity ^0.8.0; /// Price Oracle for liquidation tests contract SimplePriceOracle { diff --git a/test-foundry/aave-v3/helpers/User.sol b/test-foundry/aave-v3/helpers/User.sol index 594e6d654..302f9274e 100644 --- a/test-foundry/aave-v3/helpers/User.sol +++ b/test-foundry/aave-v3/helpers/User.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.10; +pragma solidity ^0.8.0; import "@contracts/aave-v3/interfaces/IRewardsManager.sol"; diff --git a/test-foundry/aave-v3/setup/TestSetup.sol b/test-foundry/aave-v3/setup/TestSetup.sol index 6b6dc6595..a6ade3acc 100644 --- a/test-foundry/aave-v3/setup/TestSetup.sol +++ b/test-foundry/aave-v3/setup/TestSetup.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.10; +pragma solidity ^0.8.0; import "@aave/periphery-v3/contracts/rewards/interfaces/IRewardsController.sol"; import "@aave/core-v3/contracts/interfaces/IPriceOracleGetter.sol"; diff --git a/test-foundry/aave-v3/setup/Utils.sol b/test-foundry/aave-v3/setup/Utils.sol index 3f074e4ae..ea2a72ba4 100644 --- a/test-foundry/aave-v3/setup/Utils.sol +++ b/test-foundry/aave-v3/setup/Utils.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.10; +pragma solidity ^0.8.0; import "@aave/core-v3/contracts/protocol/libraries/math/WadRayMath.sol"; @@ -24,62 +24,6 @@ contract Utils is Test { return value / 1e10; } - function underlyingToScaledBalance(uint256 _scaledBalance, uint256 _normalizedIncome) - internal - pure - returns (uint256) - { - return _scaledBalance.rayDiv(_normalizedIncome); - } - - function scaledBalanceToUnderlying(uint256 _scaledBalance, uint256 _normalizedIncome) - internal - pure - returns (uint256) - { - return _scaledBalance.rayMul(_normalizedIncome); - } - - function underlyingToAdUnit(uint256 _underlyingAmount, uint256 _normalizedVariableDebt) - internal - pure - returns (uint256) - { - return _underlyingAmount.rayDiv(_normalizedVariableDebt); - } - - function aDUnitToUnderlying(uint256 _aDUnitAmount, uint256 _normalizedVariableDebt) - internal - pure - returns (uint256) - { - return _aDUnitAmount.rayMul(_normalizedVariableDebt); - } - - function underlyingToP2PUnit(uint256 _underlyingAmount, uint256 _p2pExchangeRate) - internal - pure - returns (uint256) - { - return _underlyingAmount.rayDiv(_p2pExchangeRate); - } - - function p2pUnitToUnderlying(uint256 _p2pUnitAmount, uint256 _p2pExchangeRate) - internal - pure - returns (uint256) - { - return _p2pUnitAmount.rayMul(_p2pExchangeRate); - } - - function getAbsDiff(uint256 a, uint256 b) internal pure returns (uint256) { - if (a > b) { - return a - b; - } - - return b - a; - } - function testEquality(uint256 _firstValue, uint256 _secondValue) internal { assertApproxEqAbs(_firstValue, _secondValue, 20); } diff --git a/test-foundry/compound/TestBorrow.t.sol b/test-foundry/compound/TestBorrow.t.sol index 5f5ec274b..7923334fb 100644 --- a/test-foundry/compound/TestBorrow.t.sol +++ b/test-foundry/compound/TestBorrow.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/compound/TestEth.t.sol b/test-foundry/compound/TestEth.t.sol index 71c79b1a1..bd7091671 100644 --- a/test-foundry/compound/TestEth.t.sol +++ b/test-foundry/compound/TestEth.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/compound/TestFees.t.sol b/test-foundry/compound/TestFees.t.sol index 33cbfea93..c3eec5686 100644 --- a/test-foundry/compound/TestFees.t.sol +++ b/test-foundry/compound/TestFees.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/compound/TestGovernance.t.sol b/test-foundry/compound/TestGovernance.t.sol index d67393b2a..fb89fb232 100644 --- a/test-foundry/compound/TestGovernance.t.sol +++ b/test-foundry/compound/TestGovernance.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/compound/TestIncentivesVault.t.sol b/test-foundry/compound/TestIncentivesVault.t.sol index 52871578c..385b6f067 100644 --- a/test-foundry/compound/TestIncentivesVault.t.sol +++ b/test-foundry/compound/TestIncentivesVault.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/compound/TestInterestRates.t.sol b/test-foundry/compound/TestInterestRates.t.sol index 8d6b37aa2..f49d34008 100644 --- a/test-foundry/compound/TestInterestRates.t.sol +++ b/test-foundry/compound/TestInterestRates.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "@contracts/compound/InterestRatesManager.sol"; import "@forge-std/Test.sol"; diff --git a/test-foundry/compound/TestLens.t.sol b/test-foundry/compound/TestLens.t.sol index c998712d8..46a94becd 100644 --- a/test-foundry/compound/TestLens.t.sol +++ b/test-foundry/compound/TestLens.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; @@ -1212,11 +1212,12 @@ contract TestLens is TestSetup { address(borrower1), new address[](0) ); - assertEq( + assertApproxEqAbs( collateralValue.div(borrowedPrice).div( comptroller.liquidationIncentiveMantissa() ), - 0 + 0, + 1 ); assertEq(toRepay, 0); } diff --git a/test-foundry/compound/TestLiquidate.t.sol b/test-foundry/compound/TestLiquidate.t.sol index a0f069954..c1a72cf66 100644 --- a/test-foundry/compound/TestLiquidate.t.sol +++ b/test-foundry/compound/TestLiquidate.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/compound/TestMarketMember.t.sol b/test-foundry/compound/TestMarketMember.t.sol index b9ef7b907..678cf72d5 100644 --- a/test-foundry/compound/TestMarketMember.t.sol +++ b/test-foundry/compound/TestMarketMember.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/compound/TestMarketStrategy.t.sol b/test-foundry/compound/TestMarketStrategy.t.sol index f318b1a17..daaed6979 100644 --- a/test-foundry/compound/TestMarketStrategy.t.sol +++ b/test-foundry/compound/TestMarketStrategy.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/compound/TestMorphoGetters.t.sol b/test-foundry/compound/TestMorphoGetters.t.sol index 90512b445..213f42c96 100644 --- a/test-foundry/compound/TestMorphoGetters.t.sol +++ b/test-foundry/compound/TestMorphoGetters.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/compound/TestMorphoUtils.t.sol b/test-foundry/compound/TestMorphoUtils.t.sol index 4a76bf848..8508ef059 100644 --- a/test-foundry/compound/TestMorphoUtils.t.sol +++ b/test-foundry/compound/TestMorphoUtils.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/compound/TestP2PDisable.t.sol b/test-foundry/compound/TestP2PDisable.t.sol index e82438050..50792dfd3 100644 --- a/test-foundry/compound/TestP2PDisable.t.sol +++ b/test-foundry/compound/TestP2PDisable.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/compound/TestPausableMarket.t.sol b/test-foundry/compound/TestPausableMarket.t.sol index 134b4f53c..4ff3fa0da 100644 --- a/test-foundry/compound/TestPausableMarket.t.sol +++ b/test-foundry/compound/TestPausableMarket.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/compound/TestRatesLens.t.sol b/test-foundry/compound/TestRatesLens.t.sol index 4020dc0b2..aaa55f313 100644 --- a/test-foundry/compound/TestRatesLens.t.sol +++ b/test-foundry/compound/TestRatesLens.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/compound/TestRepay.t.sol b/test-foundry/compound/TestRepay.t.sol index 09569ddc0..e55f673a8 100644 --- a/test-foundry/compound/TestRepay.t.sol +++ b/test-foundry/compound/TestRepay.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/compound/TestRewards.t.sol b/test-foundry/compound/TestRewards.t.sol index 92a26658d..922ce0b06 100644 --- a/test-foundry/compound/TestRewards.t.sol +++ b/test-foundry/compound/TestRewards.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/compound/TestRoundings.t.sol b/test-foundry/compound/TestRoundings.t.sol index 1b6b16229..ee5a28160 100644 --- a/test-foundry/compound/TestRoundings.t.sol +++ b/test-foundry/compound/TestRoundings.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/compound/TestSupply.t.sol b/test-foundry/compound/TestSupply.t.sol index ef593042e..667943033 100644 --- a/test-foundry/compound/TestSupply.t.sol +++ b/test-foundry/compound/TestSupply.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/compound/TestUpgradeable.t.sol b/test-foundry/compound/TestUpgradeable.t.sol index be48bc0d2..d97071858 100644 --- a/test-foundry/compound/TestUpgradeable.t.sol +++ b/test-foundry/compound/TestUpgradeable.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/compound/TestWithdraw.t.sol b/test-foundry/compound/TestWithdraw.t.sol index dacadc5d4..1fda6cbf5 100644 --- a/test-foundry/compound/TestWithdraw.t.sol +++ b/test-foundry/compound/TestWithdraw.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import {Attacker} from "./helpers/Attacker.sol"; import "./setup/TestSetup.sol"; diff --git a/test-foundry/compound/helpers/Attacker.sol b/test-foundry/compound/helpers/Attacker.sol index f9ca9541d..dd4a9c770 100644 --- a/test-foundry/compound/helpers/Attacker.sol +++ b/test-foundry/compound/helpers/Attacker.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "@contracts/compound/interfaces/compound/ICompound.sol"; diff --git a/test-foundry/compound/helpers/DumbOracle.sol b/test-foundry/compound/helpers/DumbOracle.sol index 4846b77c2..6300487c8 100644 --- a/test-foundry/compound/helpers/DumbOracle.sol +++ b/test-foundry/compound/helpers/DumbOracle.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "@contracts/compound/interfaces/IOracle.sol"; diff --git a/test-foundry/compound/helpers/IncentivesVault.sol b/test-foundry/compound/helpers/IncentivesVault.sol index d02d856b8..ca3b51a04 100644 --- a/test-foundry/compound/helpers/IncentivesVault.sol +++ b/test-foundry/compound/helpers/IncentivesVault.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./DumbOracle.sol"; diff --git a/test-foundry/compound/helpers/SimplePriceOracle.sol b/test-foundry/compound/helpers/SimplePriceOracle.sol index cb5e19d6f..21e54d68a 100644 --- a/test-foundry/compound/helpers/SimplePriceOracle.sol +++ b/test-foundry/compound/helpers/SimplePriceOracle.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "@contracts/compound/interfaces/compound/ICompound.sol"; diff --git a/test-foundry/compound/helpers/User.sol b/test-foundry/compound/helpers/User.sol index a64dbc6e5..68c074a49 100644 --- a/test-foundry/compound/helpers/User.sol +++ b/test-foundry/compound/helpers/User.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "@contracts/compound/interfaces/IRewardsManager.sol"; diff --git a/test-foundry/compound/setup/TestSetup.sol b/test-foundry/compound/setup/TestSetup.sol index 35e94491a..198f4211b 100644 --- a/test-foundry/compound/setup/TestSetup.sol +++ b/test-foundry/compound/setup/TestSetup.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "@contracts/compound/interfaces/IMorpho.sol"; diff --git a/test-foundry/compound/setup/Utils.sol b/test-foundry/compound/setup/Utils.sol index 67baf33d3..d5570d565 100644 --- a/test-foundry/compound/setup/Utils.sol +++ b/test-foundry/compound/setup/Utils.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "@contracts/compound/libraries/CompoundMath.sol"; diff --git a/test-foundry/fuzzing/aave-v2/TestBorrowFuzzing.t.sol b/test-foundry/fuzzing/aave-v2/TestBorrowFuzzing.t.sol index f331996fb..ed25fd6a7 100644 --- a/test-foundry/fuzzing/aave-v2/TestBorrowFuzzing.t.sol +++ b/test-foundry/fuzzing/aave-v2/TestBorrowFuzzing.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetupFuzzing.sol"; diff --git a/test-foundry/fuzzing/aave-v2/TestInterestRateFuzzing.t.sol b/test-foundry/fuzzing/aave-v2/TestInterestRateFuzzing.t.sol index c929fa2f8..4644eacd0 100644 --- a/test-foundry/fuzzing/aave-v2/TestInterestRateFuzzing.t.sol +++ b/test-foundry/fuzzing/aave-v2/TestInterestRateFuzzing.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "@contracts/aave-v2/InterestRatesManager.sol"; import "@forge-std/Test.sol"; diff --git a/test-foundry/fuzzing/aave-v2/TestLiquidateFuzzing.t.sol b/test-foundry/fuzzing/aave-v2/TestLiquidateFuzzing.t.sol index 2a1b06412..27d3274ff 100644 --- a/test-foundry/fuzzing/aave-v2/TestLiquidateFuzzing.t.sol +++ b/test-foundry/fuzzing/aave-v2/TestLiquidateFuzzing.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetupFuzzing.sol"; diff --git a/test-foundry/fuzzing/aave-v2/TestRepayFuzzing.t.sol b/test-foundry/fuzzing/aave-v2/TestRepayFuzzing.t.sol index befc1d7d1..1d0543d0e 100644 --- a/test-foundry/fuzzing/aave-v2/TestRepayFuzzing.t.sol +++ b/test-foundry/fuzzing/aave-v2/TestRepayFuzzing.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetupFuzzing.sol"; diff --git a/test-foundry/fuzzing/aave-v2/TestSupplyFuzzing.t.sol b/test-foundry/fuzzing/aave-v2/TestSupplyFuzzing.t.sol index 9828d6bd6..ac4c41d13 100644 --- a/test-foundry/fuzzing/aave-v2/TestSupplyFuzzing.t.sol +++ b/test-foundry/fuzzing/aave-v2/TestSupplyFuzzing.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetupFuzzing.sol"; @@ -22,7 +22,7 @@ contract TestSupplyFuzzing is TestSetupFuzzing { supplier1.supply(asset, amount); uint256 normalizedIncome = lendingPool.getReserveNormalizedIncome(underlying); - uint256 expectedOnPool = underlyingToScaledBalance(amount, normalizedIncome); + uint256 expectedOnPool = amount.rayDiv(normalizedIncome); testEquality(ERC20(asset).balanceOf(address(morpho)), amount, "balance of aToken"); diff --git a/test-foundry/fuzzing/aave-v2/TestWithdrawFuzzing.t.sol b/test-foundry/fuzzing/aave-v2/TestWithdrawFuzzing.t.sol index a79fea58f..af63d6b09 100644 --- a/test-foundry/fuzzing/aave-v2/TestWithdrawFuzzing.t.sol +++ b/test-foundry/fuzzing/aave-v2/TestWithdrawFuzzing.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetupFuzzing.sol"; import {Attacker} from "../../compound/helpers/Attacker.sol"; diff --git a/test-foundry/fuzzing/aave-v2/setup/TestSetupFuzzing.sol b/test-foundry/fuzzing/aave-v2/setup/TestSetupFuzzing.sol index f3790a091..3f970a55b 100644 --- a/test-foundry/fuzzing/aave-v2/setup/TestSetupFuzzing.sol +++ b/test-foundry/fuzzing/aave-v2/setup/TestSetupFuzzing.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "@contracts/aave-v2/interfaces/aave/IAaveIncentivesController.sol"; import "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol"; diff --git a/test-foundry/fuzzing/compound/TestBorrowFuzzing.t.sol b/test-foundry/fuzzing/compound/TestBorrowFuzzing.t.sol index f3b97999a..46d3f7d2d 100644 --- a/test-foundry/fuzzing/compound/TestBorrowFuzzing.t.sol +++ b/test-foundry/fuzzing/compound/TestBorrowFuzzing.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetupFuzzing.sol"; diff --git a/test-foundry/fuzzing/compound/TestInterestRateFuzzing.t.sol b/test-foundry/fuzzing/compound/TestInterestRateFuzzing.t.sol index d83ac33d3..c0f6b1d26 100644 --- a/test-foundry/fuzzing/compound/TestInterestRateFuzzing.t.sol +++ b/test-foundry/fuzzing/compound/TestInterestRateFuzzing.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "@contracts/compound/InterestRatesManager.sol"; import "@forge-std/Test.sol"; diff --git a/test-foundry/fuzzing/compound/TestLiquidateFuzzing.t.sol b/test-foundry/fuzzing/compound/TestLiquidateFuzzing.t.sol index b50763859..87a60735b 100644 --- a/test-foundry/fuzzing/compound/TestLiquidateFuzzing.t.sol +++ b/test-foundry/fuzzing/compound/TestLiquidateFuzzing.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetupFuzzing.sol"; diff --git a/test-foundry/fuzzing/compound/TestRepayFuzzing.t.sol b/test-foundry/fuzzing/compound/TestRepayFuzzing.t.sol index 2cd169450..c6fc20086 100644 --- a/test-foundry/fuzzing/compound/TestRepayFuzzing.t.sol +++ b/test-foundry/fuzzing/compound/TestRepayFuzzing.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetupFuzzing.sol"; diff --git a/test-foundry/fuzzing/compound/TestSupplyFuzzing.t.sol b/test-foundry/fuzzing/compound/TestSupplyFuzzing.t.sol index 99cbed180..14dcdf823 100644 --- a/test-foundry/fuzzing/compound/TestSupplyFuzzing.t.sol +++ b/test-foundry/fuzzing/compound/TestSupplyFuzzing.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetupFuzzing.sol"; diff --git a/test-foundry/fuzzing/compound/TestWithdrawFuzzing.t.sol b/test-foundry/fuzzing/compound/TestWithdrawFuzzing.t.sol index a44404383..f58cb3963 100644 --- a/test-foundry/fuzzing/compound/TestWithdrawFuzzing.t.sol +++ b/test-foundry/fuzzing/compound/TestWithdrawFuzzing.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetupFuzzing.sol"; import {Attacker} from "../../compound/helpers/Attacker.sol"; diff --git a/test-foundry/fuzzing/compound/setup/TestSetupFuzzing.sol b/test-foundry/fuzzing/compound/setup/TestSetupFuzzing.sol index a107b1537..f7f824e21 100644 --- a/test-foundry/fuzzing/compound/setup/TestSetupFuzzing.sol +++ b/test-foundry/fuzzing/compound/setup/TestSetupFuzzing.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "@contracts/compound/interfaces/compound/ICompound.sol"; import "@contracts/compound/interfaces/ICompRewardsLens.sol"; diff --git a/test-foundry/prod/aave-v2/TestBorrow.t.sol b/test-foundry/prod/aave-v2/TestBorrow.t.sol index 6ca633d57..40e401bf4 100644 --- a/test-foundry/prod/aave-v2/TestBorrow.t.sol +++ b/test-foundry/prod/aave-v2/TestBorrow.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/prod/aave-v2/TestLens.t.sol b/test-foundry/prod/aave-v2/TestLens.t.sol index fe3df0491..27a929ef2 100644 --- a/test-foundry/prod/aave-v2/TestLens.t.sol +++ b/test-foundry/prod/aave-v2/TestLens.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/prod/aave-v2/TestRepay.t.sol b/test-foundry/prod/aave-v2/TestRepay.t.sol index dcbd54c41..7f4a63bf7 100644 --- a/test-foundry/prod/aave-v2/TestRepay.t.sol +++ b/test-foundry/prod/aave-v2/TestRepay.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/prod/aave-v2/TestSupply.t.sol b/test-foundry/prod/aave-v2/TestSupply.t.sol index 6f54c960a..00965c08b 100644 --- a/test-foundry/prod/aave-v2/TestSupply.t.sol +++ b/test-foundry/prod/aave-v2/TestSupply.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/prod/aave-v2/TestWithdraw.t.sol b/test-foundry/prod/aave-v2/TestWithdraw.t.sol index 83e26a38d..a9ecadd33 100644 --- a/test-foundry/prod/aave-v2/TestWithdraw.t.sol +++ b/test-foundry/prod/aave-v2/TestWithdraw.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/prod/aave-v2/setup/TestSetup.sol b/test-foundry/prod/aave-v2/setup/TestSetup.sol index e1e828929..277f05538 100644 --- a/test-foundry/prod/aave-v2/setup/TestSetup.sol +++ b/test-foundry/prod/aave-v2/setup/TestSetup.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "@contracts/aave-v2/interfaces/aave/IAaveIncentivesController.sol"; import "@contracts/aave-v2/interfaces/aave/IVariableDebtToken.sol"; diff --git a/test-foundry/prod/compound/TestBorrow.t.sol b/test-foundry/prod/compound/TestBorrow.t.sol index 828c03046..748fc8972 100644 --- a/test-foundry/prod/compound/TestBorrow.t.sol +++ b/test-foundry/prod/compound/TestBorrow.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/prod/compound/TestRepay.t.sol b/test-foundry/prod/compound/TestRepay.t.sol index ee4a9a691..1a9834bfe 100644 --- a/test-foundry/prod/compound/TestRepay.t.sol +++ b/test-foundry/prod/compound/TestRepay.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/prod/compound/TestSupply.t.sol b/test-foundry/prod/compound/TestSupply.t.sol index 6320c0841..9048a0322 100644 --- a/test-foundry/prod/compound/TestSupply.t.sol +++ b/test-foundry/prod/compound/TestSupply.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/prod/compound/TestWithdraw.t.sol b/test-foundry/prod/compound/TestWithdraw.t.sol index d1aab59a4..466cf46b8 100644 --- a/test-foundry/prod/compound/TestWithdraw.t.sol +++ b/test-foundry/prod/compound/TestWithdraw.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "./setup/TestSetup.sol"; diff --git a/test-foundry/prod/compound/setup/TestSetup.sol b/test-foundry/prod/compound/setup/TestSetup.sol index 79e37d076..db686fca5 100644 --- a/test-foundry/prod/compound/setup/TestSetup.sol +++ b/test-foundry/prod/compound/setup/TestSetup.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GNU AGPLv3 -pragma solidity 0.8.13; +pragma solidity ^0.8.0; import "@contracts/compound/interfaces/IRewardsManager.sol"; import "@contracts/compound/interfaces/IMorpho.sol";