CreditDelegationBranch::settlevaultsdebt is intended to swap a vault’s own assets for USDC to settle its debt. However, due to an incorrect parameter in the swap call, the function swaps assets from the marketmakingengine (address(this)) instead of the vault’s associated zlpvault contract. This discrepancy prevents the vault’s actual assets from being used in the settlement process, leading to inaccurate debt settlement.
The natspec of CreditDelegationBranch::settlevaultsdebt says the following:
"/// @notice Settles the given vaults' debt or credit by swapping assets to USDC or vice versa.
/// @dev Converts ZLP Vaults unsettled debt to settled debt by:
/// - If in debt, swapping the vault's assets to USDC.
/// - If in credit, swapping the vault's available USDC to its underlying assets.
/// exchange for their assets."
The natspec documentation clearly states that the vault’s assets should be swapped for USDC (if the vault is in debt) or vice versa (if in credit). However, the implementation erroneously uses address(this) when calling the swap function. This implies that the swap operation is performed using tokens from the current contract rather than from the vault’s designated asset account.
This is not intended logic and is further proven by looking at CreditDelegationBranch::convertMarketsCreditDepositsToUsdc. See below:
This function is used to convert market credit which are tokens deposited by the perp engine using CreditDelegationBranch::depositcreditformarket to usdc. As a result, it is evident that CreditDelegationBranch::settlevaultsdebt intended function is to swap assets from the vaults associated zlp vault to usdc. Assets in the zlp vault are deposited via VaultRouterBranch::deposit and the function contains the following lines:
These lines deposit the assets that user has deposited into the zlp vault. As a result, these tokens are no longer in the marketmakingengine contract. They are stored in the zlp vault. As a result, when CreditDelegationBranch::settlevaultsdebt, for it to work as intended, it must swap tokens directly from the associated zlp vault for usdc which currently is not the case.
The call:
mistakenly directs the swap to pull tokens from address(this) (the current contract) instead of from the vault's actual asset holdings.
Because the vault’s assets are not swapped as intended, the resulting USDC is not correctly allocated. This leads to an incorrect update of the vault’s unsettled debt—ultimately causing the debt to remain unaddressed when the settlement function is called.
The vault’s actual assets are not used for the swap, meaning the vault’s debt remains unsettled or is settled using an incorrect source. This discrepancy results in the vault’s debt not being properly reduced. Since the marketmakingengine contract makes the swap, it ends up with less creditdeposits than intended. If using the marketmakingengine's tokens to perform the swap was intended behaviour, then Market::creditdeposits should have been updated to reflect that there are less credit deposits in the contract and more usdc which was done in CreditDelegationBranch::convertMarketsCreditDepositsToUsdc with the following line:
This was not done in CreditDelegationBranch::settlevaultsdebt which further indicates that the marketmakingengine's creditdeposits are not intended to be used in CreditDelegationBranch::settlevaultsdebt.
Manual Review
Correct the Swap Parameter:
Update the swap call in the debt settlement function to ensure that it pulls the vault’s assets from the correct contract. Replace
address(this) with the appropriate vault asset source address so that the swap operation utilizes the vault’s own tokens for settling its debt.
Ensure Proper Asset Approval: Before executing the swap, the ZLP vault must explicitly approve the MarketMakingEngine to spend all its tokens. This approval is critical to guarantee that the MarketMakingEngine can access and swap the vault’s assets as intended.
Review Asset Flow and Design: Verify that the vault’s assets are managed in a separate contract as originally designed, and update the debt settlement logic accordingly. Confirm that the asset flow during swaps matches the specifications outlined in the natSpec documentation.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.