---
# System prepended metadata

title: Untitled

---

## Implementation Vulnerable to Selfdestruct

**Severity**: High

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

```    
function delegatecallContract(address a, bytes calldata _calldata) payable external returns (bytes memory) {
    (bool success, bytes memory ret) =  a.delegatecall(_calldata);
    require(success);
    return ret;
}
```

The EVM contains an opcode, ```SELFDESTRUCT```, which deletes the calling contract's code and returns whatever ether it contains to a specified recipient address. When contracts delegatecall, they execute another contract's code in their own context. This essentially means that the calling contract is "borrowing" the target contract's code to execute it. If a contract delegatecalls another contract which can self-destruct, then the calling contract can self-destruct as well, deleting it from the blockchain.

The Implementation contract allows any account to call ```delegateCallContract```, which will delegatecall to whatever address and whatever function the calling account desires. Anyone can thus call ```delegateCallContract```  on a malicious contract and force the Implementation contract to self-destruct. Once the Implementation code is deleted, all Proxy contracts will freeze, since the contract they delegatecall to now has no functions.

**Recommendation**: Libraries cannot be called directly and have no state, so they cannot be self-destructed. I recommend converting the Implementation contract into a library.

```diff
-contract Implementation {
+library Implementation {

-    function callContract(address a, bytes calldata _calldata) payable external returns (bytes memory) {
+    function callContract(address a, bytes calldata _calldata) external returns (bytes memory) {
        (bool success , bytes memory ret) =  a.call{value: msg.value}(_calldata);
        require(success);
        return ret;
     }

-    function delegatecallContract(address a, bytes calldata _calldata) payable external returns (bytes memory) {
+    function delegatecallContract(address a, bytes calldata _calldata) external returns (bytes memory) {
        (bool success, bytes memory ret) =  a.delegatecall(_calldata);
        require(success);
        return ret;
     }
 }
```

