Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update post-cantina #381

Merged
merged 4 commits into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/hardhat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -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
1 change: 1 addition & 0 deletions lib/morpho-blue-irm
Submodule morpho-blue-irm added at 73eddf
15 changes: 15 additions & 0 deletions src/mocks/AdaptiveCurveIrmMock.sol
Original file line number Diff line number Diff line change
@@ -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)
{}
}
81 changes: 45 additions & 36 deletions test/hardhat/EthereumBundler.spec.ts
Original file line number Diff line number Diff line change
@@ -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, AdaptiveCurveIrmMock } from "types";
import { MarketParamsStruct } from "types/lib/morpho-blue/src/Morpho";

import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers";
Expand All @@ -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",
},
],
},
Expand Down Expand Up @@ -130,7 +134,7 @@ describe("EthereumBundler", () => {
let loan: ERC20Mock;
let collateral: ERC20Mock;
let oracle: OracleMock;
let irm: IrmMock;
let irm: AdaptiveCurveIrmMock;

let morphoAuthorizationConfig: TypedDataConfig;

Expand Down Expand Up @@ -174,9 +178,9 @@ describe("EthereumBundler", () => {

const morphoAddress = await morpho.getAddress();

const IrmFactory = await hre.ethers.getContractFactory("IrmMock", admin);
const AdaptiveCurveIrmFactory = await hre.ethers.getContractFactory("AdaptiveCurveIrmMock", admin);

irm = await IrmFactory.deploy();
irm = await AdaptiveCurveIrmFactory.deploy(morphoAddress);

morphoAuthorizationConfig = {
domain: { chainId: "0x1", verifyingContract: morphoAddress },
Expand Down Expand Up @@ -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] = "Irm";
hre.tracer.nameTags[irmAddress] = "AdaptiveCurveIrm";
hre.tracer.nameTags[bundlerAddress] = "EthereumBundler";
});

Expand All @@ -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);
Expand All @@ -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, MaxUint256, borrower.address),
BundlerAction.morphoBorrow(marketParams, assets / 2n, 0, borrower.address, borrower.address),
]);
}
});
Expand All @@ -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);
Expand All @@ -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),
]);
}
Expand Down