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

feat: generate specification #30

Merged
merged 4 commits into from
Nov 9, 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
33 changes: 16 additions & 17 deletions generator/features/__snapshots__/assetListing.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ Copyright and related rights waived via [CC0](https://creativecommons.org/public
\\"liqBonus\\": \\"5_00\\",
\\"debtCeiling\\": \\"100_000\\",
\\"liqProtocolFee\\": \\"20_00\\",
\\"enabledToBorrow\\": \\"EngineFlags.ENABLED\\",
\\"flashloanable\\": \\"EngineFlags.ENABLED\\",
\\"stableRateModeEnabled\\": \\"EngineFlags.DISABLED\\",
\\"borrowableInIsolation\\": \\"EngineFlags.DISABLED\\",
\\"withSiloedBorrowing\\": \\"EngineFlags.DISABLED\\",
\\"enabledToBorrow\\": \\"ENABLED\\",
\\"flashloanable\\": \\"ENABLED\\",
\\"stableRateModeEnabled\\": \\"DISABLED\\",
\\"borrowableInIsolation\\": \\"DISABLED\\",
\\"withSiloedBorrowing\\": \\"DISABLED\\",
\\"reserveFactor\\": \\"20_00\\",
\\"supplyCap\\": \\"10_000\\",
\\"borrowCap\\": \\"5_000\\",
Expand Down Expand Up @@ -88,7 +88,6 @@ pragma solidity ^0.8.0;

import {AaveV3Ethereum, AaveV3EthereumEModes} from 'aave-address-book/AaveV3Ethereum.sol';
import {AaveV3PayloadEthereum} from 'aave-helpers/v3-config-engine/AaveV3PayloadEthereum.sol';
import {EngineFlags} from 'aave-helpers/v3-config-engine/EngineFlags.sol';
import {IAaveV3ConfigEngine} from 'aave-helpers/v3-config-engine/IAaveV3ConfigEngine.sol';
import {IV3RateStrategyFactory} from 'aave-helpers/v3-config-engine/IV3RateStrategyFactory.sol';
import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol';
Expand Down Expand Up @@ -119,11 +118,11 @@ contract AaveV3Ethereum_Test_20231023 is AaveV3PayloadEthereum {
assetSymbol: 'PSP',
priceFeed: 0x72AFAECF99C9d9C8215fF44C77B94B99C28741e8,
eModeCategory: AaveV3EthereumEModes.NONE,
enabledToBorrow: EngineFlags.ENABLED,
stableRateModeEnabled: EngineFlags.DISABLED,
borrowableInIsolation: EngineFlags.DISABLED,
withSiloedBorrowing: EngineFlags.DISABLED,
flashloanable: EngineFlags.ENABLED,
enabledToBorrow: ENABLED,
stableRateModeEnabled: DISABLED,
borrowableInIsolation: DISABLED,
withSiloedBorrowing: DISABLED,
flashloanable: ENABLED,
ltv: 40_00,
liqThreshold: 50_00,
liqBonus: 5_00,
Expand Down Expand Up @@ -168,7 +167,7 @@ contract AaveV3Ethereum_Test_20231023_Test is ProtocolV3TestBase {
AaveV3Ethereum_Test_20231023 internal proposal;

function setUp() public {
vm.createSelectFork(vm.rpcUrl('mainnet'), 18487480);
vm.createSelectFork(vm.rpcUrl('mainnet'), 18533234);
proposal = new AaveV3Ethereum_Test_20231023();
}

Expand Down Expand Up @@ -263,11 +262,11 @@ exports[`feature: assetListing > should return reasonable code 1`] = `
assetSymbol: \\"PSP\\",
priceFeed: 0x72AFAECF99C9d9C8215fF44C77B94B99C28741e8,
eModeCategory: AaveV3EthereumEModes.NONE,
enabledToBorrow: EngineFlags.ENABLED,
stableRateModeEnabled: EngineFlags.DISABLED,
borrowableInIsolation: EngineFlags.DISABLED,
withSiloedBorrowing: EngineFlags.DISABLED,
flashloanable: EngineFlags.ENABLED,
enabledToBorrow: ENABLED,
stableRateModeEnabled: DISABLED,
borrowableInIsolation: DISABLED,
withSiloedBorrowing: DISABLED,
flashloanable: ENABLED,
ltv: 40_00,
liqThreshold: 50_00,
liqBonus: 5_00,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ contract AaveV3Ethereum_Test_20231023_Test is ProtocolV3TestBase {
AaveV3Ethereum_Test_20231023 internal proposal;

function setUp() public {
vm.createSelectFork(vm.rpcUrl('mainnet'), 18487480);
vm.createSelectFork(vm.rpcUrl('mainnet'), 18533234);
proposal = new AaveV3Ethereum_Test_20231023();
}

Expand Down
37 changes: 35 additions & 2 deletions generator/features/assetListing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,39 @@ export const assetListing: FeatureModule<Listing[]> = {
}`
),
},
// aip: {
// specification: cfg.map((cfg) => {
// let listingTemplate = `The table below illustrates the configured risk parameters for **${cfg.assetSymbol}**\n\n`;
// listingTemplate += `| Parameter | Value |\n`;
// listingTemplate += `| --- | --: |\n`;
// listingTemplate += `| Isolation Mode | ${!!cfg.debtCeiling} |\n`;
// listingTemplate += `| Borrowable | ${cfg.enabledToBorrow} |\n`;
// listingTemplate += `| Collateral Enabled | ${!!cfg.liqThreshold} |\n`;
// listingTemplate += `| Supply Cap (${cfg.assetSymbol}) | ${cfg.supplyCap} |\n`;
// listingTemplate += `| Borrow Cap (${cfg.assetSymbol}) | ${cfg.borrowCap} |\n`;
// listingTemplate += `| Debt Ceiling | ${cfg.debtCeiling} |\n`;
// listingTemplate += `| LTV | ${cfg.ltv} |\n`;
// listingTemplate += `| LT | ${cfg.liqThreshold} |\n`;
// listingTemplate += `| Liquidation Bonus | ${cfg.liqBonus} |\n`;
// listingTemplate += `| Liquidation Protocol Fee | ${cfg.liqProtocolFee} |\n`;
// listingTemplate += `| Reserve Factor | ${cfg.reserveFactor} |\n`;
// listingTemplate += `| Base Variable Borrow Rate | ${cfg.rateStrategyParams.baseVariableBorrowRate} |\n`;
// listingTemplate += `| Variable Slope 1 | ${cfg.rateStrategyParams.variableRateSlope1} |\n`;
// listingTemplate += `| Variable Slope 2 | ${cfg.rateStrategyParams.variableRateSlope2} |\n`;
// listingTemplate += `| Uoptimal | ${cfg.rateStrategyParams.optimalUtilizationRate} |\n`;
// listingTemplate += `| Stable Borrowing | ${cfg.stableRateModeEnabled} |\n`;
// listingTemplate += `| Stable Slope1 | ${cfg.rateStrategyParams.stableRateSlope1} |\n`;
// listingTemplate += `| Stable Slope2 | ${cfg.rateStrategyParams.stableRateSlope2} |\n`;
// listingTemplate += `| Base Stable Rate Offset | ${cfg.rateStrategyParams.baseStableRateOffset} |\n`;
// listingTemplate += `| Stable Rate Excess Offset | ${cfg.rateStrategyParams.stableRateExcessOffset} |\n`;
// listingTemplate += `| Optimal Stable To Total Debt Ratio | ${cfg.rateStrategyParams.optimalStableToTotalDebtRatio} |\n`;
// listingTemplate += `| Flahloanable | ${cfg.flashloanable} |\n`;
// listingTemplate += `| Siloed Borrowing | ${cfg.withSiloedBorrowing} |\n`;
// listingTemplate += `| Borrowable in Isolation | ${cfg.borrowableInIsolation} |\n`;
// listingTemplate += `| Oracle | ${cfg.priceFeed} |\n`;
// return listingTemplate;
// }),
// },
};
return response;
},
Expand Down Expand Up @@ -210,8 +243,8 @@ export const assetListingCustom: FeatureModule<ListingWithCustomImpl[]> = {
.map(
(cfg, ix) => `listings[${ix}] = IAaveV3ConfigEngine.ListingWithCustomImpl(
IAaveV3ConfigEngine.Listing({
asset: ${cfg.base.assetSymbol},
assetSymbol: "${cfg.base.assetSymbol}",
asset: ${cfg.base.assetSymbol},
assetSymbol: "${cfg.base.assetSymbol}",
priceFeed: ${translateJsAddressToSol(cfg.base.priceFeed)},
eModeCategory: ${cfg.base.eModeCategory},
enabledToBorrow: ${cfg.base.enabledToBorrow},
Expand Down
37 changes: 19 additions & 18 deletions generator/features/borrowsUpdates.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,40 @@
import {CodeArtifact, ENGINE_FLAGS, FEATURE, FeatureModule} from '../types';
import {booleanSelect, percentInput} from '../prompts';
import {percentInput} from '../prompts';
import {BorrowUpdate} from './types';
import {
assetsSelectPrompt,
translateAssetToAssetLibUnderlying,
} from '../prompts/assetsSelectPrompt';
import {boolPrompt, translateJsBoolToSol} from '../prompts/boolPrompt';

export async function fetchBorrowUpdate<T extends boolean>(disableKeepCurrent?: T) {
export async function fetchBorrowUpdate<T extends boolean>(required?: T) {
return {
enabledToBorrow: await booleanSelect({
enabledToBorrow: await boolPrompt({
message: 'enabled to borrow',
disableKeepCurrent,
required,
}),
flashloanable: await booleanSelect({
flashloanable: await boolPrompt({
message: 'flashloanable',
disableKeepCurrent,
required,
}),
stableRateModeEnabled: await booleanSelect({
stableRateModeEnabled: await boolPrompt({
message: 'stable rate mode enabled',
disableKeepCurrent,
required,
defaultValue: ENGINE_FLAGS.DISABLED,
}),
borrowableInIsolation: await booleanSelect({
borrowableInIsolation: await boolPrompt({
message: 'borrowable in isolation',
disableKeepCurrent,
required,
defaultValue: ENGINE_FLAGS.DISABLED,
}),
withSiloedBorrowing: await booleanSelect({
withSiloedBorrowing: await boolPrompt({
message: 'siloed borrowing',
disableKeepCurrent,
required,
defaultValue: ENGINE_FLAGS.DISABLED,
}),
reserveFactor: await percentInput({
message: 'reserve factor',
disableKeepCurrent,
disableKeepCurrent: required,
}),
};
}
Expand Down Expand Up @@ -69,11 +70,11 @@ export const borrowsUpdates: FeatureModule<BorrowUpdates> = {
.map(
(cfg, ix) => `borrowUpdates[${ix}] = IAaveV3ConfigEngine.BorrowUpdate({
asset: ${translateAssetToAssetLibUnderlying(cfg.asset, pool)},
enabledToBorrow: ${cfg.enabledToBorrow},
flashloanable: ${cfg.flashloanable},
stableRateModeEnabled: ${cfg.stableRateModeEnabled},
borrowableInIsolation: ${cfg.borrowableInIsolation},
withSiloedBorrowing: ${cfg.withSiloedBorrowing},
enabledToBorrow: ${translateJsBoolToSol(cfg.enabledToBorrow)},
flashloanable: ${translateJsBoolToSol(cfg.flashloanable)},
stableRateModeEnabled: ${translateJsBoolToSol(cfg.stableRateModeEnabled)},
borrowableInIsolation: ${translateJsBoolToSol(cfg.borrowableInIsolation)},
withSiloedBorrowing: ${translateJsBoolToSol(cfg.withSiloedBorrowing)},
reserveFactor: ${cfg.reserveFactor}
});`
)
Expand Down
10 changes: 5 additions & 5 deletions generator/features/mocks/configs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ export const assetListingConfig: Listing[] = [
liqBonus: '5_00',
debtCeiling: '100_000',
liqProtocolFee: '20_00',
enabledToBorrow: 'EngineFlags.ENABLED',
flashloanable: 'EngineFlags.ENABLED',
stableRateModeEnabled: 'EngineFlags.DISABLED',
borrowableInIsolation: 'EngineFlags.DISABLED',
withSiloedBorrowing: 'EngineFlags.DISABLED',
enabledToBorrow: 'ENABLED',
flashloanable: 'ENABLED',
stableRateModeEnabled: 'DISABLED',
borrowableInIsolation: 'DISABLED',
withSiloedBorrowing: 'DISABLED',
reserveFactor: '20_00',
supplyCap: '10_000',
borrowCap: '5_000',
Expand Down
45 changes: 3 additions & 42 deletions generator/prompts.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {checkbox, input, select} from '@inquirer/prompts';
import {checkbox, select} from '@inquirer/prompts';
import {ENGINE_FLAGS, PoolIdentifier} from './types';
import {getAssets, getEModes} from './common';
import {getEModes} from './common';
import {advancedInput} from './prompts/advancedInput';

// VALIDATION
Expand Down Expand Up @@ -51,19 +51,6 @@ export function translateJsNumberToSol(value: string) {
return String(value).replace(/\B(?=(\d{3})+(?!\d))/g, '_');
}

function translateJsBoolToSol(value: string) {
switch (value) {
case ENGINE_FLAGS.ENABLED:
return `EngineFlags.ENABLED`;
case ENGINE_FLAGS.DISABLED:
return `EngineFlags.DISABLED`;
case ENGINE_FLAGS.KEEP_CURRENT:
return `EngineFlags.KEEP_CURRENT`;
default:
return value;
}
}

function translateEModeToEModeLib(value: string, pool: PoolIdentifier) {
if (value === ENGINE_FLAGS.KEEP_CURRENT) return `EngineFlags.KEEP_CURRENT`;
return `${pool}EModes.${value}`;
Expand All @@ -77,33 +64,6 @@ interface GenericPrompt<T extends boolean = boolean> {
defaultValue?: string;
}

export type BooleanSelectValues =
| typeof ENGINE_FLAGS.KEEP_CURRENT
| typeof ENGINE_FLAGS.ENABLED
| typeof ENGINE_FLAGS.DISABLED;

export async function booleanSelect<T extends boolean>({
message,
disableKeepCurrent,
defaultValue,
}: GenericPrompt<T>): Promise<
T extends true ? Exclude<BooleanSelectValues, 'KEEP_CURRENT'> : BooleanSelectValues
> {
const choices = [
...(disableKeepCurrent ? [] : [{value: ENGINE_FLAGS.KEEP_CURRENT}]),
{value: ENGINE_FLAGS.ENABLED},
{value: ENGINE_FLAGS.DISABLED},
];
const value = await select({
message,
choices: choices,
default: defaultValue,
});
return translateJsBoolToSol(value) as T extends true
? Exclude<BooleanSelectValues, 'KEEP_CURRENT'>
: BooleanSelectValues;
}

interface PercentInputPrompt<T extends boolean> extends GenericPrompt<T> {
toRay?: boolean;
}
Expand Down Expand Up @@ -180,6 +140,7 @@ export async function eModesSelect<T extends boolean>({message, pool}: EModeSele
.filter((e) => e != 'NONE')
.map((eMode) => ({value: eMode})),
],
required: true,
});
return values.map((mode) => translateEModeToEModeLib(mode, pool));
} else {
Expand Down
44 changes: 44 additions & 0 deletions generator/prompts/boolPrompt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import {select} from '@inquirer/prompts';
import {ENGINE_FLAGS} from '../types';
import {GenericPrompt} from './types';

export type BooleanSelectValues =
| typeof ENGINE_FLAGS.KEEP_CURRENT
| typeof ENGINE_FLAGS.ENABLED
| typeof ENGINE_FLAGS.DISABLED;

export async function boolPrompt<T extends boolean>({
message,
required,
defaultValue,
}: GenericPrompt<T> & {
defaultValue?: T extends true
? Exclude<BooleanSelectValues, 'KEEP_CURRENT'>
: BooleanSelectValues;
}): Promise<T extends true ? Exclude<BooleanSelectValues, 'KEEP_CURRENT'> : BooleanSelectValues> {
const choices = [
...(required ? [] : [{value: ENGINE_FLAGS.KEEP_CURRENT}]),
{value: ENGINE_FLAGS.ENABLED},
{value: ENGINE_FLAGS.DISABLED},
];
return select<
T extends true ? Exclude<BooleanSelectValues, 'KEEP_CURRENT'> : BooleanSelectValues
>({
message,
choices: choices as any,
default: defaultValue,
});
}

export function translateJsBoolToSol(value: string) {
switch (value) {
case ENGINE_FLAGS.ENABLED:
return `EngineFlags.ENABLED`;
case ENGINE_FLAGS.DISABLED:
return `EngineFlags.DISABLED`;
case ENGINE_FLAGS.KEEP_CURRENT:
return `EngineFlags.KEEP_CURRENT`;
default:
throw new Error('unknown boolean select value');
}
}
8 changes: 4 additions & 4 deletions generator/templates/aip.template.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {generateContractName, generateFolderName} from '../common';
import {Options, PoolConfigs} from '../types';
import {Options, PoolConfigs, PoolIdentifier} from '../types';

export function generateAIP(options: Options, configs: PoolConfigs) {
return `---
Expand All @@ -16,9 +16,9 @@ discussions: ${`"${options.discussion}"` || 'TODO'}

${Object.keys(configs)
.map((pool) => {
return configs[pool].artifacts
.filter((artifact) => artifact.aip)
.map((artifact) => artifact.aip);
return configs[pool as keyof typeof configs]!.artifacts.filter(
(artifact) => artifact.aip?.specification
).map((artifact) => artifact.aip?.specification);
})
.filter((a) => a)
.join('\n\n')}
Expand Down