Skip to content
Closed
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
4 changes: 2 additions & 2 deletions .github/workflows/certora.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ jobs:

- name: Install solc
run: |
wget https://github.com/ethereum/solidity/releases/download/v0.8.19/solc-static-linux
wget https://github.com/ethereum/solidity/releases/download/v0.8.24/solc-static-linux
chmod +x solc-static-linux
sudo mv solc-static-linux /usr/local/bin/solc8.19
sudo mv solc-static-linux /usr/local/bin/solc8.24

- name: Verify rule ${{ matrix.rule }}
run: |
Expand Down
6 changes: 4 additions & 2 deletions certora/confs/rules.conf
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@
"lib/aave-helpers:aave-v3-origin=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin/src",
"aave-v3-origin=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin",
"aave-capo=lib/aave-capo/src",
"lib/aave-capo:cl-synchronicity-price-adapter=lib/aave-capo/lib/cl-synchronicity-price-adapter/src"
"lib/aave-capo:cl-synchronicity-price-adapter=lib/aave-capo/lib/cl-synchronicity-price-adapter/src",
"openzeppelin-contracts-upgradeable=lib/aave-capo/lib/aave-address-book/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable",
"openzeppelin-contracts=lib/aave-capo/lib/aave-address-book/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts"
],
"optimistic_loop": true,
"loop_iter": "2",
"rule_sanity": "basic",
"prover_args": ["-depth 15","-mediumTimeout 1000"],
"smt_timeout": "2000",
"solc": "solc8.19",
"solc": "solc8.24",
"verify": "RiskSteward:certora/specs/rules.spec",
"cache" :"none",
"msg": "RISK-STEWARD::rules"
Expand Down
6 changes: 4 additions & 2 deletions certora/confs/sanity.conf
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
"lib/aave-helpers:aave-v3-origin=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin/src",
"aave-v3-origin=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin",
"aave-capo=lib/aave-capo/src",
"lib/aave-capo:cl-synchronicity-price-adapter=lib/aave-capo/lib/cl-synchronicity-price-adapter/src"
"lib/aave-capo:cl-synchronicity-price-adapter=lib/aave-capo/lib/cl-synchronicity-price-adapter/src",
"openzeppelin-contracts-upgradeable=lib/aave-capo/lib/aave-address-book/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable",
"openzeppelin-contracts=lib/aave-capo/lib/aave-address-book/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts"
],
"optimistic_loop": true,
"prover_args": ["-depth 15","-mediumTimeout 1000"],
"smt_timeout": "2000",
"solc": "solc8.19",
"solc": "solc8.24",
"verify": "RiskSteward:certora/specs/sanity.spec",
"cache" :"none",
"msg": "RISK-STEWARD::sanity"
Expand Down
2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ src = 'src'
test = 'tests'
script = 'scripts'
out = 'out'
solc = '0.8.22'
solc = '0.8.24'
optimizer = true
optimizer_runs = 200
libs = ['lib']
Expand Down
4 changes: 3 additions & 1 deletion generator/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import {capsUpdates} from './features/capsUpdates';
import {rateUpdatesV3} from './features/rateUpdates';
import {collateralsUpdates} from './features/collateralsUpdates';
import {eModeUpdates} from './features/eModeUpdates';
import {lstPriceCapsUpdates} from './features/lstPriceCapsUpdates';
import {stablePriceCapsUpdates} from './features/stablePriceCapsUpdates';
import {generateFiles, writeFiles} from './generator';
Expand Down Expand Up @@ -42,7 +43,8 @@ const FEATURE_MODULES_V3 = [
capsUpdates,
collateralsUpdates,
lstPriceCapsUpdates,
stablePriceCapsUpdates
stablePriceCapsUpdates,
eModeUpdates
];

