Skip to content

Commit

Permalink
Merge pull request #6 from morpho-org/test/hardhat-tests
Browse files Browse the repository at this point in the history
test(hardhat): add hardhat tests
  • Loading branch information
MerlinEgalite authored Dec 7, 2023
2 parents 6692ede + af45767 commit 73eddf9
Show file tree
Hide file tree
Showing 14 changed files with 6,565 additions and 10 deletions.
42 changes: 42 additions & 0 deletions .github/workflows/hardhat.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Hardhat

on:
push:
branches:
- main
pull_request:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
cancel-in-progress: true

jobs:
yarn-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
submodules: recursive

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1

- name: Install node
uses: actions/setup-node@v3
with:
node-version: 18
cache: yarn

- name: Install dependencies
run: yarn install --frozen-lockfile

- name: Save hardhat cache
uses: actions/cache@v3
with:
path: |
cache_hardhat
artifacts
key: ${{ github.ref_name }}-hardhat

- name: Run Hardhat tests
run: yarn test:hardhat
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,13 @@ docs/

# Dotenv file
.env

# Node.js
node_modules/

# Hardhat
/types
/cache_hardhat
/artifacts

*.log
5 changes: 5 additions & 0 deletions .husky/post-checkout
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

git submodule update --init --recursive
yarn
5 changes: 5 additions & 0 deletions .husky/post-merge
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

git submodule update --init --recursive
yarn
4 changes: 4 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx lint-staged
4 changes: 4 additions & 0 deletions .husky/prepare-commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

yarn commitlint --edit "${1}"
55 changes: 55 additions & 0 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import * as dotenv from "dotenv";
import "ethers-maths";
import "hardhat-gas-reporter";
import "hardhat-tracer";
import { HardhatUserConfig } from "hardhat/config";
import "solidity-coverage";

import "@nomicfoundation/hardhat-chai-matchers";
import "@nomicfoundation/hardhat-ethers";
import "@nomicfoundation/hardhat-foundry";
import "@nomicfoundation/hardhat-network-helpers";
import "@typechain/hardhat";


dotenv.config();

const config: HardhatUserConfig = {
defaultNetwork: "hardhat",
networks: {
hardhat: {
chainId: 1,
gasPrice: 0,
initialBaseFeePerGas: 0,
allowBlocksWithSameTimestamp: true,
},
},
solidity: {
compilers: [
{
version: "0.8.19",
settings: {
optimizer: {
enabled: true,
runs: 200,
},
viaIR: true,
},
},
],
},
mocha: {
timeout: 3000000,
},
typechain: {
target: "ethers-v6",
outDir: "types/",
externalArtifacts: ["deps/**/*.json"],
},
tracer: {
defaultVerbosity: 1,
gasCost: true,
},
};

