https://github.com/shabarkin/writing-exercise
Spearbook: Audit Process - HackMD
https://docs.spearbit.com/how-spearbit-works/security-researchers-and-apprentices
You are given an implementation for a smart contract wallet. There are two contracts
Implementation.sol
: Deployed once and used as implementation contract in Proxy.sol
.Proxy.sol
: Each user has a unique Proxy
deployment with the above implementation. This is a simply proxy contract which delegatecalls the implementation contract. It has an access control check that allows only the owner to use the fallback function.The idea is that users can keep their funds, for example, ETH or ERC20 tokens in the Proxy. To use these funds, users can execute arbitrary calls and arbitrary delegatecalls by using the implementation contract (it has callContract
and delegatecallContract
). The implementation contract is deployed only once and reused to save gas.
Severity: Critical
Impact: An attacker could delete the Implementation
contract deployed for user proxy contracts. All users funds deposited to their Proxy
contracts could be stuck forever without any option to withdraw.
Context: Implementation.sol#L9-L22
While reviewing the Proxy
and Implementation
smart contracts I have observed that Implementation
contract is defined as a normal deployable smart contract, this allows an attacker to cause the denial of service (DoS) attack for all users of Proxy
contract. By application business requirment users should have ability to execute arbitrary call
and arbitrary delegatecall
functions by using their Implementation
contract, however the current architecture implementation has a side affect.
The delegatecall
function preserves the state of the calling smart contract, but executes logic of the called smart contract/library. In this architecture the Implementation
smart contract is deployed as independent smart contract, what means that anyone within the Ethereum network could invoke their functions.
By deploying the malicious smart contract with a function, which defines selfdestruct
operation, allows an attacker to "selfdelete" the Implementation
contract. This may happen, because Implementation.delegatecallContract
function uses delegatecall
operation on the arbitrary address and arbitrary calldata. It will execute the logic of malicious function within the state of the Implementation
contract, what means that the selfdectruct
operation will be executed within the state of Implementation
contract.
The DoS attack is achieved, because there will be no way to update the address of Implementation
of Proxy
contract or to withdraw user funds. Upon deletion of Implementation
contract, all users funds holded within Proxy contracts will be stuck there forever.
The development and test running were completed with Foundry framework.