[SCH] Call Attacks

frenchkebab·2023년 5월 21일
0

Web3

목록 보기
8/8

사실 Call Attack이라는 이름은 그냥 붙인 것 같고,
전반적으로 발생할 수 있는 실수들에 대해 몇 가지 소개가 되어 있다.

1. Delegate Call - Storage Collision

delegate call을 할 때 호출할 contract의 storage layout에 대해 신경쓰지 않으면 변수가 덮어써질 위험이 있다.

더욱이, 임의의 유저에게 delegate call의 target과 calldata 모두 마음대로 할 수 있는 권한을 준다면 그냥 그 contract는 이미 박살난 것이나 상관이 없다.

2. initialize check

Proxy Pattern을 사용할 때에는 반드시 initialize에 대해 신경써야 한다.

    function initialize(address[] calldata _operators) external {
        
        initialized = true;

        require(
            _operators.length <= 10,
            "Can't set more than 10 operators at once"
        );

        for (uint8 i = 0; i < _operators.length; i++) {
            operators[_operators[i]] = true;
            emit NewOperator(_operators[i]);
        }
    }

이 예시를 보면, initialized가 false인지에 대해 체크를 하지 않고 있다.

require(!initialized);

이렇게 반드시 체크를 해주어야 한다.

3. Proxy implementation contract

Proxy가 아닌 그 implementation 원본 contract에 대해서도 취약점이 발생할 수 있다.

    function initialize(address[] calldata _operators) external {

        require(!initialized, "Can not be initialized twice");
        
        initialized = true;

        require(
            _operators.length <= 10,
            "Can't set more than 10 operators at once"
        );

        for (uint8 i = 0; i < _operators.length; i++) {
            operators[_operators[i]] = true;
            emit NewOperator(_operators[i]);
        }
    }

이렇게 최초에 배포되는 contract의 경우에, Access Control이 되어 있지 않다면,
배포 후 deployer가 initialize를 호출하는 과정에서 transaction이 frontrun될 가능성이 있으므로 주의하여야 한다.

profile
Blockchain Dev Journey

0개의 댓글