Using delegatecall to call arbitrary contracts is highly dangerous as it can be used to steal assets. An attacker could sneak in a contract that steals all the assets owned by the LlamaAccount contract.
Proof of Concept
Below is a diff to the existing codebase that shows how a super simple contract could be used to steal all the ether from the account. An attacker could even craft a very complex payload that looks benign to call another smart contract that then calls some malicious code under the hood.
The PoC below uses selfdestruct to send all ether in the account to the mock extension contract. It doesn't show ERC20 token theft, but that could also be achieved through a delegate call.
Allowing delegatecall to arbitrary contracts should not be allowed if possible. The same goes for delegatecalls through LlamaExecutor to scripts.
If using delegatecall is a necessity then the contracts that can be delegate called should be audited and locked down to a whitelist. Uniswap V4 has a new hook mechanism that could be an interesting way of achieving this, but there is a lot of speculation about its security long term.
Lines of code
https://github.com/code-423n4/2023-06-llama/blob/main/src/accounts/LlamaAccount.sol#L297
Vulnerability details
Impact
Using
delegatecall
to call arbitrary contracts is highly dangerous as it can be used to steal assets. An attacker could sneak in a contract that steals all the assets owned by theLlamaAccount
contract.Proof of Concept
Below is a diff to the existing codebase that shows how a super simple contract could be used to steal all the ether from the account. An attacker could even craft a very complex payload that looks benign to call another smart contract that then calls some malicious code under the hood.
The PoC below uses selfdestruct to send all ether in the account to the mock extension contract. It doesn't show ERC20 token theft, but that could also be achieved through a delegate call.
Tools Used
Manual review
Recommended Mitigation Steps
Allowing
delegatecall
to arbitrary contracts should not be allowed if possible. The same goes fordelegatecalls
throughLlamaExecutor
to scripts.If using
delegatecall
is a necessity then the contracts that can be delegate called should be audited and locked down to a whitelist. Uniswap V4 has a new hook mechanism that could be an interesting way of achieving this, but there is a lot of speculation about its security long term.Assessed type
call/delegatecall