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 @@ + 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/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}, + ); });