ERC20 스마트 계약의 approve는 절대 이렇게 쓰지 마세요.

4601 단어 안전 기술
저자: SECBIT 랩
최근 스마트 계약 보안 사건이 빈번하게 발생하고 있다. BEC부터 SMT, HXG부터 FXE까지 최근 이 몇 개의 스마트 계약에 문제가 발생한 것은 대부분 정수가 빈틈이 넘쳐서 발생한 것이다.모두들 정수가 넘쳐흐르는 것에 대해 잔뜩 틀어박혀 있지 않습니까?우리는 반드시 모든 곳에 안전 검사를 해서 우리의 코드에 문제가 없도록 확보해야 합니까?그런데 이게 정말 좋아요?
먼저 이 코드를 살펴보겠습니다.
 function approve(address _spender, uint _amount) returns (bool success) {
    // approval amount cannot exceed the balance
    require ( balances[msg.sender] >= _amount );
    // update allowed amount
    allowed[msg.sender][_spender] = _amount;
    // log event
    Approval(msg.sender, _spender, _amount);
    return true;
  }

이것은 ERC20 인터페이스의 approve 함수 중 하나입니다.어떻게 보면 이 코드가 완벽하지 않아요?자세히 보면, 우리는 함수가 가장 시작하는 곳에 이런 줄이 있다는 것을 알아차렸다.
require ( balances[msg.sender] >= _amount );

