You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Dec 31, 2023. It is now read-only.
sherlock-admin opened this issue
Jul 1, 2023
· 0 comments
Labels
DuplicateA valid issue that is a duplicate of an issue with `Has Duplicates` labelHighA valid High severity issueRewardA payout will be made for this issue
During liquidation, debt tokens are sent to the vault. The state stored reserve balance is not updated afterwards, leaving a difference between the actual token balance of the vault and the accounted balance of the vault. These unaccounted tokens can be stolen by calling D3VaultFunding.userDeposit for the corresponding token, which then applies the difference between it's last accounted balance and actual balance as a deposit on the users behalf, granting them dTokens which they can later withdraw for the underlying tokens.
Vulnerability Detail
D3VaultFunding.userDeposit checks the actual token balance of the contract and the last accounted balance of the contract, and assumes any increase in tokens was sent by the user, granting the user corresponding dTokens.
Anytime the actual balance of the contract is greater than the last accounted balance, it's possible to call this function and receive dTokens corresponding to the underlying tokens.
Since D3VaultLiquidation.liquidate fails to call for an update to the reserves of the debt token, there is a surplus which can be taken.
We can add the following function to D3VaultLiquidation.t.sol to test an exploit:
We can see from the output that the actual balance is higher than the accounted balance and that an attacker depositing credits them with the corresponding dTokens:
Anytime a liquidation occurs, an attacker can steal the tokens used to repay the debt, thereby preventing debt from actually being paid and leaving the system in a liquidate-able state. This allows for an attacker to liquidate => steal debt => liquidate => steal debt => ... until it is no longer profitable, draining the system of collateral.
Sign up for freeto subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Labels
DuplicateA valid issue that is a duplicate of an issue with `Has Duplicates` labelHighA valid High severity issueRewardA payout will be made for this issue
0xkaden
high
Attacker can steal debt repaid after liquidation
Summary
During liquidation, debt tokens are sent to the vault. The state stored reserve balance is not updated afterwards, leaving a difference between the actual token balance of the vault and the accounted balance of the vault. These unaccounted tokens can be stolen by calling
D3VaultFunding.userDeposit
for the corresponding token, which then applies the difference between it's last accounted balance and actual balance as a deposit on the users behalf, granting them dTokens which they can later withdraw for the underlying tokens.Vulnerability Detail
D3VaultFunding.userDeposit
checks the actual token balance of the contract and the last accounted balance of the contract, and assumes any increase in tokens was sent by the user, granting the user corresponding dTokens.Anytime the actual balance of the contract is greater than the last accounted balance, it's possible to call this function and receive dTokens corresponding to the underlying tokens.
Since
D3VaultLiquidation.liquidate
fails to call for an update to the reserves of the debt token, there is a surplus which can be taken.We can add the following function to
D3VaultLiquidation.t.sol
to test an exploit:We can see from the output that the actual balance is higher than the accounted balance and that an attacker depositing credits them with the corresponding dTokens:
Impact
Anytime a liquidation occurs, an attacker can steal the tokens used to repay the debt, thereby preventing debt from actually being paid and leaving the system in a liquidate-able state. This allows for an attacker to liquidate => steal debt => liquidate => steal debt => ... until it is no longer profitable, draining the system of collateral.
Code Snippet
D3VaultFunding.userDeposit
Tool used
Recommendation
It's recommended that in
D3VaultLiquidation.liquidate
, the debt token reserves of the pool are updated. Additionally, it's recommended that either:safeTransferFrom
instead orD3VaultFunding.userDeposit
is only allowed to be called by a validated proxyDuplicate of #211
The text was updated successfully, but these errors were encountered: