ERC-6808 키 결합 대체가능 토큰 (Fungible Key Bound Token)

Final · 토큰 · 2023-03-31 작성

ERC-20 토큰에 키 지갑 2개를 묶어 키 지갑이 미리 허용한 조건에서만 전송과 승인이 되게 하는 선택적 보안 표준입니다. 지갑이 뚫려도 자산을 대피시키거나 설정을 초기화할 수 있습니다.

왜 필요한가

셀프 커스터디 지갑은 개인키 하나에 모든 권한이 걸려 있습니다. 시드 구문이나 개인키가 한 번 유출되면 공격자가 토큰을 즉시 옮길 수 있고 되돌릴 방법이 없습니다. 원문에 따르면 2021년 1월부터 2022년 3월까지 미국 연방거래위원회에 4만 6천 건이 넘는 암호화폐 사기 신고가 접수됐고 소비자 피해액은 10억 달러를 넘었습니다. 하드웨어 지갑 같은 분산형 대안은 구매와 배송이 필요해 보급에 한계가 있고 중앙화 서비스는 계정 생성과 개인정보 제공을 요구합니다. 기존 ERC-20 토큰은 지갑이 뚫리는 순간 자산을 지킬 수단이 전혀 없습니다. 이 표준은 지갑이 아니라 자산 자체에 선택적 보안 기능을 넣어 세 지갑 중 하나가 뚫려도 토큰을 지킬 두 번째 기회를 주려는 시도입니다.

구현해야 하는 것

심층 설명

3-지갑 구조와 addBindings

토큰을 담은 보유 지갑(Holding Wallet)이 addBindings(_keyWallet1, _keyWallet2)를 호출하면 계정이 보안 상태가 되고 AccountSecured 이벤트가 발생합니다. 이후 자산은 보유 지갑에 있지만 쓰는 권한은 키 지갑이 쥐는 식으로 책임이 나뉩니다. 호출자가 보유자가 아니거나, 이미 보안 상태이거나, 두 키 지갑이 서로 같거나, 키 지갑이 호출자와 같거나, 키 지갑이 제로 주소이거나, 다른 보유 계정의 키 지갑으로 이미 쓰이고 있으면 되돌려야 합니다(SHOULD revert). addBindings를 아예 쓰지 않으면 일반 ERC-20과 같은 기본 동작을 합니다.

allowTransfer의 조건 지정

키 지갑이 transfer에 앞서 allowTransfer(_amount, _time, _to, _allFunds)를 호출해 전송을 허용합니다. _amount가 0이면 금액 제한이 없고 _time이 0이면 시간 제한이 없으며 _to가 제로 주소면 대상 제한이 없습니다. _allFunds가 true면 다른 매개변수와 무관하게 전액을 누구에게나 언제든 보낼 수 있게 허용합니다. 호출자가 키 지갑이 아니거나 _amount가 보유 계정 잔액보다 크면 되돌려야 하고 성공 시 AccountEnabledTransfer 이벤트를 반드시 발생시킵니다. 보안 계정이 이 허용 없이 transfer를 호출하면 전송이 되돌려져야 합니다.

allowApproval과 승인 통제

키 지갑이 allowApproval(_time, _numberOfTransfers)를 호출하면 보유 지갑이 _time 동안 approve, increaseAllowance, decreaseAllowance를 쓸 수 있고 지출자가 할 수 있는 전송 횟수가 _numberOfTransfers로 제한됩니다(0이면 허용량 한도 안에서 무제한). approve를 다시 호출하면 허용량과 허용 전송 횟수가 함께 덮어써집니다. transferFrom은 호출될 때마다 남은 횟수를 차감해 0이 되는지 확인하고 0이 되면 금액 0의 approve로 승인을 회수합니다. 보안 계정이 allowApproval 없이, 또는 설정된 시간이 지난 뒤 approve류 함수를 부르면 되돌려야 합니다.

두 가지 복구 장치: safeFallback과 resetBindings

safeFallback은 보유 지갑이 뚫렸거나 접근을 잃었을 때 키 지갑에서 호출합니다. 보유 계정의 모든 토큰이 호출한 지갑이 아닌 다른 키 지갑으로 이동하고 SafeFallbackActivated 이벤트가 발생합니다. resetBindings는 키 지갑이 뚫렸을 때 키 지갑에서 호출해 묶인 키 지갑들을 제거하고 AccountResetBinding 이벤트를 발생시킵니다. 초기화 후 토큰은 일반 ERC-20처럼 동작하며 보유 지갑이 addBindings를 다시 호출해 새 키 지갑을 묶을 수 있습니다. 두 함수 모두 호출자가 키 지갑이 아니면 되돌려야 합니다.

ERC-20 호환성과 선택적 보안

FKBT는 ERC-20(requires: 20)의 특성을 모두 물려받도록 설계됐습니다. 대체가능 토큰을 쓰는 기존 dApp에서 바로 쓸 수 있게 하기 위한 것으로, 기존 토큰과 지갑은 FKBT 도입의 영향 없이 그대로 동작합니다. allowTransfer와 allowApproval이 성공 시 bool을 반환하고 실패 시 되돌리는 것도 ERC-20과의 일관성을 위한 결정입니다. 또한 호출자는 returns (bool success)의 false를 반드시 처리해야 하며 false가 반환되지 않는다고 가정하면 안 됩니다.

조회 함수와 보유자 추적 이벤트

getBindings는 계정의 키 지갑 2개를, getTransferableFunds는 전송 허용 조건(amount, time, to, allFunds)을, getApprovalConditions는 승인 허용 조건(time, numberOfTransfers)을 구조체로 돌려줍니다. getApprovalConditions의 time은 approve류 함수를 부를 수 있는 기한인 block.timestamp 기준 시각입니다. getNumberOfTransfersAllowed는 지출자에게 남은 전송 횟수를, isSecureWallet은 보안 계정 여부를 알려 줍니다. 계정이 새로 보유자가 되면 Ingress, 전량을 보내 보유자가 아니게 되면 Egress 이벤트가 발생합니다. 참고로 원문 Test Cases에는 함수별 평균 가스 사용량이 기록되어 있습니다(addBindings 154,991 등).

쓸 때 주의할 점

ERC 원문 · ← ERCs