approve 시 현재 잔액을 검측하여 권한을 부여하는amount는 현재 잔액보다 작거나 같습니다.이렇게 쓰는 것은 그런대로 일리가 있는 것 같지만, 정말 그런가?approve 시 현재 잔액을 검측하여 권한을 부여하는amount는 현재 잔액보다 작거나 같습니다.이렇게 쓰는 것은 그런대로 일리가 있는 것 같지만, 정말 그런가?
우선 이렇게 쓸 필요가 있는지 없는지를 봅시다.
approve 함수를 실행할 때 위의 조건을 충족시킬 수 있다고 가정하십시오.만약 후속 조작에서 정상적인 논리에 따라 이 조건과 어긋나는 상태가 발생할 수 있다면 이런 판단은 아무런 의미가 없다고 볼 수 있다.
실제적으로 다음과 같은 몇 가지 가능성이 존재하기 때문에 approve가 통과한allowance는 사용자가 대응하는 잔액보다 크다.
  • approve 이후 토큰의 소유자는 자신이transfer 함수를 통해 토큰을 돌려 잔액이 allowance보다 적다.
  • approve는 여러 사람에게 주고 그 중 한 사람이transferFrom 조작을 한 후에 잔액이 이전에 다른 사람에게 approve를 준 값보다 작을 수 있다.

  • 후속 작업에서 권한을 부여받은allowance가 잔액보다 크다는 것을 보장할 수 없기 때문에 우리는 approve에 이러한 검증을 추가하는 것은 무의미하다는 결론을 얻을 수 있다.
    누군가는 그것에다가 이것까지 더하면 가스를 좀 더 소모하는 것 외에는 문제없다고 말할 수도 있다.정말 아무 문제 없어요?
    최근에 우리는 탈중심화 거래소 DDEX와 협력하여 이 플랫폼의 ERC20 token의 스마트 계약을 감사했는데 비교적 심각한 문제를 발견했다.현재 탈중심화 거래소에는 ZRX protocol이나 유사한 협의가 많이 사용되고 있다.ZRX의 스마트 계약에서 이체를 진행할 때 Exchange 계약의 fillOrder 함수를 통해 이체를 완성한다.
    여기서 fillOrder 함수는 다음 코드로 이체됩니다.
    require(transferViaTokenTransferProxy(
        order.makerToken,
        order.maker,
        msg.sender,
        filledMakerTokenAmount
    ));
    require(transferViaTokenTransferProxy(
        order.takerToken,
        msg.sender,
        order.maker,
        filledTakerTokenAmount
    ));

    중심화된 거래소에 가려면 중간 계좌를 준비해야 한다. 이 중간 계좌가 발기한 거래, 즉 위 코드의 msg이다.sender.구체적인 이체 과정은 다음과 같다.
  • 주문서를 판매한 Token을 한 거래소의 중간 계좌로 이체
  • 이 중간 계좌에서 매도 계좌로 WETH
  • 로 이체한다
  • 매입 계좌가 중간 계좌로 WETH
  • 로 이체됨
  • 중간 계좌가 매입 계좌로 Token
  • 으로 이체한다.
    이 네 가지 이체는 모두 Token Transfer Proxy 계약을 통해 이루어진다.중간 계정은 이 계약 approve에 충분한allowance를 필요로 합니다.ZRX가 제공한 계약은 approve 과정을 제공하지 않기 때문에 거래소가 제공한 중간 계정이 이 approve 작업을 미리 준비해야 한다.
    그러나 만약에 이 중간 계좌가 거래의token을 미리 보유하지 않았다면, 이 검사 때문에
    require ( balances[msg.sender] >= _amount );

    approve를 앞당겨 완성하지 못하는 문제는 중심화 거래소에 큰 어려움을 가져왔다.
    각종 탈중심화 거래소 중, 심지어 중심화 거래소에서 유사한 경우는 적지 않다.따라서 ERC20 스마트 계약을 쓸 때 이렇게 쓰지 말고 이런 판단을 덧붙이지 말라고 강력히 추천합니다.
    만약 이미 발표된 ERC20 Token 계약서가 이미 이렇게 쓰여 있다면, 우리는 무슨 방법이 있습니까?
    거래소가 이런 상황을 만났을 때 프로젝트 방향 거래소의 중간 계좌에 충분한 토큰을 만들어야만 approve의 성공을 보장할 수 있고 이후에 발생하는 거래액이 이 수량의 제한을 초과할 수 없다.
    우리는 SECBIT의 내부 도구를 사용하여 소스를 제공하는 22681개의 ERC20 Token 스마트 계약을 스캔한 결과 21개의 스마트 계약에 이런 문제가 존재하는데 그 중에서 3개의 계약이 거래량이 비교적 크다는 것을 발견했다.관련된 Token은 다음과 같습니다. IDH
    GZR ADE SAINT BULB ZZZ KTM ETI-P ZORRO01 ZORRO02
    현재 탈중심화거래소가 갈수록 많아질 것이다. 프로젝트 토큰의 미래 거래의 유동성에 영향을 주지 않기 위해 각 토큰은 계약에 이 문제가 존재하는지 꼼꼼히 검사하고 가능하면 가능한 한 빨리 수정할 것을 건의한다.
    위의 데이터는 SECBIT 랩에서 제공합니다.합작 교류 연락 주세요[email protected].
    앰비(SECBIT) 랩 창업자인 궈위(郭宇)는 중국과학기술대학 박사, 예일대 방문학자, 중과대 부교수를 거쳐 유명 핀테크 회사 부회장을 지냈다.형식화 증명과 시스템 소프트웨어 연구 분야에 전념한 지 10여 년이 되었고 풍부한 금융 안전 제품 연구 개발 경험을 가지고 국내에서 비트코인과 블록체인 기술을 초기에 주목하고 연구한 과학 연구자 중 한 명이다.연구 특기: 블록체인 기술, 형식화 검증, 프로그램 언어 이론, 운영 체제 내핵.
    암비(SECBIT) 실험실은 블록체인과 스마트 계약의 안전 문제에 전념하고 스마트 계약의 안전 빈틈을 전방위적으로 감시하고 전문적인 계약 안전 감사 서비스를 제공하며 스마트 계약 안전 기술에 대해 전방위적으로 깊이 있게 연구하여 공통된 인식, 신뢰성, 질서정연한 블록체인 경제체에 참여하도록 한다.

    좋은 웹페이지 즐겨찾기