Skip to content

Commit

Permalink
feat: extend listing generator with emission admin
Browse files Browse the repository at this point in the history
  • Loading branch information
Rozengarden committed Oct 3, 2024
1 parent 42b67ff commit e0c3621
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 17 deletions.
11 changes: 11 additions & 0 deletions generator/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import {
scroll,
zkSync,
} from 'viem/chains';
import {Client, Hex, getAddress} from 'viem';
import {CHAIN_ID_CLIENT_MAP} from '@bgd-labs/js-utils';

export const AVAILABLE_CHAINS = [
'Ethereum',
Expand Down Expand Up @@ -54,6 +56,15 @@ export function getPoolChain(pool: PoolIdentifier) {
return chain;
}

export function getExplorerLink(chainId: number, address: Hex) {
const client = CHAIN_ID_CLIENT_MAP[chainId];
let url = client.chain?.blockExplorers?.default.url;
if (url && url.endsWith('/')) {
url = url.slice(0, -1); // sanitize explorer url
}
return `${url}/address/${getAddress(address)}`;
}

export function getDate() {
const date = new Date();
const years = date.getFullYear();
Expand Down
54 changes: 37 additions & 17 deletions generator/features/assetListing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import {fetchRateStrategyParamsV3} from './rateUpdates';
import {fetchCollateralUpdate} from './collateralsUpdates';
import {fetchCapsUpdate} from './capsUpdates';
import {Listing, ListingWithCustomImpl, TokenImplementations} from './types';
import {CHAIN_TO_CHAIN_ID, getPoolChain} from '../common';
import {getContract} from 'viem';
import {CHAIN_TO_CHAIN_ID, getPoolChain, getExplorerLink} from '../common';
import {getContract, isAddress} from 'viem';
import {confirm} from '@inquirer/prompts';
import {TEST_EXECUTE_PROPOSAL} from '../utils/constants';
import {addressPrompt, translateJsAddressToSol} from '../prompts/addressPrompt';
Expand Down Expand Up @@ -79,6 +79,7 @@ async function fetchListing(pool: PoolIdentifier): Promise<Listing> {
pool,
}),
asset,
admin: await addressPrompt({message: 'Emission admin address (optional)', required: false}),
};
}

