From f946ab9aa1c3eaf4f661f068e05dc5d1dae7b3e4 Mon Sep 17 00:00:00 2001 From: Rubilmax Date: Wed, 8 Nov 2023 15:22:13 +0100 Subject: [PATCH 1/2] Revert "build(lib): remove morpho-blue-irm" This reverts commit 08daf4e4600bb96ac0fecbc10d375738673b63b2. --- .gitmodules | 3 +++ lib/morpho-blue-irm | 1 + src/mocks/SpeedJumpIrmMock.sol | 13 +++++++++++++ test/hardhat/EthereumBundler.spec.ts | 12 ++++++------ 4 files changed, 23 insertions(+), 6 deletions(-) create mode 160000 lib/morpho-blue-irm create mode 100644 src/mocks/SpeedJumpIrmMock.sol diff --git a/.gitmodules b/.gitmodules index 435c7f8b..d997284a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -22,3 +22,6 @@ [submodule "lib/murky"] path = lib/murky url = https://github.com/dmfxyz/murky +[submodule "lib/morpho-blue-irm"] + path = lib/morpho-blue-irm + url = https://github.com/morpho-labs/morpho-blue-irm diff --git a/lib/morpho-blue-irm b/lib/morpho-blue-irm new file mode 160000 index 00000000..0e9dc256 --- /dev/null +++ b/lib/morpho-blue-irm @@ -0,0 +1 @@ +Subproject commit 0e9dc256bacdcf7fb0c9ac3c4501d09d4be0086d diff --git a/src/mocks/SpeedJumpIrmMock.sol b/src/mocks/SpeedJumpIrmMock.sol new file mode 100644 index 00000000..91a98110 --- /dev/null +++ b/src/mocks/SpeedJumpIrmMock.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity ^0.8.0; + +import {SpeedJumpIrm} from "../../lib/morpho-blue-irm/src/SpeedJumpIrm.sol"; + +uint256 constant _LN2 = 0.69314718056 ether; +uint256 constant _TARGET_UTILIZATION = 0.8 ether; +uint256 constant _SPEED_FACTOR = uint256(0.01 ether) / uint256(10 hours); +uint128 constant _INITIAL_RATE = uint128(0.01 ether) / uint128(365 days); + +contract SpeedJumpIrmMock is SpeedJumpIrm { + constructor(address morpho) SpeedJumpIrm(morpho, _LN2, _SPEED_FACTOR, _TARGET_UTILIZATION, _INITIAL_RATE) {} +} diff --git a/test/hardhat/EthereumBundler.spec.ts b/test/hardhat/EthereumBundler.spec.ts index 3055a51a..e0c7f111 100644 --- a/test/hardhat/EthereumBundler.spec.ts +++ b/test/hardhat/EthereumBundler.spec.ts @@ -1,7 +1,7 @@ import { AbiCoder, MaxUint256, Signature, keccak256, toBigInt, TypedDataDomain, TypedDataField } from "ethers"; import hre from "hardhat"; import { BundlerAction } from "pkg"; -import { ERC20Mock, ERC4626Mock, EthereumBundler, MorphoMock, OracleMock, IrmMock } from "types"; +import { ERC20Mock, ERC4626Mock, EthereumBundler, MorphoMock, OracleMock, SpeedJumpIrmMock } from "types"; import { MarketParamsStruct } from "types/lib/morpho-blue/src/Morpho"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; @@ -130,7 +130,7 @@ describe("EthereumBundler", () => { let loan: ERC20Mock; let collateral: ERC20Mock; let oracle: OracleMock; - let irm: IrmMock; + let irm: SpeedJumpIrmMock; let morphoAuthorizationConfig: TypedDataConfig; @@ -174,9 +174,9 @@ describe("EthereumBundler", () => { const morphoAddress = await morpho.getAddress(); - const IrmFactory = await hre.ethers.getContractFactory("IrmMock", admin); + const SpeedJumpIrmFactory = await hre.ethers.getContractFactory("SpeedJumpIrmMock", admin); - irm = await IrmFactory.deploy(); + irm = await SpeedJumpIrmFactory.deploy(morphoAddress); morphoAuthorizationConfig = { domain: { chainId: "0x1", verifyingContract: morphoAddress }, @@ -226,7 +226,7 @@ describe("EthereumBundler", () => { hre.tracer.nameTags[collateralAddress] = "Collateral"; hre.tracer.nameTags[loanAddress] = "Loan"; hre.tracer.nameTags[oracleAddress] = "Oracle"; - hre.tracer.nameTags[irmAddress] = "Irm"; + hre.tracer.nameTags[irmAddress] = "SpeedJumpIrm"; hre.tracer.nameTags[bundlerAddress] = "EthereumBundler"; }); @@ -285,7 +285,7 @@ describe("EthereumBundler", () => { ), ), BundlerAction.morphoSupplyCollateral(marketParams, assets, borrower.address, []), - BundlerAction.morphoBorrow(marketParams, assets / 2n, 0, MaxUint256, borrower.address), + BundlerAction.morphoBorrow(marketParams, assets / 2n, 0, borrower.address), ]); } }); From fe15cd8eae33f99ef575312416f45a1abd1717f0 Mon Sep 17 00:00:00 2001 From: Rubilmax Date: Fri, 8 Dec 2023 09:53:07 +0100 Subject: [PATCH 2/2] ci(hardhat): update tests --- .github/workflows/hardhat.yml | 5 ++ lib/morpho-blue-irm | 2 +- src/mocks/AdaptiveCurveIrmMock.sol | 15 ++++++ src/mocks/SpeedJumpIrmMock.sol | 13 ----- test/hardhat/EthereumBundler.spec.ts | 81 +++++++++++++++------------- 5 files changed, 66 insertions(+), 50 deletions(-) create mode 100644 src/mocks/AdaptiveCurveIrmMock.sol delete mode 100644 src/mocks/SpeedJumpIrmMock.sol diff --git a/.github/workflows/hardhat.yml b/.github/workflows/hardhat.yml index 1b2dc0be..efe197ee 100644 --- a/.github/workflows/hardhat.yml +++ b/.github/workflows/hardhat.yml @@ -23,3 +23,8 @@ jobs: - name: Build contracts & package with hardhat uses: ./.github/actions/build-hardhat + + - name: Run hardhat tests + run: yarn test:hardhat + env: + ALCHEMY_KEY: ${{ secrets.ALCHEMY_KEY }} diff --git a/lib/morpho-blue-irm b/lib/morpho-blue-irm index 0e9dc256..73eddf9e 160000 --- a/lib/morpho-blue-irm +++ b/lib/morpho-blue-irm @@ -1 +1 @@ -Subproject commit 0e9dc256bacdcf7fb0c9ac3c4501d09d4be0086d +Subproject commit 73eddf9e09731b75255b51d1ee14a321f5586b42 diff --git a/src/mocks/AdaptiveCurveIrmMock.sol b/src/mocks/AdaptiveCurveIrmMock.sol new file mode 100644 index 00000000..3c6e4e6b --- /dev/null +++ b/src/mocks/AdaptiveCurveIrmMock.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity ^0.8.0; + +import {AdaptiveCurveIrm} from "../../lib/morpho-blue-irm/src/AdaptiveCurveIrm.sol"; + +int256 constant _CURVE_STEEPNESS = 4 ether; +int256 constant _ADJUSTMENT_SPEED = int256(50 ether) / 365 days; +int256 constant _TARGET_UTILIZATION = 0.9 ether; +int256 constant _INITIAL_RATE_AT_TARGET = int256(0.01 ether) / 365 days; + +contract AdaptiveCurveIrmMock is AdaptiveCurveIrm { + constructor(address morpho) + AdaptiveCurveIrm(morpho, _CURVE_STEEPNESS, _ADJUSTMENT_SPEED, _TARGET_UTILIZATION, _INITIAL_RATE_AT_TARGET) + {} +} diff --git a/src/mocks/SpeedJumpIrmMock.sol b/src/mocks/SpeedJumpIrmMock.sol deleted file mode 100644 index 91a98110..00000000 --- a/src/mocks/SpeedJumpIrmMock.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import {SpeedJumpIrm} from "../../lib/morpho-blue-irm/src/SpeedJumpIrm.sol"; - -uint256 constant _LN2 = 0.69314718056 ether; -uint256 constant _TARGET_UTILIZATION = 0.8 ether; -uint256 constant _SPEED_FACTOR = uint256(0.01 ether) / uint256(10 hours); -uint128 constant _INITIAL_RATE = uint128(0.01 ether) / uint128(365 days); - -contract SpeedJumpIrmMock is SpeedJumpIrm { - constructor(address morpho) SpeedJumpIrm(morpho, _LN2, _SPEED_FACTOR, _TARGET_UTILIZATION, _INITIAL_RATE) {} -} diff --git a/test/hardhat/EthereumBundler.spec.ts b/test/hardhat/EthereumBundler.spec.ts index e0c7f111..5ac85303 100644 --- a/test/hardhat/EthereumBundler.spec.ts +++ b/test/hardhat/EthereumBundler.spec.ts @@ -1,7 +1,7 @@ import { AbiCoder, MaxUint256, Signature, keccak256, toBigInt, TypedDataDomain, TypedDataField } from "ethers"; import hre from "hardhat"; import { BundlerAction } from "pkg"; -import { ERC20Mock, ERC4626Mock, EthereumBundler, MorphoMock, OracleMock, SpeedJumpIrmMock } from "types"; +import { ERC20Mock, ERC4626Mock, EthereumBundler, MorphoMock, OracleMock, AdaptiveCurveIrmMock } from "types"; import { MarketParamsStruct } from "types/lib/morpho-blue/src/Morpho"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; @@ -25,32 +25,36 @@ const permit2Config: TypedDataConfig = { verifyingContract: permit2Address, }, types: { - PermitTransferFrom: [ + PermitSingle: [ { - name: "permitted", - type: "TokenPermissions", + name: "details", + type: "PermitDetails", }, { name: "spender", type: "address", }, { - name: "nonce", - type: "uint256", - }, - { - name: "deadline", + name: "sigDeadline", type: "uint256", }, ], - TokenPermissions: [ + PermitDetails: [ { name: "token", type: "address", }, { name: "amount", - type: "uint256", + type: "uint160", + }, + { + name: "expiration", + type: "uint48", + }, + { + name: "nonce", + type: "uint48", }, ], }, @@ -130,7 +134,7 @@ describe("EthereumBundler", () => { let loan: ERC20Mock; let collateral: ERC20Mock; let oracle: OracleMock; - let irm: SpeedJumpIrmMock; + let irm: AdaptiveCurveIrmMock; let morphoAuthorizationConfig: TypedDataConfig; @@ -174,9 +178,9 @@ describe("EthereumBundler", () => { const morphoAddress = await morpho.getAddress(); - const SpeedJumpIrmFactory = await hre.ethers.getContractFactory("SpeedJumpIrmMock", admin); + const AdaptiveCurveIrmFactory = await hre.ethers.getContractFactory("AdaptiveCurveIrmMock", admin); - irm = await SpeedJumpIrmFactory.deploy(morphoAddress); + irm = await AdaptiveCurveIrmFactory.deploy(morphoAddress); morphoAuthorizationConfig = { domain: { chainId: "0x1", verifyingContract: morphoAddress }, @@ -226,7 +230,7 @@ describe("EthereumBundler", () => { hre.tracer.nameTags[collateralAddress] = "Collateral"; hre.tracer.nameTags[loanAddress] = "Loan"; hre.tracer.nameTags[oracleAddress] = "Oracle"; - hre.tracer.nameTags[irmAddress] = "SpeedJumpIrm"; + hre.tracer.nameTags[irmAddress] = "AdaptiveCurveIrm"; hre.tracer.nameTags[bundlerAddress] = "EthereumBundler"; }); @@ -250,14 +254,17 @@ describe("EthereumBundler", () => { deadline: MAX_UINT48, }; - const permit2TransferFrom = { - permitted: { - token: await collateral.getAddress(), + const collateralAddress = await collateral.getAddress(); + + const approve2 = { + details: { + token: collateralAddress, amount: assets, + nonce: 0n, + expiration: MAX_UINT48, }, spender: bundlerAddress, - nonce: 0n, - deadline: MAX_UINT48, + sigDeadline: MAX_UINT48, }; await collateral.connect(borrower).approve(permit2Address, MaxUint256); @@ -278,14 +285,14 @@ describe("EthereumBundler", () => { ), false, ), - BundlerAction.permit2TransferFrom( - permit2TransferFrom, - Signature.from( - await borrower.signTypedData(permit2Config.domain, permit2Config.types, permit2TransferFrom), - ), + BundlerAction.approve2( + approve2, + Signature.from(await borrower.signTypedData(permit2Config.domain, permit2Config.types, approve2)), + false, ), + BundlerAction.transferFrom2(collateralAddress, assets), BundlerAction.morphoSupplyCollateral(marketParams, assets, borrower.address, []), - BundlerAction.morphoBorrow(marketParams, assets / 2n, 0, borrower.address), + BundlerAction.morphoBorrow(marketParams, assets / 2n, 0, borrower.address, borrower.address), ]); } }); @@ -297,15 +304,17 @@ describe("EthereumBundler", () => { const supplier = suppliers[i]; const assets = BigInt.WAD * toBigInt(1 + Math.floor(random() * 100)); + const collateralAddress = await collateral.getAddress(); - const permit2TransferFrom = { - permitted: { - token: await collateral.getAddress(), + const approve2 = { + details: { + token: collateralAddress, amount: assets, + expiration: MAX_UINT48, + nonce: 0n, }, spender: bundlerAddress, - nonce: 0n, - deadline: MAX_UINT48, + sigDeadline: MAX_UINT48, }; await collateral.connect(supplier).approve(permit2Address, MaxUint256); @@ -315,12 +324,12 @@ describe("EthereumBundler", () => { await bundler .connect(supplier) .multicall([ - BundlerAction.permit2TransferFrom( - permit2TransferFrom, - Signature.from( - await supplier.signTypedData(permit2Config.domain, permit2Config.types, permit2TransferFrom), - ), + BundlerAction.approve2( + approve2, + Signature.from(await supplier.signTypedData(permit2Config.domain, permit2Config.types, approve2)), + false, ), + BundlerAction.transferFrom2(collateralAddress, assets), BundlerAction.erc4626Deposit(erc4626Address, assets, 0, supplier.address), ]); }