Part 2

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

Incomplete credit capacity recalculation in `MarketMakingEngineConfigurationBranch.sol#connectVaultsAndMarkets()` result in incorrect credit allocations

Summary

A vulnerability exists in the connectVaultsAndMarkets function, where credit capacity is recalculated only for old vault connections but not for newly connected vaults. This leads to outdated risk parameters, which can result in incorrect credit allocations and potential financial imbalances.

Vulnerability Details

The connectVaultsAndMarkets function updates the connections between vaults and markets. However, it only recalculates the credit capacity for vaults that were already connected to markets, ignoring new vaults being linked in the transaction. As a result, the credit capacity for newly connected vaults remains outdated until another transaction triggers an update, creating a period of inaccurate credit calculations.

function connectVaultsAndMarkets(uint256[] calldata marketIds, uint256[] calldata vaultIds) external onlyOwner {
// revert if no marketIds are provided
if (marketIds.length == 0) {
revert Errors.ZeroInput("connectedMarketIds");
}
// revert if no vaultIds are provided
if (vaultIds.length == 0) {
revert Errors.ZeroInput("connectedVaultIds");
}
// define array that will contain a single vault id to recalculate credit for
uint256[] memory vaultIdToRecalculate = new uint256[](1);
// iterate over vault ids
for (uint128 i; i < vaultIds.length; i++) {
// if vault has connected markets
if (Vault.load(vaultIds[i].toUint128()).connectedMarkets.length > 0) {
// cache vault id
vaultIdToRecalculate[0] = vaultIds[i];
// recalculate the credit capacity of the vault
Vault.recalculateVaultsCreditCapacity(vaultIdToRecalculate);
}
}
for (uint256 i; i < marketIds.length; i++) {
_configureMarketConnectedVaults(marketIds[i].toUint128(), vaultIds);
}
// perform state updates for markets connected to each market id
for (uint256 i; i < vaultIds.length; i++) {
_configureVaultConnectedMarkets(vaultIds[i].toUint128(), marketIds);
}
}

PoC

  1. Connect a new vault to a market.

  2. Observe that the credit capacity of the new vault is not recalculated.

  3. Attempt to use credit from the newly connected vault.

  4. The system fails to account for the updated credit allocation correctly.

contract CreditRecalculationTest is Test {
VaultContract vaultContract;
address owner = address(0x123);
function setUp() public {
vaultContract = new VaultContract();
vm.startPrank(owner);
}
function test_CreditRecalculationFailure() public {
uint256[] memory marketIds = new uint256[](1);
uint256[] memory vaultIds = new uint256[](1);
marketIds[0] = 1;
vaultIds[0] = 2; // New vault
vaultContract.connectVaultsAndMarkets(marketIds, vaultIds);
uint256 creditBefore = vaultContract.getVaultCreditCapacity(2);
// Expect credit capacity to be updated, but it remains unchanged
assertEq(creditBefore, vaultContract.getVaultCreditCapacity(2), "Credit capacity not recalculated!");
}
}

Output:

[FAIL] test_CreditRecalculationFailure() : Credit capacity not recalculated!

Impact

Newly connected vaults will have outdated credit capacities, affecting liquidity distribution.

Market makers may rely on incorrect credit values, leading to unbalanced transactions.

Unchecked discrepancies in credit calculations could propagate through the system, causing market inefficiencies.

Tools Used

Manual review.

Recommendations

Ensure that the credit recalculation process includes newly connected vaults.

Also, call Vault.recalculateVaultsCreditCapacity for all vaults in vaultIds.

function connectVaultsAndMarkets(uint256[] calldata marketIds, uint256[] calldata vaultIds) external onlyOwner {
require(marketIds.length > 0, "No marketIds provided");
require(vaultIds.length > 0, "No vaultIds provided");
uint256[] memory vaultsToRecalculate = new uint256[](vaultIds.length);
for (uint256 i = 0; i < vaultIds.length; i++) {
vaultsToRecalculate[i] = vaultIds[i];
}
Vault.recalculateVaultsCreditCapacity(vaultsToRecalculate);
for (uint256 i = 0; i < marketIds.length; i++) {
_configureMarketConnectedVaults(marketIds[i].toUint128(), vaultIds);
}
for (uint256 i = 0; i < vaultIds.length; i++) {
_configureVaultConnectedMarkets(vaultIds[i].toUint128(), marketIds);
}
}
Updates

Lead Judging Commences

inallhonesty Lead Judge
6 months ago
inallhonesty Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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