diff --git a/.assets/0d62f0b0c1bf55e0693fd4e1b0116731fd62a430.svg b/.assets/0d62f0b0c1bf55e0693fd4e1b0116731fd62a430.svg
new file mode 100644
index 0000000..403a5e0
--- /dev/null
+++ b/.assets/0d62f0b0c1bf55e0693fd4e1b0116731fd62a430.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/.assets/15265298aa7a998c6931ace04e7860b8b360a5ba.svg b/.assets/15265298aa7a998c6931ace04e7860b8b360a5ba.svg
new file mode 100644
index 0000000..3c15ce1
--- /dev/null
+++ b/.assets/15265298aa7a998c6931ace04e7860b8b360a5ba.svg
@@ -0,0 +1 @@
+ Borrow APR, variableBorrow APR, stable0%25%50%75%100%0%100%200%300%Optimal utilization 45%Optimal utilization 45%
\ No newline at end of file
diff --git a/.assets/221c424012f6b8f7d49339c1ad1f6d8be7814e8f.svg b/.assets/221c424012f6b8f7d49339c1ad1f6d8be7814e8f.svg
new file mode 100644
index 0000000..6af590b
--- /dev/null
+++ b/.assets/221c424012f6b8f7d49339c1ad1f6d8be7814e8f.svg
@@ -0,0 +1 @@
+ Borrow APR, variableBorrow APR, stable0%25%50%75%100%0%50%100%Optimal utilization 90%Optimal utilization 90%
\ No newline at end of file
diff --git a/.assets/2493d3ef35333192ec820f1bc848b5189674555c.svg b/.assets/2493d3ef35333192ec820f1bc848b5189674555c.svg
new file mode 100644
index 0000000..5212f2d
--- /dev/null
+++ b/.assets/2493d3ef35333192ec820f1bc848b5189674555c.svg
@@ -0,0 +1 @@
+ Borrow APR, variableBorrow APR, stable0%25%50%75%100%0%50%100%Optimal utilization 45%Optimal utilization 45%
\ No newline at end of file
diff --git a/.assets/32f0ae5f67532a528e6b3d83623f49f7646148c3.svg b/.assets/32f0ae5f67532a528e6b3d83623f49f7646148c3.svg
new file mode 100644
index 0000000..d348fb2
--- /dev/null
+++ b/.assets/32f0ae5f67532a528e6b3d83623f49f7646148c3.svg
@@ -0,0 +1 @@
+ Borrow APR, variableBorrow APR, stable0%25%50%75%100%0%50%100%Optimal utilization 80%Optimal utilization 80%
\ No newline at end of file
diff --git a/.assets/3a6b85c50b6d8a3cac78bba7acc69af991e8b359.svg b/.assets/3a6b85c50b6d8a3cac78bba7acc69af991e8b359.svg
new file mode 100644
index 0000000..93fde99
--- /dev/null
+++ b/.assets/3a6b85c50b6d8a3cac78bba7acc69af991e8b359.svg
@@ -0,0 +1 @@
+ Borrow APR, variableBorrow APR, stable0%25%50%75%100%0%50%100%150%200%Optimal utilization 80%Optimal utilization 80%
\ No newline at end of file
diff --git a/.assets/5d6681206ba1647c8da5212801c687932059c1c3.svg b/.assets/5d6681206ba1647c8da5212801c687932059c1c3.svg
new file mode 100644
index 0000000..d003381
--- /dev/null
+++ b/.assets/5d6681206ba1647c8da5212801c687932059c1c3.svg
@@ -0,0 +1 @@
+ Borrow APR, variableBorrow APR, stable0%25%50%75%100%0%Optimal utilization 90%Optimal utilization 90%
\ No newline at end of file
diff --git a/.assets/63ce7a55ac04d754c31aada64a733b5a0ecd6dd5.svg b/.assets/63ce7a55ac04d754c31aada64a733b5a0ecd6dd5.svg
new file mode 100644
index 0000000..4a059d9
--- /dev/null
+++ b/.assets/63ce7a55ac04d754c31aada64a733b5a0ecd6dd5.svg
@@ -0,0 +1 @@
+ Borrow APR, variableBorrow APR, stable0%25%50%75%100%0%20%40%60%80%Optimal utilization 90%Optimal utilization 90%
\ No newline at end of file
diff --git a/.assets/6554df8148ba17f5ffc961aea7512567c91e2a3d.svg b/.assets/6554df8148ba17f5ffc961aea7512567c91e2a3d.svg
new file mode 100644
index 0000000..df22600
--- /dev/null
+++ b/.assets/6554df8148ba17f5ffc961aea7512567c91e2a3d.svg
@@ -0,0 +1 @@
+ Borrow APR, variableBorrow APR, stable0%25%50%75%100%0%100%200%300%Optimal utilization 45%Optimal utilization 45%
\ No newline at end of file
diff --git a/.assets/6c89ad3b3ce52cc75ae008e02f0902e656628a29.svg b/.assets/6c89ad3b3ce52cc75ae008e02f0902e656628a29.svg
new file mode 100644
index 0000000..f9bccbd
--- /dev/null
+++ b/.assets/6c89ad3b3ce52cc75ae008e02f0902e656628a29.svg
@@ -0,0 +1 @@
+ Borrow APR, variableBorrow APR, stable0%25%50%75%100%0%100%200%300%Optimal utilization 70%Optimal utilization 70%
\ No newline at end of file
diff --git a/.assets/6e4db5711739fa231386033bdb64a3cceb8462a8.svg b/.assets/6e4db5711739fa231386033bdb64a3cceb8462a8.svg
new file mode 100644
index 0000000..ad84fcb
--- /dev/null
+++ b/.assets/6e4db5711739fa231386033bdb64a3cceb8462a8.svg
@@ -0,0 +1 @@
+ Borrow APR, variableBorrow APR, stable0%25%50%75%100%0%50%100%Optimal utilization 80%Optimal utilization 80%
\ No newline at end of file
diff --git a/.assets/794e0d79fec49d4d84b9250e643f1773f16214a5.svg b/.assets/794e0d79fec49d4d84b9250e643f1773f16214a5.svg
new file mode 100644
index 0000000..48159d2
--- /dev/null
+++ b/.assets/794e0d79fec49d4d84b9250e643f1773f16214a5.svg
@@ -0,0 +1 @@
+ Borrow APR, variableBorrow APR, stable0%25%50%75%100%0%50%100%Optimal utilization 80%Optimal utilization 80%
\ No newline at end of file
diff --git a/.assets/7fd6d26d5c1caf9a8735a932555ad64bcb400031.svg b/.assets/7fd6d26d5c1caf9a8735a932555ad64bcb400031.svg
new file mode 100644
index 0000000..a7eaa7d
--- /dev/null
+++ b/.assets/7fd6d26d5c1caf9a8735a932555ad64bcb400031.svg
@@ -0,0 +1 @@
+ Borrow APR, variableBorrow APR, stable0%25%50%75%100%0%50%100%Optimal utilization 80%Optimal utilization 80%
\ No newline at end of file
diff --git a/.assets/8748d80179d57144859fe9a7186b742ec3e9387c.svg b/.assets/8748d80179d57144859fe9a7186b742ec3e9387c.svg
new file mode 100644
index 0000000..5dff155
--- /dev/null
+++ b/.assets/8748d80179d57144859fe9a7186b742ec3e9387c.svg
@@ -0,0 +1 @@
+ Borrow APR, variableBorrow APR, stable0%25%50%75%100%0%100%200%300%Optimal utilization 45%Optimal utilization 45%
\ No newline at end of file
diff --git a/.assets/a1a7ab1f1b9fcdf6ffa41ac7a8b4daf2daf98328.svg b/.assets/a1a7ab1f1b9fcdf6ffa41ac7a8b4daf2daf98328.svg
new file mode 100644
index 0000000..7a92d3f
--- /dev/null
+++ b/.assets/a1a7ab1f1b9fcdf6ffa41ac7a8b4daf2daf98328.svg
@@ -0,0 +1 @@
+ Borrow APR, variableBorrow APR, stable0%25%50%75%100%0%2%4%6%Optimal utilization 99%Optimal utilization 99%
\ No newline at end of file
diff --git a/.assets/a8fcef60b1dfb35de994f96040b1b43df9719d28.svg b/.assets/a8fcef60b1dfb35de994f96040b1b43df9719d28.svg
new file mode 100644
index 0000000..81a6b4f
--- /dev/null
+++ b/.assets/a8fcef60b1dfb35de994f96040b1b43df9719d28.svg
@@ -0,0 +1 @@
+ Borrow APR, variableBorrow APR, stable0%25%50%75%100%0%20%40%60%80%Optimal utilization 92%Optimal utilization 92%
\ No newline at end of file
diff --git a/.assets/c1690b11066430bfb069e06227cc53f8654a7b5a.svg b/.assets/c1690b11066430bfb069e06227cc53f8654a7b5a.svg
new file mode 100644
index 0000000..d009aef
--- /dev/null
+++ b/.assets/c1690b11066430bfb069e06227cc53f8654a7b5a.svg
@@ -0,0 +1 @@
+ Borrow APR, variableBorrow APR, stable0%25%50%75%100%0%100%200%300%Optimal utilization 35%Optimal utilization 35%
\ No newline at end of file
diff --git a/.assets/e03975867d1c729d1a52bbec364211baff2dab5a.svg b/.assets/e03975867d1c729d1a52bbec364211baff2dab5a.svg
new file mode 100644
index 0000000..8a87496
--- /dev/null
+++ b/.assets/e03975867d1c729d1a52bbec364211baff2dab5a.svg
@@ -0,0 +1 @@
+ Borrow APR, variableBorrow APR, stable0%25%50%75%100%0%2%4%6%8%Optimal utilization 99%Optimal utilization 99%
\ No newline at end of file
diff --git a/.assets/e231a10768e2145bf6969b6e65d7c875df780821.svg b/.assets/e231a10768e2145bf6969b6e65d7c875df780821.svg
new file mode 100644
index 0000000..85a5bf3
--- /dev/null
+++ b/.assets/e231a10768e2145bf6969b6e65d7c875df780821.svg
@@ -0,0 +1 @@
+ Borrow APR, variableBorrow APR, stable0%25%50%75%100%0%20%40%60%80%Optimal utilization 90%Optimal utilization 90%
\ No newline at end of file
diff --git a/.assets/e3cd41bda67a1fc3ece7a4100d0a7455722f244a.svg b/.assets/e3cd41bda67a1fc3ece7a4100d0a7455722f244a.svg
new file mode 100644
index 0000000..e82eb34
--- /dev/null
+++ b/.assets/e3cd41bda67a1fc3ece7a4100d0a7455722f244a.svg
@@ -0,0 +1 @@
+ Borrow APR, variableBorrow APR, stable0%25%50%75%100%0%20%40%60%80%Optimal utilization 92%Optimal utilization 92%
\ No newline at end of file
diff --git a/src/reports/__snapshots__/report.spec.ts.snap b/src/reports/__snapshots__/report.spec.ts.snap
index f5e1811..20e0da2 100644
--- a/src/reports/__snapshots__/report.spec.ts.snap
+++ b/src/reports/__snapshots__/report.spec.ts.snap
@@ -296,7 +296,7 @@ exports[`report > should generate a well formatted report 1`] = `
\`\`\`"
`;
-exports[`report > should generate a well formatted report for 3.1 1`] = `
+exports[`report > should generate a well formatted report for 3.0 to 3.1 1`] = `
"## Reserve changes
### Reserve altered
@@ -439,3 +439,93 @@ exports[`report > should generate a well formatted report for 3.1 1`] = `
}
\`\`\`"
`;
+
+exports[`report > should generate a well formatted report for 3.1 1`] = `
+"## Reserve changes
+
+### Reserve altered
+
+#### GHO ([0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f](https://etherscan.io/address/0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f))
+
+| description | value before | value after |
+| --- | --- | --- |
+| maxVariableBorrowRate | 7 % | 6 % |
+| baseVariableBorrowRate | 7 % | 6 % |
+| interestRate | ![before](/.assets/e03975867d1c729d1a52bbec364211baff2dab5a.svg) | ![after](/.assets/a1a7ab1f1b9fcdf6ffa41ac7a8b4daf2daf98328.svg) |
+
+#### wstETH ([0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0](https://etherscan.io/address/0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0))
+
+| description | value before | value after |
+| --- | --- | --- |
+| eMode.liquidationBonus | 1 % | 2 % |
+
+
+#### ETHx ([0xA35b1B31Ce002FBF2058D22F30f95D405200A15b](https://etherscan.io/address/0xA35b1B31Ce002FBF2058D22F30f95D405200A15b))
+
+| description | value before | value after |
+| --- | --- | --- |
+| eMode.liquidationBonus | 1 % | 2 % |
+
+
+#### cbETH ([0xBe9895146f7AF43049ca1c1AE358B0541Ea49704](https://etherscan.io/address/0xBe9895146f7AF43049ca1c1AE358B0541Ea49704))
+
+| description | value before | value after |
+| --- | --- | --- |
+| eMode.liquidationBonus | 1 % | 2 % |
+
+
+#### WETH ([0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2](https://etherscan.io/address/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2))
+
+| description | value before | value after |
+| --- | --- | --- |
+| eMode.liquidationBonus | 1 % | 2 % |
+
+
+#### weETH ([0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee](https://etherscan.io/address/0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee))
+
+| description | value before | value after |
+| --- | --- | --- |
+| eMode.liquidationBonus | 1 % | 2 % |
+
+
+#### rETH ([0xae78736Cd615f374D3085123A210448E74Fc6393](https://etherscan.io/address/0xae78736Cd615f374D3085123A210448E74Fc6393))
+
+| description | value before | value after |
+| --- | --- | --- |
+| eMode.liquidationBonus | 1 % | 2 % |
+
+
+#### osETH ([0xf1C9acDc66974dFB6dEcB12aA385b9cD01190E38](https://etherscan.io/address/0xf1C9acDc66974dFB6dEcB12aA385b9cD01190E38))
+
+| description | value before | value after |
+| --- | --- | --- |
+| eMode.liquidationBonus | 1 % | 2 % |
+
+
+## Raw diff
+
+\`\`\`json
+{
+ "eModes": {
+ "1": {
+ "liquidationBonus": {
+ "from": 10100,
+ "to": 10200
+ }
+ }
+ },
+ "strategies": {
+ "0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f": {
+ "baseVariableBorrowRate": {
+ "from": "70000000000000000000000000",
+ "to": "60000000000000000000000000"
+ },
+ "maxVariableBorrowRate": {
+ "from": "70000000000000000000000000",
+ "to": "60000000000000000000000000"
+ }
+ }
+ }
+}
+\`\`\`"
+`;
diff --git a/src/reports/diff-reports.ts b/src/reports/diff-reports.ts
index f95dae7..28e6224 100644
--- a/src/reports/diff-reports.ts
+++ b/src/reports/diff-reports.ts
@@ -6,6 +6,16 @@ import {renderReserve, renderReserveDiff} from './reserve';
import {AaveV3Reserve, type AaveV3Snapshot} from './snapshot-types';
import {renderStrategy, renderStrategyDiff} from './strategy';
+function hasDiff(input: Record): boolean {
+ if (!input) return false;
+ return !!Object.keys(input).find(
+ (key) =>
+ typeof input[key as keyof typeof input] === 'object' &&
+ (input[key as keyof typeof input].hasOwnProperty('from') ||
+ input[key as keyof typeof input].hasOwnProperty('to')),
+ );
+}
+
export async function diffReports(
pre: A,
post: B,
@@ -53,26 +63,35 @@ export async function diffReports i);
const reservesAltered = Object.keys(diffResult.reserves)
.map((reserveKey) => {
- // from being present on key means reserve was removed
- if (
- !(diffResult.reserves[reserveKey] as any).hasOwnProperty('from') &&
- Object.keys(diffResult.reserves[reserveKey]).find(
- (fieldKey) => typeof (diffResult.reserves as any)[reserveKey][fieldKey] === 'object',
+ // "from" being present on reserses key means reserve was removed
+ if (!(diffResult.reserves[reserveKey] as any).hasOwnProperty('from')) {
+ const hasChangedReserveProperties = hasDiff(diffResult.reserves[reserveKey]);
+ const preIrHash = hash(pre.strategies[reserveKey]);
+ const postIrHash = hash(post.strategies[reserveKey]);
+ const hasChangedIr = preIrHash !== postIrHash;
+ const eModeCategoryChanged =
+ diffResult.reserves[reserveKey].eModeCategory?.hasOwnProperty('from');
+ const eModeParamsChanged =
+ !eModeCategoryChanged &&
+ hasDiff(diffResult.eModes?.[diffResult.reserves[reserveKey].eModeCategory as any]);
+ if (
+ !hasChangedReserveProperties &&
+ !hasChangedIr &&
+ !eModeCategoryChanged &&
+ !eModeParamsChanged
)
- ) {
+ return;
// diff reserve
let report = renderReserveDiff(diffResult.reserves[reserveKey] as any, chainId);
// diff irs
- const preIrHash = hash(pre.strategies[reserveKey]);
- const postIrHash = hash(post.strategies[reserveKey]);
- if (preIrHash !== postIrHash) {
+ if (hasChangedIr) {
report += renderStrategyDiff(
diff(pre.strategies[reserveKey], post.strategies[reserveKey]) as any,
);
report += `| interestRate | ![before](/.assets/${preIrHash}.svg) | ![after](/.assets/${postIrHash}.svg) |`;
}
// diff eModes
- if (diffResult.reserves[reserveKey].eModeCategory?.hasOwnProperty('from')) {
+ if (eModeCategoryChanged) {
report += renderEmodeDiff(
diff(
pre.eModes[(diffResult.reserves[reserveKey].eModeCategory as any).from] || {},
@@ -81,6 +100,15 @@ export async function diffReports {
{timeout: 30000},
);
it(
- 'should generate a well formatted report for 3.1',
+ 'should generate a well formatted report for 3.0 to 3.1',
async () => {
const from = readJsonFile('/src/reports/mocks/pre3-1.json');
const to = readJsonFile('/src/reports/mocks/post3-1.json');
@@ -25,4 +25,15 @@ describe('report', () => {
},
{timeout: 30000},
);
+ it(
+ 'should generate a well formatted report for 3.1',
+ async () => {
+ const from = readJsonFile('/src/reports/mocks/pregho.json');
+ const to = readJsonFile('/src/reports/mocks/postgho.json');
+ const content = await diffReports(from, to);
+ console.log(content);
+ expect(content).toMatchSnapshot();
+ },
+ {timeout: 30000},
+ );
});