export default config;
94 changes: 94 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
{
"name": "morpho-blue-irm",
"description": "Morpho Blue IRM Contracts",
"license": "GPL-2.0-or-later",
"version": "0.0.0",
"main": "lib/index.js",
"bin": "lib/cli.js",
"files": [
"lib/**/*"
],
"scripts": {
"prepare": "husky install && forge install",
"build:forge": "FOUNDRY_PROFILE=build forge build",
"build:hardhat": "npx hardhat compile",
"test:forge": "FOUNDRY_PROFILE=test forge test",
"test:hardhat": "npx hardhat test",
"lint": "yarn lint:forge && yarn lint:ts",
"lint:ts": "prettier --check test/hardhat",
"lint:forge": "forge fmt --check",
"lint:fix": "yarn lint:forge:fix && yarn lint:ts:fix",
"lint:ts:fix": "prettier --write test/hardhat",
"lint:forge:fix": "forge fmt",
"clean": "npx hardhat clean && forge clean"
},
"repository": {
"type": "git",
"url": "git+https://github.com/morpho-org/morpho-blue-irm.git"
},
"author": {
"name": "Morpho Labs",
"email": "security@morpho.org",
"url": "https://github.com/morpho-labs"
},
"bugs": {
"url": "https://github.com/morpho-org/morpho-blue-irm/issues"
},
"homepage": "https://github.com/morpho-org/morpho-blue-irm#readme",
"dependencies": {
"ethers": "^6.7.1",
"ethers-maths": "^4.0.2",
"lodash": "^4.17.21"
},
"devDependencies": {
"@commitlint/cli": "^17.7.1",
"@commitlint/config-conventional": "^17.7.0",
"@nomicfoundation/hardhat-chai-matchers": "^2.0.2",
"@nomicfoundation/hardhat-ethers": "^3.0.4",
"@nomicfoundation/hardhat-foundry": "^1.0.3",
"@nomicfoundation/hardhat-network-helpers": "^1.0.8",
"@trivago/prettier-plugin-sort-imports": "^4.2.0",
"@typechain/ethers-v6": "^0.5.0",
"@typechain/hardhat": "^9.0.0",
"@types/chai": "^4.3.5",
"@types/lodash": "^4.14.197",
"@types/mocha": "^10.0.1",
"@types/node": "^20.5.4",
"chai": "^4.3.7",
"dotenv": "^16.3.1",
"hardhat": "^2.17.1",
"hardhat-gas-reporter": "^1.0.9",
"hardhat-tracer": "^2.6.0",
"husky": "^8.0.3",
"lint-staged": "^14.0.1",
"prettier": "^3.0.2",
"solidity-coverage": "^0.8.4",
"ts-node": "^10.9.1",
"typechain": "^8.3.1",
"typescript": "^5.1.6"
},
"lint-staged": {
"*.sol": "forge fmt",
"*.js": "prettier",
"*.ts": "prettier",
"*.json": "prettier",
"*.yml": "prettier"
},
"commitlint": {
"extends": [
"@commitlint/config-conventional"
]
},
"prettier": {
"printWidth": 120,
"plugins": [
"@trivago/prettier-plugin-sort-imports"
],
"importOrder": [
"^@",
"^\\.\\.",
"^\\."
],
"importOrderSeparation": true
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "../src/AdaptiveCurveIrm.sol";
import "../../src/AdaptiveCurveIrm.sol";

import "../lib/forge-std/src/Test.sol";
import "../../lib/forge-std/src/Test.sol";

contract AdaptiveCurveIrmTest is Test {
using MathLib for int256;
Expand Down
12 changes: 6 additions & 6 deletions test/ExpLibTest.sol → test/forge/ExpLibTest.sol
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {MathLib, WAD_INT} from "../src/libraries/MathLib.sol";
import {ConstantsLib} from "../src/libraries/adaptive-curve/ConstantsLib.sol";
import {ExpLib} from "../src/libraries/adaptive-curve/ExpLib.sol";
import {wadExp} from "../lib/solmate/src/utils/SignedWadMath.sol";
import {MathLib as MorphoMathLib} from "../lib/morpho-blue/src/libraries/MathLib.sol";
import {MathLib, WAD_INT} from "../../src/libraries/MathLib.sol";
import {ConstantsLib} from "../../src/libraries/adaptive-curve/ConstantsLib.sol";
import {ExpLib} from "../../src/libraries/adaptive-curve/ExpLib.sol";
import {wadExp} from "../../lib/solmate/src/utils/SignedWadMath.sol";
import {MathLib as MorphoMathLib} from "../../lib/morpho-blue/src/libraries/MathLib.sol";

import "../lib/forge-std/src/Test.sol";
import "../../lib/forge-std/src/Test.sol";

contract ExpLibTest is Test {
using MathLib for int256;
Expand Down
4 changes: 2 additions & 2 deletions test/UtilsLibTest.sol → test/forge/UtilsLibTest.sol
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "../src/libraries/UtilsLib.sol";
import "../../src/libraries/UtilsLib.sol";

import "../lib/forge-std/src/Test.sol";
import "../../lib/forge-std/src/Test.sol";

contract UtilsTest is Test {
using UtilsLib for int256;
Expand Down
95 changes: 95 additions & 0 deletions test/hardhat/irm/Irm.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { AbiCoder, keccak256, toBigInt } from "ethers";
import hre from "hardhat";
import _range from "lodash/range";
import { AdaptiveCurveIrm } from "types";
import { MarketParamsStruct } from "types/lib/morpho-blue/src/interfaces/IIrm";

import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers";
import { setNextBlockTimestamp } from "@nomicfoundation/hardhat-network-helpers/dist/src/helpers/time";

let seed = 42;
const random = () => {
seed = (seed * 16807) % 2147483647;

return (seed - 1) / 2147483646;
};

const identifier = (marketParams: MarketParamsStruct) => {
const encodedMarket = AbiCoder.defaultAbiCoder().encode(
["address", "address", "address", "address", "uint256"],
Object.values(marketParams),
);

return Buffer.from(keccak256(encodedMarket).slice(2), "hex");
};

const logProgress = (name: string, i: number, max: number) => {
if (i % 10 == 0) console.log("[" + name + "]", Math.floor((100 * i) / max), "%");
};

const randomForwardTimestamp = async () => {
const block = await hre.ethers.provider.getBlock("latest");
const elapsed = random() < 1 / 2 ? 0 : (1 + Math.floor(random() * 100)) * 12; // 50% of the time, don't go forward in time.

const newTimestamp = block!.timestamp + elapsed;

await setNextBlockTimestamp(block!.timestamp + elapsed);

return newTimestamp;
};

describe("irm", () => {
let admin: SignerWithAddress;

let irm: AdaptiveCurveIrm;

let marketParams: MarketParamsStruct;

beforeEach(async () => {
[admin] = await hre.ethers.getSigners();

const AdaptiveCurveIrmFactory = await hre.ethers.getContractFactory("AdaptiveCurveIrm", admin);

irm = await AdaptiveCurveIrmFactory.deploy(
await admin.getAddress(),
4000000000000000000n,
1585489599188n,
900000000000000000n,
317097919n,
);

const irmAddress = await irm.getAddress();

marketParams = {
// Non-zero address to include calldata gas cost.
collateralToken: irmAddress,
loanToken: irmAddress,
oracle: irmAddress,
irm: irmAddress,
lltv: 0,
};

hre.tracer.nameTags[irmAddress] = "IRM";
});

it("should simulate gas cost [main]", async () => {
for (let i = 0; i < 200; ++i) {
logProgress("main", i, 200);

const lastUpdate = await randomForwardTimestamp();

const totalSupplyAssets = BigInt.WAD * toBigInt(1 + Math.floor(random() * 100));
const totalBorrowAssets = totalSupplyAssets.percentMul(toBigInt(Math.floor(random() * BigInt.PERCENT.toFloat())));

await irm.borrowRate(marketParams, {
fee: 0,
lastUpdate,
totalSupplyAssets: totalSupplyAssets,
totalBorrowAssets: totalBorrowAssets,
// Non-zero shares to include calldata gas cost.
totalSupplyShares: 1000000000000n,
totalBorrowShares: 1000000000000n,
});
}
});
});
15 changes: 15 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"compilerOptions": {
"target": "es2020",
"module": "nodenext",
"moduleResolution": "nodenext",
"outDir": "dist",
"baseUrl": ".",
"strict": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"declaration": true
},
"include": ["types", "test/hardhat"],
"files": ["hardhat.config.ts"]
}
Loading

0 comments on commit 73eddf9

Please sign in to comment.