---
# System prepended metadata

title: Wallet Protocol

---

# Wallet Protocol

## Nested delegatecall can trigger SELFDESTRUCT leading to system freeze

**Severity**: High

**Context**: [`Implementation.sol#L17`](https://github.com/spearbit-audits/writing-exercise/blob/develop/contracts/Implementation.sol#L17)


- Proxy delegates call to trusted implementation but the implementation contract can further delegate the call to any contract and execute that logic.

- If that third-party logic on an arbitrary contract contains `SELFDESTRUCT` opcode, the implementation contract will execute it in the context of proxy and hence wiping out storage trie and code of proxy.

**POC**

```solidity
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;

contract Malicious {
    function kill() external {
        selfdestruct(payable(address(0)));
    }
}
```

- Calling proxy with calldata as `delegatecallContract(malicious,bytes4(keccack256("kill()")))` will delegatecall to implementation which further delegate calls to malicious contract which executes `SELFDESTRUCT` and returns true and then implementation also returns true to the proxy.

- After the end of the transaction, code of the proxy will be `0x` and the `owner` storage variable will be wiped

**Recommendations**

- Do not allow delegatecall to any arbitrary address from `Implementation`, instead maintain a mapping of trusted addresses to which call can be delegated from `Implementation`

- checking `address(this).code.length > 0` will not work since state is not yet commited