-
Notifications
You must be signed in to change notification settings - Fork 5
feat: enhance deployment configurations with address profiles; mFONE … #213
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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, | ||
|
|
@@ -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}`; | ||
|
|
@@ -34,25 +32,27 @@ export const grantAllProductRoles = async ( | |
| hre: HardhatRuntimeEnvironment, | ||
| token: MTokenName, | ||
| ) => { | ||
| const { grantRoles: networkConfig } = getNetworkConfig( | ||
| hre, | ||
| const chainId = hre.network.config.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); | ||
|
|
||
|
|
@@ -75,9 +75,6 @@ export const grantAllProductRoles = async ( | |
|
|
||
| const defaultManager = provider.address; | ||
|
|
||
| const contractsRoles: string[] = []; | ||
| const contractsAddresses: string[] = []; | ||
|
|
||
| const depositVaults = resolveAllVaultAddresses( | ||
| tokenAddresses, | ||
| defaultDepositVaultPriority, | ||
|
|
@@ -87,45 +84,50 @@ export const grantAllProductRoles = async ( | |
| roleGrantRedemptionVaultPriority, | ||
| ); | ||
|
|
||
| const roleBatch: string[] = []; | ||
| const addressBatch: string[] = []; | ||
|
|
||
| // Token / vault / oracle managers | ||
| if (managerGrantConfig) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The logic for granting manager roles has changed from being mandatory (throwing an error if missing) to being optional (silently skipping if |
||
| 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`, | ||
| ); | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,6 +17,7 @@ import { | |
| RedemptionVaultWithMToken, | ||
| RedemptionVaultWIthBUIDL, | ||
| } from '../../../typechain-types'; | ||
| import { getDeploymentTokenAddresses } from '../configs/deployment-profiles'; | ||
|
|
||
| export type DeployRvConfigCommon = { | ||
| feeReceiver?: string; | ||
|
|
@@ -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); | ||
|
|
||
|
|
@@ -129,7 +136,7 @@ export const deployRedemptionVault = async ( | |
| swapperVaultAddress = DUMMY_ADDRESS; | ||
| } else { | ||
| swapperVaultAddress = | ||
| addresses[swapperVault.mToken]?.[swapperVault.redemptionVaultType]; | ||
| addresses?.[swapperVault.mToken]?.[swapperVault.redemptionVaultType]; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While this change correctly adds optional chaining to prevent a crash, it does not account for the new 'address profiles' feature. If the |
||
| } | ||
|
|
||
| if (!swapperVaultAddress) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using the non-null assertion operator (
!) onchainIdcan lead to a runtime crash if the network configuration is incomplete. It is safer to handle the case wherechainIdmight be undefined or retrieve it directly from the provider.