async function generateDeterministicPoolCache(pool: PoolIdentifier): Promise<PoolCache> {
Expand Down
9 changes: 6 additions & 3 deletions generator/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,12 @@ export function getAssets(pool: PoolIdentifier): string[] {
return Object.keys(assets);
}

export function getEModes(pool: PoolIdentifierV3) {
const eModes = addressBook[pool].E_MODES;
return eModes;
export function getEModes(pool: PoolIdentifierV3): {value: string; id: number}[] {
return Object.keys(addressBook[pool].E_MODES).map((key) => ({
// map the complex type to a string as used in the sol libs
value: addressBook[pool].E_MODES[key].label.toUpperCase().replace(/[^A-Z0-9]+/gi, '_'),
id: key as unknown as number,
}));
}

export function getVersion(pool: PoolIdentifier) {
Expand Down
102 changes: 102 additions & 0 deletions generator/features/__snapshots__/eModeUpdates.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`feature: eModeUpdates > should properly generate files 1`] = `
{
"jsonConfig": "import {ConfigFile} from '../../generator/types';
export const config: ConfigFile = {
rootOptions: {
pools: ['AaveV3Ethereum'],
title: 'test',
shortName: 'Test',
date: '20231023',
author: 'test',
discussion: 'test',
},
poolOptions: {
AaveV3Ethereum: {
configs: {
EMODES_UPDATE: [
{
eModeCategory: 'AaveV3EthereumEModes.ETH_CORRELATED',
ltv: '',
liqThreshold: '50',
liqBonus: '',
label: '',
},
],
},
cache: {blockNumber: 42},
},
},
};
",
"payloads": [
{
"contractName": "AaveV3Ethereum_Test_20231023",
"payload": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {AaveV3EthereumEModes} from 'aave-address-book/AaveV3Ethereum.sol';
import {RiskStewardsEthereum} from '../../../../scripts/networks/RiskStewardsEthereum.s.sol';
import {EngineFlags} from 'aave-v3-origin/src/contracts/extensions/v3-config-engine/EngineFlags.sol';
import {IAaveV3ConfigEngine} from 'aave-v3-origin/src/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol';

/**
* @title test
* @author test
* - discussion: test
* - deploy-command: make run-script contract=src/contracts/updates/20231023_AaveV3Ethereum_Test/AaveV3Ethereum_Test_20231023.sol:AaveV3Ethereum_Test_20231023 network=mainnet broadcast=false generate_diff=true skip_timelock=false
*/
contract AaveV3Ethereum_Test_20231023 is RiskStewardsEthereum {
function name() public pure override returns (string memory) {
return 'AaveV3Ethereum_Test_20231023';
}

function eModeCategoriesUpdates()
public
pure
override
returns (IAaveV3ConfigEngine.EModeCategoryUpdate[] memory)
{
IAaveV3ConfigEngine.EModeCategoryUpdate[]
memory eModeUpdates = new IAaveV3ConfigEngine.EModeCategoryUpdate[](1);

eModeUpdates[0] = IAaveV3ConfigEngine.EModeCategoryUpdate({
eModeCategory: AaveV3EthereumEModes.ETH_CORRELATED,
ltv: EngineFlags.KEEP_CURRENT,
liqThreshold: 50_00,
liqBonus: EngineFlags.KEEP_CURRENT,
label: EngineFlags.KEEP_CURRENT_STRING
});

return eModeUpdates;
}
}
",
"pool": "AaveV3Ethereum",
},
],
}
`;

exports[`feature: eModeUpdates > should return reasonable code 1`] = `
{
"code": {
"fn": [
"function eModeCategoriesUpdates() public pure override returns (IAaveV3ConfigEngine.EModeCategoryUpdate[] memory) {
IAaveV3ConfigEngine.EModeCategoryUpdate[] memory eModeUpdates = new IAaveV3ConfigEngine.EModeCategoryUpdate[](1);

eModeUpdates[0] = IAaveV3ConfigEngine.EModeCategoryUpdate({
eModeCategory: AaveV3EthereumEModes.ETH_CORRELATED,
ltv: EngineFlags.KEEP_CURRENT,
liqThreshold: 50_00,
liqBonus: EngineFlags.KEEP_CURRENT,
label: EngineFlags.KEEP_CURRENT_STRING
});

return eModeUpdates;
}",
],
},
}
`;
37 changes: 37 additions & 0 deletions generator/features/eModeUpdates.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// sum.test.js
import {expect, describe, it} from 'vitest';
import {MOCK_OPTIONS, eModeUpdate} from './mocks/configs';
import {generateFiles} from '../generator';
import {FEATURE, PoolConfigs} from '../types';
import {eModeUpdates} from './eModeUpdates';

describe('feature: eModeUpdates', () => {
it('should return reasonable code', () => {
const output = eModeUpdates.build({
options: MOCK_OPTIONS,
pool: 'AaveV3Ethereum',
cfg: eModeUpdate,
cache: {blockNumber: 42},
});
expect(output).toMatchSnapshot();
});

it('should properly generate files', async () => {
const poolConfigs: PoolConfigs = {
['AaveV3Ethereum']: {
artifacts: [
eModeUpdates.build({
options: {...MOCK_OPTIONS, pools: ['AaveV3Ethereum']},
pool: 'AaveV3Ethereum',
cfg: eModeUpdate,
cache: {blockNumber: 42},
}),
],
configs: {[FEATURE.EMODES_UPDATE]: eModeUpdate},
cache: {blockNumber: 42},
},
};
const files = await generateFiles({...MOCK_OPTIONS, pools: ['AaveV3Ethereum']}, poolConfigs);
expect(files).toMatchSnapshot();
});
});
82 changes: 82 additions & 0 deletions generator/features/eModeUpdates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import {CodeArtifact, FEATURE, FeatureModule} from '../types';
import {eModesSelect} from '../prompts';
import {EModeCategoryUpdate} from './types';
import {stringOrKeepCurrent, stringPrompt} from '../prompts/stringPrompt';
import {percentPrompt, translateJsPercentToSol} from '../prompts/percentPrompt';

async function fetchEmodeCategoryUpdate<T extends boolean>(
eModeCategory: string | number,
required?: T,
): Promise<EModeCategoryUpdate> {
return {
eModeCategory,
ltv: await percentPrompt({
message: 'ltv',
required,
}),
liqThreshold: await percentPrompt({
message: 'liqThreshold',
required,
}),
liqBonus: await percentPrompt({
message: 'liqBonus',
required,
}),
label: await stringPrompt({
message: 'label',
required,
}),
};
}

type EmodeUpdates = EModeCategoryUpdate[];

export const eModeUpdates: FeatureModule<EmodeUpdates> = {
value: FEATURE.EMODES_UPDATE,
description: 'eModeCategoriesUpdates (altering eMode category params)',
async cli({pool}) {
console.log(`Fetching information for EMode category updates on ${pool}`);

const response: EmodeUpdates = [];
const eModeCategories = await eModesSelect({
message: 'Select the eModes you want to amend',
pool,
});

if (eModeCategories) {
for (const eModeCategory of eModeCategories) {
console.log(`collecting info for ${eModeCategory}`);
response.push(await fetchEmodeCategoryUpdate(eModeCategory));
}
}
return response;
},
build({pool, cfg}) {
const response: CodeArtifact = {
code: {
fn: [
`function eModeCategoriesUpdates() public pure override returns (IAaveV3ConfigEngine.EModeCategoryUpdate[] memory) {
IAaveV3ConfigEngine.EModeCategoryUpdate[] memory eModeUpdates = new IAaveV3ConfigEngine.EModeCategoryUpdate[](${
cfg.length
});

${cfg
.map(
(cfg, ix) => `eModeUpdates[${ix}] = IAaveV3ConfigEngine.EModeCategoryUpdate({
eModeCategory: ${cfg.eModeCategory},
ltv: ${translateJsPercentToSol(cfg.ltv)},
liqThreshold: ${translateJsPercentToSol(cfg.liqThreshold)},
liqBonus: ${translateJsPercentToSol(cfg.liqBonus)},
label: ${stringOrKeepCurrent(cfg.label)}
});`,
)
.join('\n')}

return eModeUpdates;
}`,
],
},
};
return response;
},
};
12 changes: 11 additions & 1 deletion generator/features/mocks/configs.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Options} from '../../types';
import {CapsUpdate, CollateralUpdate, RateStrategyUpdate, LstPriceCapUpdate, StablePriceCapUpdate} from '../types';
import {CapsUpdate, CollateralUpdate, RateStrategyUpdate, LstPriceCapUpdate, StablePriceCapUpdate, EModeCategoryUpdate} from '../types';

export const MOCK_OPTIONS: Options = {
pools: ['AaveV3Ethereum'],
Expand Down Expand Up @@ -29,6 +29,16 @@ export const collateralUpdate: CollateralUpdate[] = [
},
];

export const eModeUpdate: EModeCategoryUpdate[] = [
{
eModeCategory: 'AaveV3EthereumEModes.ETH_CORRELATED',
ltv: '',
liqThreshold: '50',
liqBonus: '',
label: '',
},
];

export const rateUpdateV3: RateStrategyUpdate[] = [
{
asset: 'WETH',
Expand Down
9 changes: 9 additions & 0 deletions generator/features/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ export interface CollateralUpdatePartial {

export interface CollateralUpdate extends CollateralUpdatePartial, AssetSelector {}

export interface EModeCategoryUpdate {
// library accessor or new id
eModeCategory: string | number;
ltv: NumberInputValues;
liqThreshold: NumberInputValues;
liqBonus: NumberInputValues;
label: string;
}

export interface RateStrategyParams {
optimalUtilizationRate: string;
baseVariableBorrowRate: string;
Expand Down
15 changes: 4 additions & 11 deletions generator/prompts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,10 @@ export async function eModeSelect<T extends boolean>({
pool,
}: EModeSelectPrompt<T>) {
const eModes = getEModes(pool as any);
if (Object.keys(eModes).length != 0) {
if (eModes.length != 0) {
const eMode = await select({
message,
choices: [
...(disableKeepCurrent ? [] : [{value: ENGINE_FLAGS.KEEP_CURRENT}]),
...Object.keys(eModes).map((eMode) => ({value: eMode})),
],
choices: eModes,
});
return translateEModeToEModeLib(eMode, pool);
} else {
Expand All @@ -51,14 +48,10 @@ export async function eModeSelect<T extends boolean>({

export async function eModesSelect<T extends boolean>({message, pool}: EModeSelectPrompt<T>) {
const eModes = getEModes(pool as any);
if (Object.keys(eModes).length != 0) {
if (eModes.length != 0) {
const values = await checkbox({
message,
choices: [
...Object.keys(eModes)
.filter((e) => e != 'NONE')
.map((eMode) => ({value: eMode})),
],
choices: eModes,
required: true,
});
return values.map((mode) => translateEModeToEModeLib(mode, pool));
Expand Down
1 change: 1 addition & 0 deletions generator/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export type CodeArtifact = {

export enum FEATURE {
CAPS_UPDATE = 'CAPS_UPDATE',
EMODES_UPDATE = 'EMODES_UPDATE',
COLLATERALS_UPDATE = 'COLLATERALS_UPDATE',
RATE_UPDATE_V3 = 'RATE_UPDATE_V3',
LST_PRICE_CAP_UPDATE = 'LST_PRICE_CAP_UPDATE',
Expand Down
Loading
Loading