ERC-7540 비동기 토큰화 금고 확장 (Asynchronous ERC-4626 Tokenized Vaults)

Final · 금고·DeFi · 2023-10-18 작성

ERC-4626 토큰화 금고에 비동기 예치·환매를 더한 확장입니다. 요청(Request)을 먼저 제출하고 금고가 처리를 마치면 기존 ERC-4626 함수로 결과를 수령합니다.

왜 필요한가

ERC-4626 토큰화 금고 표준은 수익형 토큰을 디파이 전반에서 조합하기 쉽게 만들었지만 예치와 환매가 한 번의 호출로 즉시 끝나는 구조에 최적화되어 있습니다. 한도에 도달하면 새 예치나 환매를 아예 받을 수 없습니다. 그런데 현실 자산(RWA) 프로토콜, 저담보 대출, 크로스체인 대출, 리퀴드 스테이킹 토큰, 보험 안전모듈처럼 금고와 상호작용하기 전에 비동기 처리나 지연이 반드시 필요한 시스템에는 이 방식이 맞지 않습니다. 예를 들어 스테이킹 해제에는 대기 기간이 있어 환매를 즉시 처리할 수 없습니다. 이 표준은 요청을 먼저 제출하고 나중에 수령하는 2단계 흐름을 표준화해, 이런 비동기 사용 사례에서도 ERC-4626 금고의 인터페이스를 그대로 활용할 수 있게 합니다.

구현해야 하는 것

심층 설명

두 흐름의 선택과 ERC-4626 오버라이드

ERC-7540 금고는 비동기 예치와 비동기 환매 중 하나 이상을 반드시 구현해야 하고 구현하지 않은 쪽은 ERC-4626의 동기 방식 그대로 동작해야 합니다. 비동기 예치 금고에서는 자산 이전이 이미 requestDeposit에서 일어났으므로 deposit과 mint가 자산을 옮기지 않습니다. previewDeposit과 previewMint는 모든 호출자와 입력에 대해 반드시 revert해야 합니다. 비동기 환매 금고에서도 같은 이유로 redeem과 withdraw가 지분을 옮기지 않습니다. 두 함수의 owner 필드는 controller로 바꿔 부르기를 권고하고 controller는 msg.sender이거나 msg.sender를 오퍼레이터로 승인한 계정이어야 합니다. previewRedeem과 previewWithdraw도 반드시 revert해야 합니다.

요청 수명주기와 풀(pull) 원칙

요청은 제출 후 Pending, Claimable, Claimed 단계를 거칩니다. 요청이 바로 Claimable 상태로 넘어갈 수는 있지만 Claimable 단계를 건너뛸 수는 없습니다. 같은 블록 안이라도 사용자는 request 함수와 수령 함수를 각각 따로 호출해야 합니다. 금고가 요청 처리 후 토큰을 사용자에게 밀어 넣는(push) 방식은 금지되고 사용자가 직접 당겨 받아야(pull) 합니다. maxDeposit은 claimableDepositRequest와 함께 늘고 줄어듭니다. 대기 중인 환매 요청의 수익 발생 여부와 교환 비율 고정 여부는 구현에 달려 있습니다.

requestId 규칙

requestId는 requestDeposit과 requestRedeem이 돌려줍니다. 여러 요청이 같은 requestId를 가질 수 있어 요청은 requestId와 controller의 조합으로 구분합니다. 같은 requestId의 요청들은 서로 대체 가능해야 합니다. 즉 동시에 Pending에서 Claimable로 전환되고 같은 교환 비율을 받아야 합니다. requestId가 0이 아닌 요청이 부분적으로 수령 가능해지면 같은 requestId의 모든 요청이 같은 비율로 함께 수령 가능해져야 합니다. 서로 다른 requestId 사이에는 순서나 상관관계에 대한 어떤 요구도 없습니다. requestId가 0이면 금고는 오직 controller로만 요청 상태를 구분하고 같은 controller의 여러 요청을 합산합니다. 어느 한 요청에 0을 돌려주는 금고는 모든 요청에 0을 돌려줘야 합니다.

