[ERC20] 토큰만들기 + 문제점

개발개발·2022년 11월 21일
0

NFT를 다룬 ERC721에 이에서 FT를 다루는 ERC20을 살펴보았다.

거래소에 상장되어 있는 많은 코인들이 이더리움 네트워크상에서 ERC20을 통해 생겨난 것들이다. EIP20을 보면서 구성요소를 살피고 공격당할 수 있는 부분까지 확인해본다.


초록을 보면 토큰 전송 및 제 3자가 사용할 수 있도록 사용을 승인하는 기능을 가지고 있다.

아래는 ERC20 인터페이스다.

function name() public view returns (string)
function symbol() public view returns (string) 
function decimals() public view returns (uint8) // 소수점 자리수, default 18
function totalSupply() public view returns (uint256) // 총 발행량
function balanceOf(address _owner) public view returns (uint256 balance) // 계좌의 잔액
function transfer(address _to, uint256 _value) public returns (bool success) // 전송(실행 주체가 전송자)
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) // 전송
function approve(address _spender, uint256 _value) public returns (bool success) // 승인된 금액 확인
function allowance(address _owner, address _spender) public view returns (uint256 remaining) // 누가(A) 누구에게(B) 얼마를 줄 수 있는가
event Transfer(address indexed _from, address indexed _to, uint256 _value)
event Approval(address indexed _owner, address indexed _spender, uint256 _value)

ERC20 을 구현한 토큰인 SAND를 보면서 확인해보려 한다.

웹사이트에서 보면 symbol, total supply, decimals를 바로 확인할 수 있다.

contract 시그니처를 보면 ERC20 interface를 상속받고있는 것을 알 수 있다. 생성자에서 _mint 함수를 통해 발행자 지갑에 total supply를 입력해서 민팅한다. 그 밑에 이름과 심볼을 정했다. 기본적인 내용만 이해하고자 하므로 구현한 내용에 대해서는 더 살펴보지 않았다.

  • 유의할 내용

EIP20 문서를 보면 approve 함수 부분에서 유의점을 설명한다.

approve 함수
1. spender가 value만큼 사용할 수 있도록 해준다.
2. 트랜잭션이 커밋되기 전에 approve 함수를 다시 호출하면 value 값이 최신 값으로 변동된다.

2번 항목 때문에 문제가 발생할 수 있다. 문제가 발생할 수 있는 시나리오는 아래와 같다.

  1. 사토시가 비탈릭에서 N을 전송한다. contract에서 approve(첫번째 트랜잭션) 함수의 파라미터로 비탈릭의 계좌와 N을 넘긴다.
  2. 사토시가 비탈릭에게 승인한 value를 N에서 M으로 바꾸려고 한다. 그래서 다시 한번 더 approve 함수(두번째 트랜잭션)를 호출한다. 파라미터의 주소는 동일하지만 value는 M이다.
  3. 여기서 비탈릭은 두번째 트랜잭션이 채굴되기 전에 알아차리고 빠르게 N값을 사용(세번째 트랜잭션)해버린다.(첫번째 트랜잭션은 이미 채굴되었다)
  4. 비탈릭이 N 값을 사용(세번째 트랜잭션)이 두번째 트랜잭션보다 먼저 실행된다면 비탈릭은 성공적으로 N값을 사용하게 된 것이다.
  5. N값을 전송하고나서 N값을 M으로 바꾸는 두번째 트랜잭션이 성공하면 비탈릭은 다시 M값을 사용할 수 있게 된다.
  6. 사토시가 문제를 알아차리기 전에 비탈릭은 M값을 사용해버린다.

---> 사토시가 비탈릭에게 N값을 M만큼 사용할 수 있도록 변경을 시도했지만 비탈릭은 N+M만큼의 값을 사용한 것이 된다.

문제를 예방하기 위해서는 NOTE에 나와있듯이 동일한 spender에게 값을 전송할 경우 초기값을 0으로 설정해서 contract를 작성하라고 알려주고 있다.

EIP20 -> https://eips.ethereum.org/EIPS/eip-20
공격 위험설명 -> https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/edit#

profile
청포도루이보스민트티

0개의 댓글