Skip to content
Open
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
838 changes: 838 additions & 0 deletions .openzeppelin/mainnet.json

Large diffs are not rendered by default.

13 changes: 12 additions & 1 deletion config/constants/addresses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type AxelarTokenAddresses = {
executables?: Partial<Record<PaymentTokenName, string>>;
};

type TokenFeedAddresses = {
export type TokenFeedAddresses = {
customFeed?: string;
customFeedGrowth?: string;

Expand All @@ -43,10 +43,14 @@ type TokenFeedAddresses = {
dataFeedRv?: string;
};

export type AddressProfileTokenAddresses = TokenFeedAddresses &
Partial<Record<DepositVaultType | RedemptionVaultType, string>>;

export type TokenAddresses = TokenFeedAddresses & {
token?: string;
layerZero?: LayerZeroTokenAddresses;
axelar?: AxelarTokenAddresses;
addressProfiles?: Partial<Record<string, AddressProfileTokenAddresses>>;
} & Partial<Record<DepositVaultType | RedemptionVaultType, string>>;

export type VaultType = RedemptionVaultType | DepositVaultType;
Expand Down Expand Up @@ -295,6 +299,13 @@ export const midasAddressesPerNetwork: ConfigPerNetwork<
dataFeed: '0xCF4e49f5e750Af8F2f9Aa1642B68E5839D9c1C00',
depositVault: '0x41438435c20B1C2f1fcA702d387889F346A0C3DE',
redemptionVaultSwapper: '0x44b0440e35c596e858cEA433D0d82F5a985fD19C',
addressProfiles: {
mFONEUnloop: {
customFeed: '0x6dfD4f744273142AcdAaFd96E3A194D604a14Db3',
dataFeed: '0x24dF63499E8116724E8189aFa7e9a1F812e62Cca',
redemptionVaultSwapper: '0x375ea756418fe30Eea21E1189104974c185aBB48',
},
},
},
mHYPER: {
token: '0x9b5528528656DBC094765E2abB79F293c21191B9',
Expand Down
12 changes: 10 additions & 2 deletions scripts/deploy/common/common-vault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
ManageableVault,
RedemptionVaultWithAave,
} from '../../../typechain-types';
import { getDeploymentTokenAddresses } from '../configs/deployment-profiles';

export type AddPaymentTokensConfig = {
vaults: {
Expand Down Expand Up @@ -266,8 +267,15 @@ const getVaultContract = async (
vaultType: VaultType,
) => {
const addresses = getCurrentAddresses(hre);

const vaultAddress = addresses?.[mToken]?.[vaultType];
const tokenAddresses = addresses?.[mToken]
? getDeploymentTokenAddresses(
addresses[mToken]!,
mToken,
hre.deploymentConfig,
)
: undefined;

const vaultAddress = tokenAddresses?.[vaultType];

if (!vaultAddress) {
throw new Error('Vault address is not found');
Expand Down
18 changes: 16 additions & 2 deletions scripts/deploy/common/data-feed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
CustomAggregatorV3CompatibleFeed,
CustomAggregatorV3CompatibleFeedGrowth,
} from '../../../typechain-types';
import { getDeploymentTokenAddresses } from '../configs/deployment-profiles';
import { paymentTokenDeploymentConfigs } from '../configs/payment-tokens';

export type DeployDataFeedConfigCommon = {
Expand Down Expand Up @@ -159,7 +160,13 @@ export const setRoundDataMToken = async (
}

const addresses = getCurrentAddresses(hre);
const tokenAddresses = addresses?.[token];
const tokenAddresses = addresses?.[token]
? getDeploymentTokenAddresses(
addresses[token]!,
token,
hre.deploymentConfig,
)
: undefined;
const customFeed =
tokenAddresses?.customFeedGrowth ?? tokenAddresses?.customFeed;

Expand Down Expand Up @@ -224,6 +231,7 @@ const setRoundData = async (
const txRes = await sendAndWaitForCustomTxSign(hre, tx, {
action: isMToken ? 'update-feed-mtoken' : 'update-feed-ptoken',
comment: log,
...(isMToken ? { mToken: token as MTokenName } : {}),
});

console.log(log, txRes);
Expand Down Expand Up @@ -393,7 +401,13 @@ export const deployMTokenDataFeed = async (
token: MTokenName,
) => {
const addresses = getCurrentAddresses(hre);
const tokenAddresses = addresses?.[token];
const tokenAddresses = addresses?.[token]
? getDeploymentTokenAddresses(
addresses[token]!,
token,
hre.deploymentConfig,
)
: undefined;

const aggregator =
tokenAddresses?.customFeedAdjusted ??
Expand Down
88 changes: 45 additions & 43 deletions scripts/deploy/common/roles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@ import { Provider } from '@ethersproject/providers';
import { Signer } from 'ethers';
import { HardhatRuntimeEnvironment } from 'hardhat/types';

import {
getDeployer,
getNetworkConfig,
sendAndWaitForCustomTxSign,
} from './utils';
import { getDeployer, sendAndWaitForCustomTxSign } from './utils';
import {
defaultDepositVaultPriority,
resolveAllVaultAddresses,
Expand All @@ -16,8 +12,10 @@ import {
import { MTokenName } from '../../../config';
import { getCurrentAddresses } from '../../../config/constants/addresses';
import { getCommonContractNames } from '../../../helpers/contracts';
import { getAllRoles } from '../../../helpers/roles';
import { getAllRoles, getRolesForToken } from '../../../helpers/roles';
import { MidasAccessControl } from '../../../typechain-types';
import { getDeploymentTokenAddresses } from '../configs/deployment-profiles';
import { getDeploymentConfigForToken } from '../configs/index';
import { networkDeploymentConfigs } from '../configs/network-configs';

type Address = `0x${string}`;
Expand All @@ -34,25 +32,27 @@ export const grantAllProductRoles = async (
hre: HardhatRuntimeEnvironment,
token: MTokenName,
) => {
const { grantRoles: networkConfig } = getNetworkConfig(
hre,
const chainId = hre.network.config.chainId!;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using the non-null assertion operator (!) on chainId can lead to a runtime crash if the network configuration is incomplete. It is safer to handle the case where chainId might be undefined or retrieve it directly from the provider.

Suggested change
const chainId = hre.network.config.chainId!;
const chainId = hre.network.config.chainId ?? (await hre.ethers.provider.getNetwork()).chainId;

const managerGrantConfig = getDeploymentConfigForToken(
token,
'postDeploy',
);

if (!networkConfig) {
throw new Error('Network config is not found');
}
hre.deploymentConfig,
)?.networkConfigs?.[chainId]?.postDeploy?.grantRoles;

const addresses = getCurrentAddresses(hre);
const tokenAddresses = addresses?.[token];
const tokenAddresses = addresses?.[token]
? getDeploymentTokenAddresses(
addresses[token]!,
token,
hre.deploymentConfig,
)
: undefined;

if (!tokenAddresses) {
throw new Error(`Token addresses are not found for ${token}`);
}

const allRoles = getAllRoles();
const tokenRoles = allRoles.tokenRoles[token];
const tokenRoles = getRolesForToken(token);

const provider = await getDeployer(hre);

Expand All @@ -75,9 +75,6 @@ export const grantAllProductRoles = async (

const defaultManager = provider.address;

const contractsRoles: string[] = [];
const contractsAddresses: string[] = [];

const depositVaults = resolveAllVaultAddresses(
tokenAddresses,
defaultDepositVaultPriority,
Expand All @@ -87,45 +84,50 @@ export const grantAllProductRoles = async (
roleGrantRedemptionVaultPriority,
);

const roleBatch: string[] = [];
const addressBatch: string[] = [];

// Token / vault / oracle managers
if (managerGrantConfig) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The logic for granting manager roles has changed from being mandatory (throwing an error if missing) to being optional (silently skipping if managerGrantConfig is undefined). If this change in behavior is unintended, it could lead to incomplete deployments where critical roles are not assigned to the expected manager addresses.

roleBatch.push(
...tokenManagerRoles,
...vaultManagerRoles,
...oracleManagerRoles,
);
addressBatch.push(
...tokenManagerRoles.map(() => managerGrantConfig.tokenManagerAddress),
...vaultManagerRoles.map(
() => managerGrantConfig.vaultsManagerAddress ?? defaultManager,
),
...oracleManagerRoles.map(() => managerGrantConfig.oracleManagerAddress),
);
}

for (const dv of depositVaults) {
contractsRoles.push(tokenRoles.minter);
contractsAddresses.push(dv);
roleBatch.push(tokenRoles.minter);
addressBatch.push(dv);
}

for (const rv of redemptionVaults) {
contractsRoles.push(tokenRoles.burner);
contractsAddresses.push(rv);
roleBatch.push(tokenRoles.burner);
addressBatch.push(rv);
}

const grantRoles = [
...tokenManagerRoles,
...vaultManagerRoles,
...oracleManagerRoles,
...contractsRoles,
];
const grantAddresses = [
...tokenManagerRoles.map(() => networkConfig.tokenManagerAddress),
...vaultManagerRoles.map(
() => networkConfig.vaultsManagerAddress ?? defaultManager,
),
...oracleManagerRoles.map(() => networkConfig.oracleManagerAddress),
...contractsAddresses,
];

const present = await Promise.all(
grantRoles.map((role, i) => accessControl.hasRole(role, grantAddresses[i])),
roleBatch.map((role, i) => accessControl.hasRole(role, addressBatch[i])),
);
const rolesToGrant = grantRoles.filter((_, i) => !present[i]);
const addressesToGrant = grantAddresses.filter((_, i) => !present[i]);
const rolesToGrant = roleBatch.filter((_, i) => !present[i]);
const addressesToGrant = addressBatch.filter((_, i) => !present[i]);

if (rolesToGrant.length === 0) {
console.log(`${token}: all product roles already granted — skip`);
return;
}

const alreadyHeld = grantRoles.length - rolesToGrant.length;
const alreadyHeld = roleBatch.length - rolesToGrant.length;
console.log(
alreadyHeld > 0
? `${token}: grant ${rolesToGrant.length} missing (${alreadyHeld}/${grantRoles.length} already held)`
? `${token}: grant ${rolesToGrant.length} missing (${alreadyHeld}/${roleBatch.length} already held)`
: `${token}: grant ${rolesToGrant.length} missing`,
);

Expand Down
11 changes: 9 additions & 2 deletions scripts/deploy/common/rv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
RedemptionVaultWithMToken,
RedemptionVaultWIthBUIDL,
} from '../../../typechain-types';
import { getDeploymentTokenAddresses } from '../configs/deployment-profiles';

export type DeployRvConfigCommon = {
feeReceiver?: string;
Expand Down Expand Up @@ -98,7 +99,13 @@ export const deployRedemptionVault = async (
) => {
const addresses = getCurrentAddresses(hre);
const deployer = await getDeployer(hre);
const tokenAddresses = addresses?.[token];
const tokenAddresses = addresses?.[token]
? getDeploymentTokenAddresses(
addresses[token]!,
token,
hre.deploymentConfig,
)
: undefined;

const networkConfig = getNetworkConfig(hre, token, type);

Expand Down Expand Up @@ -129,7 +136,7 @@ export const deployRedemptionVault = async (
swapperVaultAddress = DUMMY_ADDRESS;
} else {
swapperVaultAddress =
addresses[swapperVault.mToken]?.[swapperVault.redemptionVaultType];
addresses?.[swapperVault.mToken]?.[swapperVault.redemptionVaultType];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

While this change correctly adds optional chaining to prevent a crash, it does not account for the new 'address profiles' feature. If the swapperVault was deployed under a specific profile, its address should be retrieved using getDeploymentTokenAddresses rather than directly from the base addresses object. This ensures consistency when multiple deployment profiles are used for different tokens.

}

if (!swapperVaultAddress) {
Expand Down
10 changes: 5 additions & 5 deletions scripts/deploy/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
logDeployProxy,
tryEtherscanVerifyImplementation,
} from '../../../helpers/utils';
import { configsPerToken } from '../configs';
import { getDeploymentConfigForToken } from '../configs';

const safeAbi = [
{
Expand Down Expand Up @@ -211,7 +211,8 @@ export const getDeploymentGenericConfig = <
token: MTokenName,
configKey: TConfigKey,
) => {
const config = configsPerToken[token]?.genericConfigs?.[configKey] as TConfig;
const config = getDeploymentConfigForToken(token, hre.deploymentConfig)
?.genericConfigs?.[configKey] as TConfig;

if (!config) {
throw new Error('Deployment config is not found');
Expand All @@ -228,9 +229,8 @@ export const getNetworkConfig = <
token: MTokenName,
configKey: TConfigKey,
) => {
const config = configsPerToken[token]?.networkConfigs?.[
hre.network.config.chainId!
]?.[configKey] as TConfig;
const config = getDeploymentConfigForToken(token, hre.deploymentConfig)
?.networkConfigs?.[hre.network.config.chainId!]?.[configKey] as TConfig;

if (!config) {
throw new Error('Deployment config is not found');
Expand Down
Loading
Loading