컨트롤러와 오퍼레이터

controller는 요청의 소유자로, 자산이나 지분의 수령을 포함한 요청 관련 행동을 관리합니다. 계정은 setOperator로 다른 계정을 오퍼레이터로 승인해 자신의 요청 관리를 맡길 수 있고 isOperator로 승인 상태를 조회합니다. requestDeposit의 owner는 msg.sender이거나 msg.sender를 오퍼레이터로 승인한 계정이어야 합니다. requestRedeem에서는 owner가 아닌 msg.sender의 권한이 지분에 대한 ERC-20 approve 또는 오퍼레이터 승인에서 올 수 있습니다. 한도 차감 방식은 ERC-6909의 승인·오퍼레이터 규칙과 일치해야 합니다. 또한 deposit과 mint에 controller 입력을 더한 오버로드를 반드시 지원해야 하고 msg.sender가 controller 본인이거나 승인된 오퍼레이터가 아니면 revert해야 합니다. 이때 Deposit 이벤트의 첫 매개변수는 controller, 둘째는 receiver여야 합니다.

requestMint와 requestWithdraw가 없는 이유

ERC-4626은 자산과 지분 변환에 대해 deposit/withdraw와 mint/redeem을 모두 두어 대칭을 이뤘지만 비동기 금고는 요청 시점에 수량이 확정되는 쪽으로만 동작할 수 있습니다. 예치에서는 assets, 환매에서는 shares가 그렇습니다. 요청한 shares에 해당하는 assets 양이 체결 전까지 변동할 수 있으므로 예치 요청 흐름은 mint 수량 기준으로, 환매 요청 흐름은 withdraw 수량 기준으로 만들 수 없습니다. 요청 취소 흐름도 표준에 포함하지 않았는데, 취소가 기술적으로 어려운 경우가 많고 동기일 수도 비동기일 수도 있어 별도 EIP로 표준화해야 한다고 봤기 때문입니다.

preview 함수를 revert로 강제한 이유

preview 함수에는 주소 매개변수가 없어 교환 비율 차이를 구분할 방법이 msg.sender뿐인데, 이러면 지원 컨트랙트가 controller를 대신한 수령 결과를 계산할 수 없는 통합 복잡성이 생깁니다. 또한 수령 단계에서 유효한 다음 상태 전이는 수령뿐이므로 미리보기의 온체인 이점이 없고 결과가 마음에 들지 않으면 호출 컨트랙트가 그 함수 호출의 출력을 보고 revert하면 됩니다. request 함수가 assets나 shares를 출력하지 않는 것도 수령 시점의 교환 비율을 요청 시점에 알 수 없기 때문입니다. Claimable 전환 시점의 이벤트도 구현마다 전환 방식이 달라 요구하지 않습니다.

ERC-165와 ERC-7575 지원 의무

이 표준을 구현하는 컨트랙트는 ERC-165 supportsInterface를 반드시 구현해야 합니다. 모든 비동기 금고는 오퍼레이터 메서드를 나타내는 0xe3bc4e65와 ERC-7575 인터페이스를 나타내는 0x2f0a18c5에 대해 true를 돌려줘야 합니다. 비동기 예치 금고는 0xce3bbe50, 비동기 환매 금고는 0x620ee8e4에 대해 true를 돌려줘야 합니다. 예치와 환매의 비동기 여부가 선택 사항이므로, 통합하는 쪽은 이 조회로 금고 유형을 판별해 하나의 컨트랙트로 모든 경우를 지원할 수 있습니다. 또한 ERC-7575 표준, 특히 share 메서드를 반드시 구현해야 합니다. 이 제안의 상태는 Final로 확정되어 있습니다.

쓸 때 주의할 점

ERC 원문 · ← ERCs