In the invoke function, there is no validation check to ensure that the vault address passed as an argument is a valid Vault contract. This means that the attacker can drain the vault contract.
Vulnerability Detail
function invoke(Invocation[] calldata invocations) external payable {
for(uint i = 0; i < invocations.length; ++i) {
Invocation memory invocation = invocations[i];
} else if (invocation.action == PerennialAction.UPDATE_VAULT) {
(IVault vault, UFixed6 depositAssets, UFixed6 redeemShares, UFixed6 claimAssets, bool wrap)
= abi.decode(invocation.args, (IVault, UFixed6, UFixed6, UFixed6, bool));
_vaultUpdate(vault, depositAssets, redeemShares, claimAssets, wrap);
// there is no validation about the legitimacy of the Vault contract
next
function _vaultUpdate(
IVault vault,)
...
vault.update(msg.sender, depositAssets, redeemShares, claimAssets);
Since this is a custom Vault contract, the update function will successfully return for any claim amount
Then code continues on to withdraw
...
if (!claimAmount.isZero()) {
_withdraw(msg.sender, claimAmount, wrap);
}
In withdraw, the funds are just pushed to the receiver
tives
high
No validation of the Vault address in invoke
Summary
In the
invoke
function, there is no validation check to ensure that thevault
address passed as an argument is a valid Vault contract. This means that the attacker can drain the vault contract.Vulnerability Detail
next
Since this is a custom Vault contract, the update function will successfully return for any claim amount
Then code continues on to withdraw
In withdraw, the funds are just pushed to the receiver
Impact
Users can drain the DSU from vault
Code Snippet
https://github.com/sherlock-audit/2023-07-perennial/blob/main/perennial-v2/packages/perennial-extensions/contracts/MultiInvoker.sol/#L193
Tool used
Manual Review
Recommendation
Use a Vault whitelist so users cannot use a custom vault.