프로그래밍/트러블슈팅(trouble shooting)

[truffle] Error: VM Exception while processing transaction: revert -- Reason given: Panic: Arithmetic overflow.

싯타마 2023. 3. 15. 14:41

Dapp 개발을 위한 테스트를 하는 도 중 다음과 같은 오류가 발생하였다.

구글링 해보니 산술연산을 한 결괏값이 타입의 허용 범위를 넘어서 overflow 됐다고 알려주는 것 같았다. 

 

Solidity에서 고정 크기 정수에 대한 산술 연산은 연산 결과가 데이터 유형으로 나타낼 수 있는 최댓값 또는 최솟값을 초과할 경우 Overflow 또는 Underflow 오류가 발생할 수 있는데. Overflow는 최댓값을 초과한 경우, Underflow는 최솟값을 초과할 경우 나타난다.

 

그래서 컨트랙트 함수내의 산술연산하는 부분을 살펴보았고 다음과 같이 오입력 된 연산을 발견할 수 있었다.

mapping(address => mapping(address => uint256)) public allowance;

function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
        require(_value <= balanceOf[_from]);
        require(allowance[_from][msg.sender] >= _value);
        // add the balance for transferFrom
        balanceOf[_to] += _value;
        // subtract the balance for transferFrom
        balanceOf[_from] -= _value;
        allowance[msg.sender][_from] -= _value; // 에러를 발생한 이유
        emit Transfer(_from, _to, _value);
        return true;
    }

transferFrom은 허용된 spender의 토큰을 원하는 곳으로 전송할 수 있는 함수이다. 해당 함수 부분 중 allowance[msg.sender][_from] -= _value가 아닌 allowance[_from][msg.sender]가 되어야 토큰을 보내는 주소(from)에서 보내는 토큰의 값만큼 뺄 수가 있다.

 

mapping(address => mapping(address => uint256)) public allowance;

function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
        require(_value <= balanceOf[_from]);
        require(allowance[_from][msg.sender] >= _value);
        // add the balance for transferFrom
        balanceOf[_to] += _value;
        // subtract the balance for transferFrom
        balanceOf[_from] -= _value;
        allowance[_from][msg.sender] -= _value; // 에러를 발생한 이유
        emit Transfer(_from, _to, _value);
        return true;
    }

 

mapping이 헷갈려서 오입력을 한듯하다. 처음에는 uint의 타입 범위설정이 잘못된 줄 알고 uint부분을 보다가 시간을 많이 썻다. overflow, underflow는 자주 발생하는 오류이고 해당 오류가 발생하면 보안에 치명적인 듯하다.

 

찾아보니 해당 오류를 더 방지할 수 있는 Safe Math 라이브러리가 있는 것을 발견했다. 듣고 있는 강의가 끝나면 해당 라이브러리를 도입해 볼 예정이다.

 

- Safe Math 참고 블로그

https://velog.io/@gunkk/%EC%86%94%EB%A6%AC%EB%94%94%ED%8B%B0-SafeMath-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0

 

솔리디티 SafeMath 이해하기

오버플로와 언더플로는 프로그램이 무한루프를 걸리게 하거나 고장나게 할 수 있다. 그러나 이더리움은 이러한 문제를 가스비를 이용해 자동으로 판단을 하도록 설계를 해두었다. 또한 프로그

velog.io