Omniscia Tesseract Audit

TesseractVaultDeployer Manual Review Findings

TesseractVaultDeployer Manual Review Findings

TVD-01M: Inexistent Control Variable of Fees

Description:

The deployment of a vault via the TesseractVaultDeployer may involve performance and management fees to be imposed on it. These fees are configured by the owner of the TesseractVaultDeployer, meaning that they may change between a vault deployment transaction's submission to the network and its execution.

Impact:

A user may deploy a vault with a significant initialDeposit believing the management / performance fee to be low only for it to be changed before their transaction's execution and increased unfairly.

Example:

contracts/TesseractVaultDeployer.sol
237function _deployVault(uint256 initialDeposit)
238 internal
239 returns (FusionFactoryLogicLib.FusionInstance memory fusionInstance)
240{
241 if (initialDeposit < minInitialDeposit) revert InsufficientInitialDeposit();
242
243 // Step 1: Clone vault with deployer as temporary owner
244 fusionInstance = FUSION_FACTORY.clone(
245 assetName,
246 assetSymbol,
247 UNDERLYING_TOKEN,
248 REDEMPTION_DELAY_IN_SECONDS,
249 address(this),
250 daoFeePackageIndex
251 );
252
253 IporFusionAccessManager accessManager = IporFusionAccessManager(fusionInstance.accessManager);
254
255 // Step 2: Grant OWNER-managed roles
256 accessManager.grantRole(Roles.GUARDIAN_ROLE, guardian, 0);
257
258 // Step 3: Grant temporary ATOMIST_ROLE to deployer
259 accessManager.grantRole(Roles.ATOMIST_ROLE, address(this), 0);
260
261 // Step 4: Grant ATOMIST-managed roles
262 accessManager.grantRole(Roles.ALPHA_ROLE, alpha, 0);
263 accessManager.grantRole(Roles.WHITELIST_ROLE, msg.sender, 0);
264 accessManager.grantRole(Roles.WHITELIST_ROLE, address(this), 0);
265 accessManager.grantRole(Roles.FUSE_MANAGER_ROLE, atomist, 0);
266 accessManager.grantRole(Roles.FUSE_MANAGER_ROLE, fuseManager, 0);
267 accessManager.grantRole(Roles.CONFIG_INSTANT_WITHDRAWAL_FUSES_ROLE, alpha, 0);
268 accessManager.grantRole(Roles.CLAIM_REWARDS_ROLE, tesseractRewardsManager, 0);
269 accessManager.grantRole(Roles.TRANSFER_REWARDS_ROLE, tesseractRewardsManager, 0);
270 accessManager.grantRole(Roles.UPDATE_REWARDS_BALANCE_ROLE, tesseractRewardsManager, 0);
271
272 // Step 5: Grant real ATOMIST_ROLE
273 accessManager.grantRole(Roles.ATOMIST_ROLE, atomist, 0);
274
275 // Step 6: Configure fees (skip if both are 0)
276 uint256 perfFee = performanceFee;
277 uint256 mgmtFee = managementFee;
278 if (perfFee > 0 || mgmtFee > 0) {

Recommendation:

We advise control variables to be introduced for vault deployers, permitting them to specify the maximum management / performance fee they are willing to accept for the initialDeposit they have configured, akin to how slippage functions in AMM trades.

Alleviation (fdf0694b5c38834fa5a20cb2765766924d34f5d4):

Proper control variables called maxManagementFee and maxPerformanceFee have been introduced to the TesseractVaultDeployer::_deployVault function and its parent calls that are checked against the current managementFee and performanceFee respectively, alleviating this exhibit in full.