Summary
In the recalculateVaultsCreditCapacity
function, the logic assigns the same weight to all markets using a vault. As a result, the entire creditCapacity
of a vault is allocated to each market instead of being proportionally distributed. This leads to over-allocation, which can cause financial inconsistencies.
Affected Code
function updateVaultAndCreditDelegationWeight(
Data storage self,
uint128[] memory connectedMarketsIdsCache
)
internal
{
uint256 connectedMarketsConfigLength = self.connectedMarkets.length;
EnumerableSet.UintSet storage connectedMarkets = self.connectedMarkets[connectedMarketsConfigLength - 1];
uint128 newWeight = uint128(IERC4626(self.indexToken).totalAssets());
for (uint256 i; i < connectedMarketsIdsCache.length; i++) {
CreditDelegation.Data storage creditDelegation =
CreditDelegation.load(self.id, connectedMarkets.at(i).toUint128());
creditDelegation.weight = newWeight;
}
self.totalCreditDelegationWeight = newWeight;
}
Vulnerability Details
Scenario: Over-Allocation of Credit Capacity
A vault is connected to two markets.
Each market is assigned a weight of 1000, making the total weight also 1000.
If the vault has a creditCapacity
of 100, it should distribute 50 to each market.
However, due to the current logic, each market receives the full 100, leading to over-allocation.
Impact
Markets will incorrectly assume that they have sufficient creditCapacity, when in reality, the total credit has been over-allocated across multiple markets. This can lead to:
Misleading credit availability – Markets may operate under the false assumption that they have enough liquidity.
Tools Used
Manual review
Recommendations
Refactor the logic:
function updateVaultAndCreditDelegationWeight(
Data storage self,
uint128[] memory connectedMarketsIdsCache // Here, passing just the length would be sufficient
)
internal
{
// Cache the length of connected markets
uint256 connectedMarketsConfigLength = self.connectedMarkets.length;
// Load the connected markets storage pointer from the last configured market set
EnumerableSet.UintSet storage connectedMarkets = self.connectedMarkets[connectedMarketsConfigLength - 1];
// Get the total shares
uint128 newWeight = uint128(IERC4626(self.indexToken).totalAssets());
for (uint256 i; i < connectedMarketsIdsCache.length; i++) {
// Load the credit delegation for the given market ID
CreditDelegation.Data storage creditDelegation =
CreditDelegation.load(self.id, connectedMarkets.at(i).toUint128());
// Assign the entire newWeight to each market
creditDelegation.weight = newWeight;
}
// Update the total vault weight
+ self.totalCreditDelegationWeight = newWeight * connectedMarketsIdsCache*length;
- self.totalCreditDelegationWeight = newWeight;
}