
스토리지에 값을 추가/수정하는
SSTORE는 EVM에서 매우 비싼 연산이다. 하지만 트랜잭션 중에만 값을 유지하는TSTORE를 사용하면 96% 이상 가스비를 절감할 수 있다.
이번 포스트에서는 EIP-1153transient storage를 활용하여 구현된 v4의Flash Accounting & Locking개념에 대해 알아본다.
SSTORE의 가스 소비량undefined, null, NIL, None 등 특수한 상태를 정의하여 초기화 이전 상태를 정의한다. 그러나 EVM의 모든 초기 상태는 0이고, 현재 시점에서 트랜잭션 종료 후에도 Contract의 상태를 유지할 수 있는 수단은 오로지 storage 밖에 없다.SSTORE의 가스비는 비싸게 책정되었다. 특히, 처음 슬롯을 할당하는 시점에는 더욱 비싸다. 이유는 슬롯 할당에 대한 제약을 낮출수록 많은 이들이 스토리지를 적극 활용하는 구현을 시작할 것이고, 이는 고스란히 노드의 부담으로 돌아가 결과적으로 체인의 수명을 단축시킬 것이기 때문이다.
tstore, tload는 EIP-1153를 통해 매 트랜잭션마다 초기화되는 임시 storage 변수를 사용할 수 있도록 제안했다. Cancun hardfork에서 처음 모습을 드러냈으며, solc version 0.8.24부터 해당 opcode의 사용을 지원한다.transfer 또는 Vyper의 send 함수는 고정적으로 낮은 가스비를 사용하여 Native Token을 전송했다. 덕분에 어떤 컨트랙트는 Reentrancy 공격에 취약한 구조였음에도 다행히 공격의 대상이 되지 않았다. 그러나 transient storage를 사용하면 재진입 시에도 상태를 매우 저렴한 가격에 보존할 수 있다.ChainSecurity 팀은 포스트를 통해 Cancun 이전의 컨트랙트와의 상호작용 괜찮지만, 새로운 컨트랙트의 상호작용에 유의해야 한다 고 설명했다. 이러한 기능 추가를 통해 개발 편의성과 연산 효율성이 증가했지만, 이와 동시에 결과적으로 기존 공격 벡터를 보다 활성화시키게 되었다.
transient storage활용 사례 #1
Pause처럼 컨트랙트의 상태 자체를 비활성화하는 것이라면 기존 storage를 사용해야 하지만,
Lock처럼 Reentrancy를 방지하기 위한 목적이라면 동일 트랜잭션 내에서만 상태가 유지되면 된다.
Locking은 Transient Storage의 컨셉을 소개하기에 가장 적합한 활용 사례 중 하나이다. Periphery contract는 PoolManager의 unlock() 함수를 호출하는 것으로 컨트랙트 이용 권한을 얻는다. 이후 로직 함수에 onlyWhenUnlocked modifier를 붙여 반드시 정해진 flow대로만 이용이 가능하도록 강제했다. 

transient storage활용 사례 #2
금을 거래한다고 실물을 배달하는 것은 거래 효율성을 떨어뜨린다.
각각의 트랜잭션에서 모든 유형의 거래를 장부에 기록하고,
최종적으로 서로가 원하던 결과를 얻었음만 확인하면 된다.
동일한 원리가Flash Accounting에도 적용된다.
실제 토큰을 전송하지 않고도, 장부에 기록된 내용을 활용하여 거래가 가능하다.
구현체에 대한 자세한 분석은 🚧 작성 예정
x*y>=k 조건을 활용했지만, v4에서는 거래 간 발생하는 delta, 즉, 유저와 PM 모두 서로에게 빚진 토큰이 없는지를 기준으로 삼는다.transient storage를 활용할 경우, 기존에 비해 가스비를 크게 절감할 수 있다.multi-hop swap을 진행하면 그 효율은 극대화된다. 한 트랜잭션 내에 n-1개 풀에 대한 swap 연산을 진행했을 때, v3는 모든 n개의 토큰 컨트랙트에 대한 상태 업데이트가 모두 이루어졌지만, v4는 ERC-1155: Multi Token Standard를 간소화 한 ERC-6909: Minimal Multi-Token Interface를 사용하여, 소유주의 다양한 토큰을 단 하나의 컨트랙트에서 모두 관리한다.