Expand Down Expand Up @@ -134,17 +135,24 @@ export const assetListing: FeatureModule<Listing[]> = {
build({pool, cfg}) {
const response: CodeArtifact = {
code: {
constants: cfg
.map((cfg) => [
`address public constant ${cfg.assetSymbol} = ${translateJsAddressToSol(cfg.asset)};`,
`uint256 public constant ${cfg.assetSymbol}_SEED_AMOUNT = 1e${cfg.decimals};`,
])
.flat(),
execute: cfg.map(
(cfg) =>
`IERC20(${cfg.assetSymbol}).forceApprove(address(${pool}.POOL), ${cfg.assetSymbol}_SEED_AMOUNT);
${pool}.POOL.supply(${cfg.assetSymbol}, ${cfg.assetSymbol}_SEED_AMOUNT, address(${pool}.COLLECTOR), 0);`,
),
constants: cfg.map((cfg) => {
let listingConstant = `address public constant ${cfg.assetSymbol} = ${translateJsAddressToSol(cfg.asset)};\n`;
listingConstant += `uint256 public constant ${cfg.assetSymbol}_SEED_AMOUNT = 1e${cfg.decimals};\n`;
if (isAddress(cfg.admin)) {
listingConstant += `address public constant ${cfg.assetSymbol}_ADMIN = ${translateJsAddressToSol(cfg.admin)};\n`;
}
return listingConstant;
}),
execute: cfg.map((cfg) => {
let listingExe = `IERC20(${cfg.assetSymbol}).forceApprove(address(${pool}.POOL), ${cfg.assetSymbol}_SEED_AMOUNT);\n`;
listingExe += `${pool}.POOL.supply(${cfg.assetSymbol}, ${cfg.assetSymbol}_SEED_AMOUNT, address(${pool}.COLLECTOR), 0);\n`;
if (isAddress(cfg.admin)) {
listingExe += `\n(address a${cfg.assetSymbol}, , ) = ${pool}.AAVE_PROTOCOL_DATA_PROVIDER.getReserveTokensAddresses(${cfg.assetSymbol});\n`;
listingExe += `IEmissionManager(${pool}.EMISSION_MANAGER).setEmissionAdmin(${cfg.assetSymbol}, ${cfg.assetSymbol}_ADMIN);\n`;
listingExe += `IEmissionManager(${pool}.EMISSION_MANAGER).setEmissionAdmin(a${cfg.assetSymbol}, ${cfg.assetSymbol}_ADMIN);\n`;
}
return listingExe;
}),
fn: [
`function newListings() public pure override returns (IAaveV3ConfigEngine.Listing[] memory) {
IAaveV3ConfigEngine.Listing[] memory listings = new IAaveV3ConfigEngine.Listing[](${
Expand All @@ -164,13 +172,22 @@ export const assetListing: FeatureModule<Listing[]> = {
],
},
test: {
fn: cfg.map(
(cfg) => `function test_collectorHas${cfg.assetSymbol}Funds() public {
fn: cfg.map((cfg) => {
let listingTest = `function test_collectorHas${cfg.assetSymbol}Funds() public {
${TEST_EXECUTE_PROPOSAL}
(address aTokenAddress, , ) = ${pool}.AAVE_PROTOCOL_DATA_PROVIDER.getReserveTokensAddresses(proposal.${cfg.assetSymbol}());
assertGe(IERC20(aTokenAddress).balanceOf(address(${pool}.COLLECTOR)), 10 ** ${cfg.decimals});
}`,
),
}\n`;
if (isAddress(cfg.admin)) {
listingTest += `\nfunction test_${cfg.assetSymbol}Admin() public {
${TEST_EXECUTE_PROPOSAL}
(address a${cfg.assetSymbol}, , ) = ${pool}.AAVE_PROTOCOL_DATA_PROVIDER.getReserveTokensAddresses(proposal.${cfg.assetSymbol}());
assertEq(IEmissionManager(${pool}.EMISSION_MANAGER).getEmissionAdmin(proposal.${cfg.assetSymbol}()), proposal.${cfg.assetSymbol}_ADMIN());
assertEq(IEmissionManager(${pool}.EMISSION_MANAGER).getEmissionAdmin(a${cfg.assetSymbol}), proposal.${cfg.assetSymbol}_ADMIN());
}\n`;
}
return listingTest;
}),
},
aip: {
specification: cfg.map((cfg) => {
Expand Down Expand Up @@ -215,6 +232,9 @@ export const assetListing: FeatureModule<Listing[]> = {
listingTemplate += `| Siloed Borrowing | ${cfg.withSiloedBorrowing} |\n`;
listingTemplate += `| Borrowable in Isolation | ${cfg.borrowableInIsolation} |\n`;
listingTemplate += `| Oracle | ${cfg.priceFeed} |\n`;
if (isAddress(cfg.admin)) {
listingTemplate += `\nAdditionaly [${cfg.admin}](${getExplorerLink(CHAIN_TO_CHAIN_ID[getPoolChain(pool)], cfg.admin)}) has been set as the emission admin for ${cfg.assetSymbol} and the corresponding aToken.\n`;
}
return listingTemplate;
}),
},
Expand Down
1 change: 1 addition & 0 deletions generator/features/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export interface Listing
rateStrategyParams: RateStrategyParams;
eModeCategory: string;
decimals: number;
admin?: Hex | '';
}

export interface ListingWithCustomImpl {
Expand Down
3 changes: 3 additions & 0 deletions generator/utils/importsResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ export function prefixWithImports(code: string) {
if (findMatch(code, 'GovernanceV3Ethereum')) {
imports += `import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol';\n`;
}
if (findMatch(code, 'IEmissionManager')) {
imports += `import {IEmissionManager} from 'aave-v3-periphery/contracts/rewards/interfaces/IEmissionManager.sol';\n`;
}

return imports + code;
}

0 comments on commit e0c3621

Please sign in to comment.