Part 2

Zaros
PerpetualsDEXFoundrySolidity
70,000 USDC
View results
Submission Details
Severity: medium
Invalid

Vault ID collision in `MarketMakingEngineConfigurationBranch.sol#createVault()` allow to to overwrite existing vault configurations

Summary

A critical vulnerability exists in the createVault function due to the lack of uniqueness checks for vaultId. This flaw allows an attacker or an accidental misconfiguration to overwrite existing vault configurations, potentially leading to loss of data, disruption of system operations, and financial loss.

Vulnerability Details

The createVault function does not verify whether the provided vaultId has already been used. This means that if a duplicate vaultId is provided, it will overwrite an existing vault configuration without warning.

function createVault(Vault.CreateParams calldata params) external onlyOwner {
if (params.indexToken == address(0)) {
revert Errors.ZeroInput("indexToken");
}
if (params.depositCap == 0) {
revert Errors.ZeroInput("depositCap");
}
if (params.withdrawalDelay == 0) {
revert Errors.ZeroInput("withdrawDelay");
}
if (params.vaultId == 0) {
revert Errors.ZeroInput("vaultId");
}
if (params.engine == address(0)) {
revert Errors.ZeroInput("engine");
}
Vault.create(params);
emit LogCreateVault(msg.sender, params.vaultId);
}

PoC

A malicious or unintended transaction creates a vault with an existing vaultId, overwriting its configuration.

contract VaultCollisionTest is Test {
VaultContract vaultContract;
address owner = address(0x123);
function setUp() public {
vaultContract = new VaultContract();
vm.startPrank(owner);
}
function test_VaultCollision() public {
Vault.CreateParams memory params1 = Vault.CreateParams({
vaultId: 1,
depositCap: 1000,
withdrawalDelay: 3600,
indexToken: address(0xABC),
collateral: Collateral.Data({ asset: address(0xDEF), priceAdapter: address(0x123), creditRatio: 50, isEnabled: true, decimals: 18 }),
depositFee: 10,
redeemFee: 5,
engine: address(0x456)
});
vaultContract.createVault(params1);
// Attempt to overwrite vaultId 1
Vault.CreateParams memory params2 = params1;
params2.depositCap = 5000; // Changing deposit cap
vaultContract.createVault(params2);
uint256 newDepositCap = vaultContract.getVaultDepositCap(1);
assertEq(newDepositCap, 5000, "Vault ID collision detected: depositCap changed unexpectedly!");
}
}

Output:

[FAIL] test_VaultCollision() : Vault ID collision detected: depositCap changed unexpectedly!

Impact

Vault configurations can be accidentally or maliciously overwritten.

Previously deployed vaults may stop working as expected.

If vault parameters like deposit caps or withdrawal delays are altered, users might lose funds or be unable to access the

Tools Used

Manual review.

Recommendations

Before creating a vault, verify that the ID does not already exist.

Implement a check that prevents overwriting an existing vault.

function createVault(Vault.CreateParams calldata params) external onlyOwner {
require(!vaultExists(params.vaultId), "Vault ID already exists");
Vault.create(params);
emit LogCreateVault(msg.sender, params.vaultId);
}
function vaultExists(uint256 vaultId) internal view returns (bool) {
return vaultsConfig[vaultId].vaultId != 0;
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.