Jekyll2022-08-02T14:10:19+00:00https://bears-team.github.io//feed.xmlBears Team BlogBEARS means Blacksmith Enhanced Armor for Robust Smart-contract. The purpose of BEARS team is to analyze and learn the old and contemporary vulnerabilities of smart-contract as quickly as possible. And our team will research various methods for discovering the vulnerabilities of smart-contract. Furthermore, our team survey and research the bussiness model of blockchain ecosystem including system trading algorithms.BEARSA Survey On DEX Protocol Part1: Leveraged Yield Farming-Part2(Tokenflow Analysis)2022-07-04T22:00:00+00:002022-07-04T22:00:00+00:00https://bears-team.github.io//background/smart%20contract/bears%20team/tokenflow%20analysis/bears-a-survey-on-dex-protocol-leveraged-yield-farming-part2<h1 id="executive-summary">Executive Summary</h1>
<h1 id="introudction">Introudction</h1>
<h1 id="project-configuration-troubleshooting">Project Configuration Troubleshooting</h1>
<h2 id="case1--compile-failed">CASE#1 : Compile Failed</h2>
<h2 id="case2--metamaskbalanaceof-doent-work">CASE#2 : Metamask(BalanaceOf doen’t work)</h2>
<h2 id="case3--import-failedhardhat">CASE#3 : import failed(Hardhat)</h2>
<h1 id="service-componentssource-code-level">Service components(Source Code Level)</h1>
<h1 id="tokenflow-analysis">Tokenflow Analysis</h1>
<p>Tokenflow라는 단어는 구글에 검색해도 잘 안 나올겁니다. 왜냐하면 제가 만든 용어라서 그렇습니다. 일반적으로 우리가 기존 시스템(x86, Android, iOS, …)에서 취약점을 탐지하기 위해서 분석을 할 때, 크게는 두 가지 관점에서 분석을 합니다. 바로 Controlflow, Dataflow입니다. Controlflow는 함수 호출을 중심으로 기능을 분석하면서, 취약한 로직, 코드가 있는 부분을 발견 버그를 취약점을 발전시키는 것이라면 Dataflow 분석은 입력데이터로 부터 이 입력 데이터가 영향을 주는 코드를 중심으로 분석하면서 취약점을 탐지하는 분석입니다. Dataflow기반 취약점 탐지 방법으로는 가장 유명한 기법이 Taint analysis라고 볼 수 있습니다. 이러한 관점을 Blockchain에게 적용했을 때 결국 Smart Contract에서의 취약점이 의미가 있을려면 Token의 무단 인출이 가능해야 함으로 Token을 중심으로 DApp을 분석하자는 관점으로 Tokenflow라는 용어를 만들어 봤습니다. 스마트 컨트렉트 생태계애서의 Dataflow라고 생각할 수 있습니다. 앞으로 제 포스팅에서는 Tokenflow, Tokenflow analysis라는 용어를 계속 사용할 계획입니다.</p>
<h2 id="the-overview-tokenflow">The Overview Tokenflow</h2>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-06-22-bears-a-survey-on-dex-protocol-leveraged-yield-farming-part2/alpaca_farm02.png" alt="Image Alt 텍스트" /></td>
</tr>
<tr>
<td>그림.1 Alpaca Finance Leveraged Yield Farming 중심의 서비스 관계도</td>
</tr>
</tbody>
</table>
<ul>
<li>Alice : 대여자(Lender), BNB토큰을 Lending Pool, 코드상 Vault에 예치하고 대응하는 ibToken인 ibBNB를 받게 된다. 관련코드는 <a href="https://github.com/alpaca-finance/bsc-alpaca-contract/blob/c6fafa2a9f32604464ed3a5116384a476800e45c/solidity/contracts/6/protocol/Vault.sol#L207">여기</a>를 보면됩니다. 실제 코드를 보면 BNB가 아니라 WBNB(Wrapped BNB)라는 것을 확인할 수 있는데, 이것에 대해서는 좀더 조사를해서 내용을 보완하겠습니다. 여기서 우리가 알아야할 것은 최초의 외부 지갑에서 돈이 흘러들어가는 것을 과정을 분석하기 위해서 Vault.sol 파일을 분석해야한다는 사실입니다.</li>
</ul>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>// Solidity
address vaultContractAddress = '0xd7D069493685A581d27824Fc46EdA46B7EfC0063'; // BNB Vault
if (msg.value == 0) { // if no native token is sent, then it is a ERC20/BEP20 token deposit
IERC20(tokenAddess).safeTransferFrom(address(msg.sender), address(this), amountToken);
}
// Allow transfer to vault
SafeToken.safeApprove(tokenAddess, vaultContractAddress, amountToken);
// Deposit to vault
IVault(vaultContractAddress).deposit(amountToken);
</code></pre></div></div>
<p>예치시 받는 ibToken의 가치는 아래와 코드의 계산과정을 거쳐서 결정됩니다.
Vault는 ERC20 토큰 컨트렉트를 상속하기 때문에 totalSupply() 함수는 <a href="https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20-totalSupply--">Openzeppelin 사이트</a>에서 확인 가능하다. totalToken()은 Vault내 BNB토큰의 전체 개수이고 totalSupply()는 전체 발행된 ibToken의 개수입니다.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>// Solidity
address vaultContractAddress = '0xd7D069493685A581d27824Fc46EdA46B7EfC0063'; // BNB Vault
IVault vault = IVault(vaultContractAddress);
uint256 ibTokenAmount = ...;
uint256 ibTokenPrice = vault.totalToken()).div(vault.totalSupply();
uint256 underlyingTokenAmount = ibTokenAmount.mul(ibTokenPrice);
</code></pre></div></div>
<ul>
<li>Bob : 이자 농사 농부(Farmer), 그림.6에서는 BTC/BNB 페어에서 이자농사를 하기를 원하며, BTC를 예치하고, BNB를 빌리는 형태로 레버리지 이자 농사를 실시, 이 때 Bob의 전제는 BTC가격이 오를 것을 예상하고 농사를 하는 것이며, 앞에서 설명한 Long(롱) 포지션에 해당합니다. 소스코드에서도 이 동작을 확인하고 싶어서 찾고 있으며, 아직 확인하지 못 했습니다.</li>
<li>Erin : 청산 봇(Liquidator bot), Bob과 같이 레버리지 이자 농사를 하는 경우 담보물의 가치 변동에 따른 청산이 발생할 수 있는데, 이 작업을 돕는 봇이며 청산시 보상으로 \(5%\) 를 수수료를 챙기며, 이 수수료로 Alpaca 거버넌스 코는 Alpaca를 소각하는데 활용, Alpaca 토큰의 가격 상승의 동력을 만들어냅니다. 변동성이 강할때 청산이 많이 발생함으로 그 때 Alpaca Finance는 많은 수익 창출이 가능합니다. 코드상 확인이 필요합니다.</li>
<li>Carlos : 보상 헌팅 봇(Bounty Hunter Bot), 각각의 풀에 보상들이 자동으로 재투자되는지 확인하고 감시하는 역할을 담당하는 봇이라고 하는데, 정확하게 확인이 필요할 것 같습니다. 모든 이자 농부들이게 복리 이자를 자동 지급하는 역할을 한다고 하며, 이 역할을 수행함으로서 보상의 약 \(3%\) 의 수수료를 챙긴다고 되어 있습니다. 이 수수료를 Alpaca 개발팀에서 가져가게 됩니다.</li>
</ul>
<p>위 Alpaca Finance내 참여자들의 구성을 볼때, 우리가 집중해서 분석해야할 코드는 Alice와 Bob인 것을 확인할 수 있습니다. 결국 Vault에 큰 돈이될 토큰이 있으므로 Alpaca 서비스에서 돈을 빼낸다면 Vault에 집중해야할 것으로 보이고, Yield Farming쪽에서 돈을 빼낼 방법을 고민할려면 연동된 서비스 코드까지 광범위하게 분석해야할 것입니다.</p>
<p>Alpaca Finance 서비스에서는 일반 시중은행에서 다양한 투자회사의 금융상품을 판매하는 것 처럼 다양한 연동서비스의 상품을 취급하고 있습니다. Alpaca Finance에서 제공하는 상품은 다음과 같습니다.</p>
<ul>
<li>PancakeSwap Farms(BNB)</li>
<li>Mdex Farms(BNB)</li>
<li>Biswap Farms(BNB)</li>
<li>SpookySwap Farms(Fantom)</li>
<li>WaultSwap Farms(Deprecated)</li>
</ul>
<p>Alpaca 서비스의 contract 소스코드에서도 위 서비스를 확인할 수 있습니다.</p>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-06-22-bears-a-survey-on-dex-protocol-leveraged-yield-farming-part2/alpaca_project01.png" alt="Image Alt 텍스트" /></td>
</tr>
<tr>
<td>그림.2 Alpaca Finance 프로젝트 폴더, Alpaca Finance의 경우 외부 서비스의 풀을 그대로 활용하고 있음을 알 수 있다.</td>
</tr>
</tbody>
</table>
<p>또한 <a href="https://docs.alpacafinance.org/leveraged-yield-farming/pool-specific-parameters-1/pool-specific-parameters#pancakeswap-tusd-pairs-1">이곳 문서</a>를 확인하면, PancakeSwap 풀중에서 Alpaca Finance에서 지원하는 서비스별 Contract주소를 확인할 수 있습니다.</p>
<p>Alpaca 서비스의 경우 자신들이 서비스하는 <a href="https://github.com/alpaca-finance/bsc-alpaca-contract/blob/c6fafa2a9f32604464ed3a5116384a476800e45c/.mainnet.json#L709">토큰쌍 풀의 컨트렉트(Contract)주소</a>를 json형태로 유지관리 하고 있는 것을 확인할 수 있습니다.</p>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-06-22-bears-a-survey-on-dex-protocol-leveraged-yield-farming-part2/alpaca_pancake01.jpg" alt="Image Alt 텍스트" /></td>
</tr>
<tr>
<td>그림.3 Alpaca Finance와 PancakeSwap간의 Tokenflow</td>
</tr>
</tbody>
</table>
<h2 id="the-detailed-tokenflowwith-respect-to-bnb">The Detailed Tokenflow(With respect to BNB)</h2>
<p>소스코드 분석을 기반으로 EOA(개인지갑)에서 부터 Pancakeswap까지의 흐름을 도식화한 것입니다. 아래 그림.4에서 PancakeswapWork가 바로 Yield Farming에 관련된 핵심 컨트렉트입니다.</p>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-06-22-bears-a-survey-on-dex-protocol-leveraged-yield-farming-part2/overview_alpaca_tokenflow.png" alt="Image Alt 텍스트" /></td>
</tr>
<tr>
<td>그림.4 EOA에서 PancakeSwap까지의 Tokenflow</td>
</tr>
</tbody>
</table>
<h3 id="왜-yield-farming-컨트렉트-파일의-접미사가-worker일까">왜 Yield Farming 컨트렉트 파일의 접미사가 Worker일까?</h3>
<ul>
<li>소스코드를 분석하면 다양한 Worker들이 존재하는 것을 확인할 수 있음</li>
<li>연동되는 서비스별 Work가 존재함</li>
<li>개인적인 생각으로는 Vault의 자산 증식에 기여하는 일꾼이라는 개념으로 Worker라는 접미사를 붙인 것으로 추정함</li>
</ul>
<h3 id="overview를-통해-확인하는-alpaca-finance의-수익-구조">Overview를 통해 확인하는 Alpaca Finance의 수익 구조</h3>
<ul>
<li>Alpaca Finance 서비스를 통해 Yield Farming을 위해 부족한 돈은 위 그림.4에서 처럼 Alpaca Finance내 Vault에서 대출 받게 됨.</li>
<li>이는 대출 수수로 형태로 Vault의 자산을 늘이게 됨</li>
<li>또한 Vault에 유동성을 공급하는 사람들이 추가적인 이자수익을 획득하기 위해 ibToken를 FairLaunch를 통해 Alpaca Token를 받고, 이 Alpaca Token를 스테이킹하거나 유통하여 Alpaca Token을 유통시킴, 이 유통의 힘으로 Alpaca Finance의 가치 상승에 기여함</li>
<li>Yield Farming을 하는 가운데, 청산이되는 농부들이 있을 것이며, 해당 청산을 통해 Vault 및 Alpaca Token의 가치를 향상 시켜서 이윤을 창출함</li>
<li>Alpaca Token의 가치 상승, 에초에 개발자 그룹에 할당된 Alpaca Token의 매도를 통해, 개발자 그룹은 현금 확보가 가능함</li>
</ul>
<h1 id="conclusion">Conclusion</h1>
<h1 id="references">References</h1>
<ul>
<li><a href="https://medium.com/@versofinance/understanding-leveraged-yield-farming-72b5f8609a0a">https://medium.com/@versofinance/understanding-leveraged-yield-farming-72b5f8609a0a</a></li>
<li><a href="https://alphafinancelab.gitbook.io/alpha-homora-vbsc/what-is-leveraged-yield-farming">https://alphafinancelab.gitbook.io/alpha-homora-vbsc/what-is-leveraged-yield-farming</a></li>
<li><a href="https://docs.alpacafinance.org/help-center/alpaca-academy/lesson-3-liquidation-risk-in-leveraged-yield-farming">https://docs.alpacafinance.org/help-center/alpaca-academy/lesson-3-liquidation-risk-in-leveraged-yield-farming</a></li>
<li><a href="https://alphaventuredao.io/">https://alphaventuredao.io/</a></li>
<li><a href="https://docs.kleva.io/v/copy-of/undefined-1/undefined-3/3">https://docs.kleva.io/v/copy-of/undefined-1/undefined-3/3</a></li>
<li><a href="https://medium.com/alpaca-finance/introducing-alpaca-finance-d6e858896efd">https://medium.com/alpaca-finance/introducing-alpaca-finance-d6e858896efd</a></li>
<li><a href="https://thedefiant.io/leveraged-yield-farming/">https://thedefiant.io/leveraged-yield-farming/</a></li>
<li><a href="https://francium.io/app/calculator">https://francium.io/app/calculator</a></li>
<li><a href="https://github.com/alpaca-finance/bsc-alpaca-contract/tree/main/solidity/contracts">https://github.com/alpaca-finance/bsc-alpaca-contract/tree/main/solidity/contracts</a></li>
<li><a href="https://medium.com/immunefi/belt-finance-logic-error-bug-fix-postmortem-39308a158291">https://medium.com/immunefi/belt-finance-logic-error-bug-fix-postmortem-39308a158291</a></li>
<li><a href="rpc.info">rpc.info</a></li>
</ul>PandaDeFi 취약점 연구를 위한 DeFi 프로토콜 분석, 그 첫번째 Alpaca Finance에 대한 Overview에 이어 Tokenflow 분석 결과에 대한 글입니다.The Timeline of DeFi Exploits: Fulcrum of bZx2022-07-04T22:00:00+00:002022-07-04T22:00:00+00:00https://bears-team.github.io//security/smart%20contract/incident/cryptosec-timeline-of-defi-exploits-fulcrum-and-bZx%20-%20%EB%B3%B5%EC%82%AC%EB%B3%B8<h1 id="introudction">Introudction</h1>
<h1 id="fulcrum-had-a-25m-vulnerability-over-a-month-ago-and-still-hasnt-told-anyone">Fulcrum had a $2.5m vulnerability over a month ago and still hasn’t told anyone</h1>
<ul>
<li>단 하나의 트렌젝션(Flashloan)에 의해 2.5M정도 해킹당할 수 있었으나, 1inch팀에서 사전에 제보</li>
<li>해당 문서에는 취약점에 대한 기술적인 내용은 없고, bZx팀과의 1inch팀간의 다툼만 기록되어 있음</li>
</ul>
<h2 id="issues-between-1inch-and-bzx">Issues between 1inch and bZx</h2>
<ul>
<li>첫번째 논란은 보상과 관련된 것, 무려 2.5M을 잃어 버릴 수 있는 취약점인데도 bZx 팀에서는 1.5k를 제안, 단순히 취약점을 패치하거나 공격하는데 코드가 몇 줄 안된다는게 이유, 결국 두 팀간의 논의 끝에 3.5k에 합의</li>
<li>패치 이후에 bZx는 아무런 일이 없었던 것 처럼 행동하기를 원했음. 심지여 NDA를 서명하지 않았음에도 1inch팀이 입다불고 있기를 협박한 것으로 보임</li>
<li>그리고 몇 주 후 아래의 2월15일에 Flashloan을 활용한 공격이 bZx에 있었고, bZx는 1inch팀을 해킹의 배후로 지목하면서, 모욕적인 언행을 보임, 1inch 팀으로봐서는 화가날 만한 것 같음</li>
</ul>
<h2 id="vulnerability">Vulnerability</h2>
<ul>
<li>취약점 분석을 위해, 공식 github를 살펴보았지만 Fulcrum 서비스 관련 소스코드 레파지토리가 없음</li>
<li>여전히 bZx사의 Fulcrum DeFi 서비스에서는 아래 그림과 같이 OpenSouce라고 광고하고 있음</li>
</ul>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-07-01-cryptosec-timeline-of-defi-exploits-fulcrum-and-bZx/fulcrum02.png" alt="Image Alt 텍스트" /></td>
</tr>
<tr>
<td>그림.1 bZx의 Fulcrum 서비스 Opensource라고 광고하지만, 실제 github에 아무것도 없음</td>
</tr>
</tbody>
</table>
<ul>
<li>사고대응 부터 정직함까지 무엇하나 믿을 수 없는 회사이고, 절대 이 DeFi에는 돈을 예치하면 안 될 것으로 판단됨</li>
</ul>
<h1 id="arbs-exploit-defi-to-make-900k-in-seconds-provoke-soul-searching-in-the-process">Arbs Exploit DeFi to Make $900k in Seconds; Provoke Soul-Searching in the Process</h1>
<ul>
<li>bZx와 Fulcrum은 동일한 의미로 사용됨</li>
<li>Flashloan기능을 활용한 시세차익 공격에 대한 분석 글</li>
</ul>
<h2 id="attack-scenario">Attack Scenario</h2>
<p>공격 시나리오는 다음과 같습니다.</p>
<ul>
<li>해커가 10k ETH를 flashloan으로 <a href="https://dydx.exchange/">dydx</a> 거래소에서 빌림</li>
<li>해커가 5.5k ETH를 112 WBTC(Wrapped Bitcoin)으로 Compound DeFi에서 교환함</li>
<li>bZx의 마진 거래 기능을 활용해서, 최대 레버리지 BTC기반 ETH를 숏포지션(매도하여 가격을 떨어뜨림)을 잡아서, 많은 양의 ETH를 BTC로 교환하도록 유도. 즉 ETH의 가치 하락을 의도했다라고 보며, 실제 공격에 1.3k ETH가 활용됨</li>
<li>해커의 요청(5배 숏포지션)을 처리할려고, bZx는 5.6k ETH를 Kyberswap에서 51 WBTC로 교환 시도, Kyberswap는 이 요청을 처리하기 위해 Uniswap에 주문하고 이로 인해 Uniswap에서 WBTC 가격이 갑자기 상승함</li>
<li>스와핑 서브시에서 최대한 좋은 교환비로 ETH와 BTC를 교환을 시도했지만, 원래 51 BTC의 적절한 가치는 2k ETH이며, BTC와 ETH 모두 총 공급량이 타토큰 대비 상대적으로 상당히 제안되게 공급이 이뤄지기 때문에 가격이 급상승하게 되었고, 51BTC에 대해 5.6k를 bZx가 지불하게 됨</li>
<li>bZx에서는 마진거래를 마감할 때가 되면 ETH 가격이 오르면, 해커의 예치금을 공제해 손실을 만회함. 하지만 해커의 예치금을 손실을 만회할 정도로 충분하지 않음(2k –> 5.6k, 약 3배 올랐음)</li>
<li>현재 bZx의 실질적은 손실은 2.3k ETH 정도 됨 만약에 해커가 마진 거래를 살리지 않는다면…</li>
<li>Uniswap의 경우 스와핑 알고리즘이 CPMM임으로 현재 ETH의 가치가 BTC대비 떨어져 있음, 해커는 112 BTC를 Uniswap 풀에서 교환함, 약 6.8k ETH를 얻음, 이제는 BTC대비 ETH의 가치가 올라갔음</li>
<li>담보로 잡힌 5.5k ETH를 해제하기 위해서 112 WBTC의 가치에 해당하는 4.2k ETH를 컴파운드에 상환함</li>
<li>해커는 이제 12.5k ETH를 자산을 가지고 있고, 바로 10.0k ETH를 bZx에 상환하고, 쿨하게 1.3k ETH를 포기하고, 1.2k ETH의 이익을 취한다. bZx는 2.3k ETH의 영구적 손실을 입음</li>
</ul>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-07-01-cryptosec-timeline-of-defi-exploits-fulcrum-and-bZx/bZx_attack_ani.gif" alt="Image Alt 텍스트" /></td>
</tr>
<tr>
<td>그림.2 bZx대상 Flashloan기반 공격 시나리오 애니메이션</td>
</tr>
</tbody>
</table>
<p>다양한 자료에 공격에 대한 그림이 존재하지만, 해커를 중심에두고 순차적으로 공격을 그림으로 표현했기 때문에, 아마 공격에 대한 이해가 가장 쉬울 것으로 판단된다.</p>
<h2 id="discussion">Discussion</h2>
<p>앞에서 공격에 대한 그림을 봤지만, Flashloan의 기능을 기반으로 하는 공격이며, 그렇지만 중요한 것은 왜 bZx인지를 알아내는 것이 블록체인 보안을 학습하는 입장에서는 중요하다. 과거 윈도우, 리눅스 보안에서의 표현을 빌리면 왜 수만은 Attack Surface중에 bZx라는 공격 벡터를 선택했느냐? 이것에 대해서 의견을 나눠볼 필요가 있고 이 것에 대한 토론 결과를 가지고 소스코드 분석을 통해 최대한 검증할 수 있는 것은 검증하는 것이 중요하다고 생각된다.</p>
<ul>
<li>왜 ETH/BTC 일까?
<ul>
<li>BTC, ETH 이 두 토큰은 매우 시장에서 희소성을 가지고 있음, 타 토큰 대비 발행량이 매우 적음(추정)</li>
</ul>
</li>
<li>해커는 공격 목표 DeFi를 어떤 기준으로 선택했을까?(왜 bZx인가?)
<ul>
<li>Flashloan 기능을 지원해야 한다.(Mandatory !!!)</li>
<li>Uniswap과 같은 CPMM기반의 Swapping 서비스를 활용해야 한다.</li>
</ul>
</li>
<li>Compound에서 돈을 빌린 이유는?</li>
</ul>
<h2 id="mitigation">Mitigation</h2>
<p>bZx가 유사한 공격으로부터 자신들을 지키기위해 어떻게 패치했는지 그 내용을 분석해서, 이 섹션에 기술해야 하지만 b2x사는 Fulcrum 소스코드를 다 지워서 어떤 식으로 패치했는지 확인할 수 없음. 아마도 전부 비공개로 전환한 것으로 판단됨</p>
<h1 id="fulcrum-itoken-duplication-incident">Fulcrum iToken Duplication Incident</h1>
<ul>
<li>20년 9월 15일에 발생한 bZx의 ibTokne인 iToken관련 취약점으로 약 8백만 달러 상당의 사고가 발생함</li>
<li>자세한 내용은 모르겠지만, 해커를 식별했고, 검거해서 돈을 돌려 받음</li>
<li>해커에 대한 법적 책임에 대한 부분은 노코멘트, 아마도 고소를 취하하던지 법적인 책임을 묻지 않는 선에서 해커와 합의를 한 것으로 추정됨</li>
<li>Marc Thalen이라는 Bitcoin.com의 엔진니어는 자기가 최초로 이 버그를 발견했다라고 주장, Marc의 경우 $4.5k를 bZx로 받았음. 다른 글을 확인해보니 공격이 시작되고, 종료되기 전 이 가운데 어디쯤에서 취약점에 대해서 제보한 것으로 보임. Marc Thalen이 제보하기 전까지 bZx는 무엇이 잘못되었는지도 모르고 있었음</li>
</ul>
<h2 id="cause-of-vulnerabilitycov">Cause of Vulnerability(COV)</h2>
<ul>
<li>문제가 되는 소스를 확인할 수는 없음. github 통채로 없어짐</li>
<li>취약점은 너무나 간단한데, transfer 함수에서 from, to의 주소에 대한 검증이 없어서임</li>
<li>즉 from과 to가 동일한 주소일때 벨란스가 0이 되었다가, 2배가 되는 기적이 일어남</li>
<li>그림 3을 보면 공격자가 자기 계좌에 100개의 토큰이 있고, 전체를 자신의 주소로 전송하는 코드를 만들면</li>
<li>그림 3의 balanceFrom도 100이고, balanceTo도 100이된다.</li>
<li>이 상태에서 그림.3의 아래 코드를 수행하게 되면 balanceFormNew는 100에서 100을 빼게 됨으로 잠시 나의 계좌가 0이 되었다가 balanceNew는 200이므로 내 계좌는 200으로 업데이트 된다.</li>
<li>이를 무한히 반복하면 내 계좌의 돈을 계속 늘일 수 있음</li>
</ul>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-07-01-cryptosec-timeline-of-defi-exploits-fulcrum-and-bZx/code1.png" alt="Image Alt 텍스트" /></td>
</tr>
<tr>
<td><img src="/assets/images_post/2022-07-01-cryptosec-timeline-of-defi-exploits-fulcrum-and-bZx/code2.png" alt="Image Alt 텍스트" /></td>
</tr>
<tr>
<td>그림.3 bZx Fulcrum의 문제가 되는 코드 조각, from, to 주소에 대한 검증 부재로 발생하는 문제</td>
</tr>
</tbody>
</table>
<h1 id="conclusion">Conclusion</h1>
<ul>
<li>우리는 Flashload 기능을 활용한 bZx을 대상으로 한 공격을 살펴봤음. 이 공격의 핵심은 Flashloan 기능에도 있지만, 또한 Uniswap과 같은 CPMM 알고리즘을 기반으로 토큰간의 가치를 결정하는 변동성에도 있는 것으로 판단됨</li>
<li>1inch사와 bZx사의 다툼을 보면 bZx사의 DeFi 프로토콜에 자산을 예치하는 것에 대해서 부정적인 생각이 들며 극도의 신중함이 필요해 보임</li>
</ul>
<h1 id="references">References</h1>
<ul>
<li><a href="https://cryptosec.info/defi-hacks/">https://cryptosec.info/defi-hacks/</a></li>
<li><a href="https://blog.1inch.io/yes-we-hacked-bzx-fulcrum-but-one-month-ago-3f7e5c437ee3">https://blog.1inch.io/yes-we-hacked-bzx-fulcrum-but-one-month-ago-3f7e5c437ee3</a></li>
<li><a href="https://newsletter.thedefiant.io/p/arbs-exploit-defi-to-make-900k-in">https://newsletter.thedefiant.io/p/arbs-exploit-defi-to-make-900k-in</a></li>
<li><a href="https://www.coinbase.com/learn/market-updates/around-the-block-issue-3">https://www.coinbase.com/learn/market-updates/around-the-block-issue-3</a></li>
<li><a href="https://mudit.blog/bzx-hack-analysis-defi-legos/">https://mudit.blog/bzx-hack-analysis-defi-legos/</a></li>
</ul>Panda2020년 1월 11일, 2020년 2월 15일에 발생했던 Fulcrum, bZx DeFi 해킹사건에 대한 조사 결과입니다.A Survey On DEX Protocol Part1: Leveraged Yield Farming-Part1(Overview)2022-06-13T22:00:00+00:002022-06-13T22:00:00+00:00https://bears-team.github.io//background/smart%20contract/bears%20team/bears-a-survey-on-dex-protocol-leveraged-yield-farming<h1 id="executive-summary">Executive Summary</h1>
<p>DeFi에 대한 취약점 탐지를 위해 현재 DeFi서비스의 프로토콜을 이해하는 것이 중요하기 때문에, 실제 코드 감사에 앞서 DeFi서비스 프토토콜에 대해서 조사한 내용을 BEARS 세미나에서 공유하는 목적으로 작성된 포스트입니다.</p>
<h1 id="introudction">Introudction</h1>
<p>이 번 포스트는 “Leveraged Yield Farming” 프로토콜에 대한 포스트입니다. DeFi의 취약점을 코드 기반으로 탐색하고 공격하는 연구에 앞서 DeFi의 다양한 프로토콜을 이해하고 전체적인 토큰 플로우를 알아보는 시간을 먼저 가지는 것이 중요하다는 생각을 다양한 취약점 케이스 분석 글을 확인하던 중 들었습니다. 실제 취약점의 원인을 분석하면 그 원인 자체는 단순합니다. 개발자의 실수, 사용하지 말아야할 주소 사용, Reentrancy와 같은 고전 취약점 그러나, 이런 취약점을 이해하고 있더라도, DeFi 서비스가 어떤 유형에 포함되고 전체적인 토큰의 흐름을 알지 못 하면 실제 속칭 돈이 되는 취약점을 찾기가 어려울 수 있습니다. 따라서 DeFi 프로토콜을 먼저 이해하고, 해당 프로토콜에서 주로 발생하는 취약점을 케이스 스터디하고 해당 취야검 사례를 기반으로 유사한 서비스에 대해서 비슷한 취약점이 존재하는지 살펴보는 순으로 진행하는 것이 보다 적절한 접근으로 보입니다. 이 번 포스트는 DeFi 프로토콜의 첫 번째로 Leveraged Yield Farming에 대해서 알아보고 이후 포스트에서 해당 서비스와 연관된 <a href="https://medium.com/immunefi/belt-finance-logic-error-bug-fix-postmortem-39308a158291">취약점 사례</a>를 다음 포스트에서 살펴보로록 하겠습니다.</p>
<h1 id="background">Background</h1>
<h2 id="entities">Entities</h2>
<h3 id="lenders대여자">Lenders(대여자)</h3>
<ul>
<li>기존 금융체계에서 은행에 돈을 예금하는 것과 유사함</li>
<li>스테이킹과 달리 자유롭게 예치(Deposit), 출금(Withdraw)할 수 있음</li>
<li>대여자의 수익모델은 예치에 대한 이자(interest) 수령을 통한 모델임</li>
<li>대여자의 수익은 농부가 얼마나 랜딩풀을 활용하는지에 따라서 지급받는 이자수익도 달라지게 되며, 대여자의 경우 DeFi내에서 비교적 안정적인 장기수익을 기대할 수 있음</li>
</ul>
<h3 id="farmer농부">Farmer(농부)</h3>
<ul>
<li>이자농사에 참여하는 대상자를 농부(Farmer)로 지칭함</li>
<li>이자농사를 위해 일정한 자기 자산을 담보물로 제공해야함</li>
<li>랜딩풀에서 자산을 대출(레버리지) 받음으로써 보다 큰 자산을 활용하여 이자농사에 참여할 수 있음</li>
<li>대출 비용이 클 수록 포지션청산 및 비영구적 손실에 노출될 가능성이 높음</li>
<li>개인적으로 이자 농사 금융상품의 모델에서 대여자가 대지주라면 농부는 소작농이라고 부르고 싶고, 소작농의 레버리지를 활용한 고배율 투자가 실패했을 때 그 포지션 청산비용이 다 대여자, 대지주에게 공급될 높은 APY 이자 지급에 활용된다. 물론 소작농이 고배율 레버리지 포지션을 잡 활용하면 큰 돈을 벌 수 있지만, 변동성이 높은 암호화폐 시장에서 돈일 잃는 쪽이 더 많을 것 같고, 인간의 탐욕을 기반으로하는 선물시장과 비슷한 구조라 생각이 듭니다.</li>
</ul>
<h3 id="staker스테이커">Staker(스테이커)</h3>
<ul>
<li>대여자는 자산을 랜딩풀에 예치하면 ibToken을 수령</li>
<li>이 ibToken을 Stacking Vault(금고)에 예치함으로써 이자수익을 더 할 수 있음</li>
<li>이 때 스테이킹에 대한 이자는 거버넌스토큰으로 지급함</li>
<li>일반적으로 Stacking을 하면 최소한의 Lockup 기간이 존재하며, 그 전에 Unstacking하면 패널티를 부과하는 곳도 존재함</li>
<li>DeFi에서 스테이킹을 통한 유동성에 Lock을 걸려고 하는 이유는 뱅크런과 같은 것을 방지하기 위함이며, 일상생활에서 은행 예금의 경우 만기를 채우지 않은 상태에서 해지시 손해가 있는것과 동일한 관점임</li>
</ul>
<h2 id="what-is-yield-farming이자농사">What is Yield Farming(이자농사)</h2>
<p>이자 농사의 정의를 명확하게 정리한 문서는 찾지 못 했습니다. 하지만 여러 문서를 살펴본 결과, 다음과 같이 이자농사를 정의할 수 있을 것 같습니다.</p>
<ul>
<li>첫번째 토큰을 예치하여 유동성을 공급하고, 이 것으로 부터 이자를 얻는 행위도 이자농사라고 할 수 있습니다. 가장 쉽고 가장 안전한 방법입니다. 유동성 공급시 인출할 때 시간적인 제한을 두는 DeFi도 있으므로, 이 번 루나사태와 같은 것이 발생하면, 막대한 손실을 볼 수 있습니다.</li>
<li>일반적인 DeFi에서 토큰쌍을 예치하고, 고수익의 이자를 얻을 수 있는 풀(Pool)을 서비스하는 DeFi가 많이 있습니다. 예를 들면 USDC-ETH와 같이 스테이블코인과 변동성이 높은 토큰을 쌍으로하는 풀입니다. USDC와 예치하는 USDC와 동일한 가치의 ETH를 입금하면 해당 풀에서 제공하는 이자 APR(Annual Percentage Rate)를 얻을 수 있습니다. 각 DeFi에서 제공하는 Pool서비스를 모아서 쉽게 예치할 수 있게 도와주는 서비스를 하는 서비스를 하는 곳도 있습니다. 이러한 풀을 묶어서 보여주는 것을 농장(Farm)이라고 지치하고 있으며 풀은 큰 농장에 있는 다양한 밭이라고 생각하시면 됩니다. 아래 그림은 Alpaca Finance에서 제공하는 농장(Farm) 서비스내 풀(Pool) 화면캡쳐입니다.</li>
</ul>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-06-02-bears-a-survey-on-dex-protocol-leveraged-yield-farming/alpaca_farm01.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">그림.1 Alpaca Finance의 Farm서비스에서 제공하는 풀의 예시</td>
</tr>
</tbody>
</table>
<ul>
<li>그럼 항상 양쪽 토큰을 다 가지고 있어야 이자 수익을 얻을 수 있는 것은 아닙니다. USDC-ETH풀에 돈을 넣을 때 만약에 USDC만 있다면 나의 돈에 해당하는 ETH가 없을 때 바로 ETH 금고에서 대출을 받으면 됩니다. 대출을 받았을 경우 대출이자보다 높은 APR을 달성할 수 있어야 하며, 대출 이자도 경우에 따라 10%정도 될 수 있기 때문에 손해를 볼 수 있다는 생각을 하고 투자해야 합니다.</li>
<li>여기에 또 암호화폐의 변동성이 큰 영향을 주게되는데, 만약에 ETH의 가격이 점점 내려가면 내가 같아야할 ETH의 가격이 싸졌기 때문에(공매도와 유사) 내가 갚아야할 돈이 적어지고 만약에 ETH의 가격이 오르면 내가 갚아야할 돈이 커지기 때문에 반드시 무엇을 예치하고 무슨 코인을 빌릴지 잘 생각해야 합니다. 정말 운이 없이 시장의 방향과 반대로 투자하게 되면 한 푼도 못 남길 수 있습니다.</li>
</ul>
<h2 id="what-is-ibtokeninterest-bearing-token">What is ibToken(interest bearing Token)</h2>
<p>ibToken은 토큰을 예치했을때 받게되는 징표와 같은 것입니다. Interest Bearing (ib)라는 접두사가 붙은 이유는 이자 농사를 하는 사람이 청산당하거나, 대출을 같을 때의 제공하는 이자등이 해당 금고에 누적이되고 그 때 Vault(금고)에 상황에 따라 이자를 포함하는 토큰을 돌려 받기 때문에 붙은 접두사입니다. 현재상태 금고(Vault)의 지분률이라고 보시면 정확합니다.</p>
<p>코든 랜딩풀은 고유의 ibToken을 가지고 있습니다. 만약에 Alpaca의 경우 ibBNB, Kleva의 경우는 ibWEMIX와 같이 랜딩풀에 따라 ibToken을 민팅하게 됩니다.</p>
<p>여기서 DeFi 설계자들은 고민하게 됩니다. 랜딩풀에 적절한 수준의 유동성을 공급해야하는데, 사람들이 돈을 묶어 둘 필요가 있습니다. 그래서 ibToken을 스테이킹할 수 있게 하고, 스테이킹하면 ibToken에 대응하는 거버넌스 토큰을 지급하게 됩니다. 만약에 이 거버넌스코튼의 가격이 올라가면 대여자는 추가적인 수익을 얻을 수 있고, 장시간 돈을 맡기게되며 DeFi는 안정적인 유동성을 확보할 수 있습니다. 다만 스테이킹 서비스의 경우 최소 예치기간을 두는 곳이 많고, 해치기간 전에 스테이킹을 해제 못 하게 하거나 하더라고 패널티를 부과하는 곳도 있으니 주의가 필요합니다.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> function _deposit(uint256 amountToken) internal {
uint256 total = totalToken().sub(amountToken);
uint256 share = total == 0 ? amountToken : amountToken.mul(totalSupply()).div(total);
_mint(msg.sender, share);
require(totalSupply() > 1e17, "no tiny shares");
}
</code></pre></div></div>
<h2 id="what-is-positionliqudiation">What is position(Liqudiation)</h2>
<p>이제 Leveraged Yield Farming에 들어가기전에 Position에 대해서 알아보겠습니다. 포지션은 시장을 바라보는 나의 시각이라고 보시면 되고 long position은 앞으로 투자 상품의 가격이 상승할꺼라는 것이고 short position은 가격이 하락할 것이라는 관점입니다. 아래 그림은 바이낸스 비트코인 선물시장이며 비트코인이 상승할 것이라면 long 포지션을 사고, 가격이 하락할 것이라면 short 포지션을 사면 됩니다. 포지션 거래와 꼭 함께 있는 것이 레버리지(leverage)입니다.</p>
<p>만약에 아래 그림에서 leverage를 10배를 하게되었을 때 내가 만약에 long포지션을 샀고, 비트코인이 10%가 올랐다면 100% 수익을 올릴수 있습니다. 만약 반대의 경우가 발생하면 -100%가 되는 것이고 이 때 청산(liqudiation)이 발생하게 됩니다. 일종의 홀짝 게임이라고 생각하시면 됩니다. 청산이되면 내가 포지션 구입 비용에 들어갔던 돈은 다른쪽(short 포지션 매수자) 수익과 바이낸스 거래 수수료로 사용됩니다.</p>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-06-02-bears-a-survey-on-dex-protocol-leveraged-yield-farming/position.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">그림.2 Binance Future 거래 화면</td>
</tr>
</tbody>
</table>
<p>Leveraged Yield Framing에서는 다들 예상하셨다시피 leveraged를 사용할 수 있으며, 이때 중요한게 이자농사 풀에 투입될 토큰중 어느 토큰을 빌릴지 잘 선택하는게 중요합니다.</p>
<h2 id="what-is-leveraged-yield-farming레버리지-이자농사">What is Leveraged Yield Farming(레버리지 이자농사)</h2>
<p>내가 가진 담보토큰 보다 훨씬 큰돈을 가지고 이자농사를 하면 훨씬 큰 이자를 벌 수 있다는 돈에 대한 인간의 탐욕을 기반으로하는 서비스입니다. 더욱이 변동성이 큰 암호화폐 시장의 특징과 적절한 대여 토콘의 선택은 이익을 극대화할 수도 있고, 최악의 손실을 볼 수 도 있습니다.</p>
<p>프랑슘(Francium)이라고 솔라나 네트워크에서 Alpaca와 비슷한 서비스를 하는 곳입니다. 이 프랑슘에서는 Leveraged Yield Farming이전에 다양한 시뮬레이션을 할 수 있게해주고, 적절한 레버리지 및 대출 토큰 선택에 도움주고 있습니다. 레버리지 이자 농사를 할 때 가급적 한 쪽 토큰을 스테이블 토큰으로해서 변동성을 조금이라도 낮추는게 좋습니다. 변동성 높은 토큰 두개를 하는게 수익을 극대화할 수 있으나 반대의 경우도 생각해야합니다.</p>
<p>현재 22년 6월과 같이 베어(Bear) 마켓인 경우는 아무래도 가격이 내려갈 가능성이 높은 Solana를 대출받아서 이자농사를 하는게 나중에 갚아야할 솔라나를 생각하면 좋은 선택이 될 수 있습니다. 그림 3에서와 같이 솔라나 가격이 상승하면 청산될 수 있습니다.</p>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-06-02-bears-a-survey-on-dex-protocol-leveraged-yield-farming/francium01.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">그림.3 Francium Leverage Farming서비스 시뮬레이터에서 USDC를 공급하고 Solana를 빌렸을 경우</td>
</tr>
</tbody>
</table>
<p>그러나 솔라나가 지금 저점이라고 생각하고 솔라나를 공급하고 USDC를 대출받을 수 있습니다. 나중에 솔라나 가격이 올라가면 적은 솔나라로 USDC를 값을 수 있으니 이자 플러스 훨씬 이득이 됩니다. 그러나 솔라나 가격이 더 떨어진다면 청산되게 됩니다.</p>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-06-02-bears-a-survey-on-dex-protocol-leveraged-yield-farming/francium02.png" alt="Image Alt 텍스트" /></td>
</tr>
<tr>
<td>그림.4 Francium Leverage Farming서비스 시뮬레이터에서 Solana를 공급하고 USDC를 빌렸을 경우</td>
</tr>
</tbody>
</table>
<p>즉 Leveraged Yield Farming의 경우 시장의 상태에 따라 받을 수 있는 이자를 극대화할 수 있으며, 실제 풀(Pool)에서 표시하고 있는 APR보다 훨씬 많은 이자 수익을 확보할 수 있습니다.</p>
<p>Kleva Protocol에서 예로 레버리지 이자 농사를 설명해보겠습니다.</p>
<p>지금 현재 2022년 6월6일 WEMIX의 경우 $ 3.694이고 Klaytn의 경우 $ 0.4069 대략 계산을 쉽게 하기 위해서 교환비가 1:10 정도 된다고 가정하겠습니다.</p>
<p>투자가 홍길동씨는 100 WEMIX를 가지고 있습니다. 100WEMIX를 가만히 거래소에 두기 보다, 장기적으로 BEAR 마킷이고 WEMIX 토큰을 매도할 생각이 없기 때문에 이자농사를 할 계획인데 단기적으로 이익을 극대화하기 위해 레버리지를 사용할 생각을 합니다.</p>
<ul>
<li>홍길동씨의 자산은 100 WEMIX입니다. 최대 이익을 위해 레버리지 계수를 3을 선택합니다.</li>
<li>이제 홍길동씨의 자산은 300(100 * 3) WEMIX입니다. 이 300 WEMIX를 자산을 형성하기 위해 200 WEMIX를 대여풀에서 빌려야 합니다.</li>
<li>이 때 선택을 할 수 있습니다. WEMIX가 Klaytn 상승률보다 높아서 나중에 교환비가 1:100, 1:1000이 될 것이라고 생각하면 Klaytn을 대출하는게 훨씬 이득입니다. 만약에 반대라면 지금 WEMIX를 Klaytn으로 바꾸고, WEMIX를 대출받는게 더 좋습니다.</li>
<li>여기서는 WEMIX가 더 상승한다고 홍길동씨는 판단했기 때문에 200 WEMIX에 대응하는 2000 Klaytn을 빌렸습니다.</li>
<li>풀에 넣을 때에는 1:1 비율로 집어 넣어야 하기 때문에 500 Klaytn을 50 WEMIX로 바꾸고 150 WEMIX, 1500 Klaytn을 풀에 집어 넣었습니다.</li>
<li>한 달뒤 이자풀에서 돈을 인출합니다. 이 때 교환비가 1:100이 되었습니다. 일단 1500 klaytn에서 부족한 500 Klaytn에 대한 5 WEMIX만 교환해서 2000 Klaytn과 이자를 갚고 풀 이자와 추가적인 가격변동에 의한 WEMIX 수익을 얻게 됩니다.</li>
</ul>
<p>위의 경우는 정말 운이 좋은 경우라 볼 수 있고, 보통은 암호화폐 두개를 페어로 하는 것은 고려사항이 많아서 너무 위험한 것 같습니다. 개인적으로는 스테이블코인과 암호화폐 쌍이 보다 안전해 보입니다.</p>
<h1 id="alpaca-finance">Alpaca Finance</h1>
<h2 id="project-configuration">Project Configuration</h2>
<h3 id="types-of-nodes">Types of nodes</h3>
<ul>
<li>Archive nodes : Has data since genesis block.</li>
<li>Full nodes : Receive copies of transactions. Has the current state of the blockchain.</li>
<li>Light nodes : Doesn’t have the entirety of the current blockchain state and depends on a full node, useful for low memory and computational devices.</li>
<li>Miner nodes : Miner nodes verify transactions and add them to the blocks. They then mine those blocks and secure the blockchain with proof of work.</li>
</ul>
<h3 id="yarn-compile-and-yarn">Yarn Compile and Yarn</h3>
<p>Alpaca Finance의 프로젝트 설명을 보면 yarn을 실행하라고 되어 있습니다. 실제로 sudo apt install yarn으로 yarn을 설치하고 실행하면 에러가 발생할 수 있습이다 그럴 경우 아래의 명령어로 yarn을 일단 재설치해보시기 바랍니다.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt remove cmdtest
sudo apt remove yarn
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt update
sudo apt install yarn
</code></pre></div></div>
<p>yarn과 npm install도 궁합이 안 좋은 것 같습니다. yarn을 재설치하고 난 뒤에 <span style="background-color:#fff5b1">“yarn error An unexpected error occurred: “Commit hash required”.</span> 에러가 발생한다면 git clone으로 새로 alpaca finance 프로젝트를 다운로드 받아야 합니다.</p>
<p>yarn을 실행하다보면 아래와 같은 에러가 출력이 되는 경우가 있습니다. 이 에러를 해결하기 위해 많은 시간을 투자하였는데, Alpaca 프로젝트 관련자로 추정되는 사람이 한 답변 한 개를 찾을 수 있었습니다. <span style="background-color:#fff5b1">해결 방법은 yarn compile을 실행하고 다시 yarn을 실행</span>하라는 것이였습니다.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ tsc -p tsconfig.cjs.json
error TS18003: No inputs were found in config file '/mnt/d/Playground/BEARS/case/bsc-alpaca-contract/tsconfig.cjs.json'. Specified 'include' paths were '["./typechain/**/*.ts"]' and 'exclude' paths were '["node_modules","build","cache","artifacts"]'.
</code></pre></div></div>
<p>yarn compile을 하면 또 수많은 에러가 생성됩니다. 이 쯤되면 로컬 환경 구축을 통한 분석환경을 구축을 통한 분석을 해당 프로젝트 팀이 의도적으로 방해하고 있다라는 느낌이 듭니다. yarn compile 에러를 해결해야 하는데, WSL 환경이라서 생기는 문제일 수도 있을 것 같습니다.</p>
<h3 id="hardhat-installation">Hardhat Installation</h3>
<p>만약에 Hardhat이 설치되어 있지 않으면 Hardhat이 없다는 에러가 출력이 될 것 입니다. Hardhat을 설치하는 방법은 아래와 같으며 Alpaca 프로젝트의 경우 NodeJS 패키지 매니저로 yarn을 설치하는 것이 좋습니다.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm install --save-dev hardhat
npm install --save-dev @nomiclabs/hardhat-ethers ethers chai @nomiclabs/hardhat-waffle ethereum-waffle
yarn add hardhat
yarn add @nomiclabs/hardhat-ethers ethers chai @nomiclabs/hardhat-waffle ethereum-waffle
</code></pre></div></div>
<p>yarn으로 Hardhat 설치시 아래와 같은 에러가 발생한다면 <span style="background-color:#fff5b1">nvm install –lts</span> 명령을 실행 후 다시 설치시도하면 에러를 해결할 수 있습니다.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>"error hardhat@2.9.8: The engine "node" is incompatible with this module. Expected version "^12.0.0 || ^14.0.0 || ^16.0.0". Got "17.0.1"
</code></pre></div></div>
<h3 id="install-package-from-local-folder">Install package from local folder</h3>
<p>Alpaca Finance의 BSC쪽 contract 분석환경을 구축하면서, contract 컴파일이 실패, 이것에 대한 원인 분석 및 디버깅을 위해 Openzeplin에서 개발한 @openzeplin/hardhat-upgrades 모듈에 콘솔 출력을 추가할 필요가 생겼습니다. 이를 위해 처음에는 node_model 폴더에 @openzeplin/hardhat-upgrades 폴더에 소스코드를 수정했지만 반영이 안되었습니다. 이것을 해결하기위해 구글 검색결과 대략 2가지 정도의 해결 방법이 있었습니다. 핵심은 소스수정후 재컴파일이 필요하다는 것이고 이것을 위해 github 프로젝트의 경우 fork를 한 후, 해당 프로젝트 소스코드 변조후 http를 통한 패키지 재설치이고 다른 한 방법은 fork한 프로젝트를 로컬에서 수정 및 컴파일하여 이상없는 것을 확인 후 로컬 폴더로 부터 패키지 설치 명령을 실행하는 방법이다. 로컬 폴더 설치의 경우 link를 활용한 심볼 링크로 설치할 수도 있고, add 옵션으로 실제 파일 복사 컴파일 설치 방법이 있다.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yarn add --dev --force @openzeppelin/hardhat-upgrades@https://github.com/bears-team/openzeppelin-upgrades.git
yarn add --dev --force file:../openzeppelin-upgrades/packages/plugin-hardhat/
</code></pre></div></div>
<h3 id="hardhat-network-configurationfork-bsc-mainnet">Hardhat Network Configuration(fork BSC mainnet)</h3>
<p>Alpaca finance github 프로젝트를 다운로드하면 DotEnv파일 예제가 다음과 같이 있습니다. Metamask에서 계정을 두개 만들고 각각의 PrivateKey를 Export해서 PRIVATE_KEY와 QA_PRIVATE_KEY를 설정해 줍니다. BSC_MAINET_ARCHIVE_RPC의 경우는 <a href="rcp.info">rpc.info</a> 사이트에서 BSC Mainent주소를 입력하였습니다.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Testnet Env
BSC_TESTNET_PRIVATE_KEY="xxx"
ETH_TESTNET_PRIVATE_KEY="xxx"
FANTOM_TESTNET_PRIVATE_KEY="xxx"
ETH_KOVAN_RPC="xxx"
# Mainnet Env
BSC_MAINNET_PRIVATE_KEY="xxx"
ETH_MAINNET_PRIVATE_KEY="xxx"
FANTOM_MAINNET_PRIVATE_KEY="xxx"
BSC_MAINNET_ARCHIVE_RPC="https://bsc-dataseed.binance.org/"
BSC_MAINNET_RPC="xxx"
ETH_MAINNET_RPC="xxx"
FTM_MAINNET_RPC="xxx"
FORK_RPC="http://127.0.0.1:8545"
DEPLOYER_ADDRESS="xxx"
TYPECHAIN_TARGET="ethers-v5"
QA_PRIVATE_KEY="xxx"
</code></pre></div></div>
<p>Hardhat의 경우 localhost RPC의 chainid는 31337이라고 합니다. Hardhat에서 mainnet을 포크해서 로컬 RPC를 구성하는 명령은 “npx hardhat node –fork https://bac-dataseed.binance.org/ –no-deploy” 을 입력하면되고, 친절하게 alpaca 프로젝트는 스크립트(run_mainnet_fork.sh)를 지원하고 있습니다. 메인넷 포크를 실행한 후 metamask와의 연동은 그림과 같이 네트워크를 추가함으로써 가능합니다.</p>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-06-02-bears-a-survey-on-dex-protocol-leveraged-yield-farming/mm01.png" alt="Image Alt 텍스트" /></td>
</tr>
<tr>
<td>그림.6 BSC네트쿼크를 포크후 메타마스크에 포크된 네트워크를 추가할때의 설정</td>
</tr>
</tbody>
</table>
<p>네트워크도 연결되었으니, 이제 테스트를 위한 계정 설정으로 살펴보겠습니다.
일단 스마트컨트렉트를 트리거(Trigger)할려면, 토큰이 많은 계정이 필요합니다. 메인넷을 포크하면 Hardhat에서 토큰이 아주 많은 계정들을 제공해줍니다. 아래이 그림에서와 같이 Hardhat이 제공하는 계정을 “Private Key”를 활용해서 메타마스크에 추가하였고, 해당 계정에서 다른 계정으로 토큰을 전송하였습니다. 계정을 추가는 메타마스크의 “Import Account” 메뉴로 할 수 있습니다.</p>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-06-02-bears-a-survey-on-dex-protocol-leveraged-yield-farming/hh05.png" alt="Image Alt 텍스트" /></td>
</tr>
<tr>
<td>그림.7 BSC 메인넷 포크할 때 제공되는 계정을 메타마스크에 추가하고, 다른 계정으로 토큰 전송</td>
</tr>
</tbody>
</table>
<p>이제 우리는 BSC 메인넷도 BNB토큰을 가지고 있는 계정도 가짐으로써, 분석을 위한 기본적인 준비는 된 것 같습니다.</p>
<h2 id="the-overview-of-alpaca-finance">The Overview of Alpaca Finance</h2>
<p>Alpaca Finance의 경우 FairLaunch 서비스라는 것을 강조하고 있습니다. 실제 FairLaunch관련 컨트렉트도 github에서 확인할 수 있습니다. 그 개념을 미뤄 짐작해 보면 다음과 같습니다.</p>
<p>FairLaunch의 반대 경우를 생각해보면 되는데 바로 ICO 또는 PreSale을 생각하면 됩니다. 일반적으로 블록체인 프로젝트를 시작할 때 자금을 모으기 위해 ICO 또는 토큰 PreSale을 합니다. 소스의 몇몇이 초기 저렴하게 토큰을 구매해서 나중에 가격 상승의 혜택을 보게 됩니다. Alpaca Finance의 경우 이러한 ICO 또는 PreSale을 하지 않고 누구나 Lending 풀에 토큰을 예치하고 해당 ibToken을 스테이킹 함으로써 Alpaca 토큰을 가질 수 있습니다. 소수의 인원의 섬점 효과가 없이 누구나 공평하게 Alpaca 커너넌스 토큰을 소요할 수 있습니다. 이러한 특징을 FairLaunch 서비스로 표현하고 있습니다. <a href="https://github.com/bears-team/bsc-alpaca-contract/blob/c6fafa2a9f32604464ed3a5116384a476800e45c/solidity/contracts/6/token/FairLaunch.sol#L47">FairLaunch 소스코드</a>를 보면 Alpaca토큰 동작과 관련있음을 확인할 수 있습니다.</p>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-06-02-bears-a-survey-on-dex-protocol-leveraged-yield-farming/alpaca_farm02.png" alt="Image Alt 텍스트" /></td>
</tr>
<tr>
<td>그림.8 Alpaca Finance Leveraged Yield Farming 중심의 서비스 관계도</td>
</tr>
</tbody>
</table>
<ul>
<li>Alice : 대여자(Lender), BNB토큰을 Lending Pool, 코드상 Vault에 예치하고 대응하는 ibToken인 ibBNB를 받게 된다. 관련코드는 <a href="https://github.com/alpaca-finance/bsc-alpaca-contract/blob/c6fafa2a9f32604464ed3a5116384a476800e45c/solidity/contracts/6/protocol/Vault.sol#L207">여기</a>를 보면됩니다. 실제 코드를 보면 BNB가 아니라 WBNB(Wrapped BNB)라는 것을 확인할 수 있는데, 이것에 대해서는 좀더 조사를해서 내용을 보완하겠습니다. 여기서 우리가 알아야할 것은 최초의 외부 지갑에서 돈이 흘러들어가는 것을 과정을 분석하기 위해서 Vault.sol 파일을 분석해야한다는 사실입니다.</li>
</ul>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>// Solidity
address vaultContractAddress = '0xd7D069493685A581d27824Fc46EdA46B7EfC0063'; // BNB Vault
if (msg.value == 0) { // if no native token is sent, then it is a ERC20/BEP20 token deposit
IERC20(tokenAddess).safeTransferFrom(address(msg.sender), address(this), amountToken);
}
// Allow transfer to vault
SafeToken.safeApprove(tokenAddess, vaultContractAddress, amountToken);
// Deposit to vault
IVault(vaultContractAddress).deposit(amountToken);
</code></pre></div></div>
<p>예치시 받는 ibToken의 가치는 아래와 코드의 계산과정을 거쳐서 결정됩니다.
Vault는 ERC20 토큰 컨트렉트를 상속하기 때문에 totalSupply() 함수는 <a href="https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20-totalSupply--">Openzeppelin 사이트</a>에서 확인 가능하다. totalToken()은 Vault내 BNB토큰의 전체 개수이고 totalSupply()는 전체 발행된 ibToken의 개수입니다.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>// Solidity
address vaultContractAddress = '0xd7D069493685A581d27824Fc46EdA46B7EfC0063'; // BNB Vault
IVault vault = IVault(vaultContractAddress);
uint256 ibTokenAmount = ...;
uint256 ibTokenPrice = vault.totalToken()).div(vault.totalSupply();
uint256 underlyingTokenAmount = ibTokenAmount.mul(ibTokenPrice);
</code></pre></div></div>
<ul>
<li>Bob : 이자 농사 농부(Farmer), 그림.6에서는 BTC/BNB 페어에서 이자농사를 하기를 원하며, BTC를 예치하고, BNB를 빌리는 형태로 레버리지 이자 농사를 실시, 이 때 Bob의 전제는 BTC가격이 오를 것을 예상하고 농사를 하는 것이며, 앞에서 설명한 Long(롱) 포지션에 해당합니다. 소스코드에서도 이 동작을 확인하고 싶어서 찾고 있으며, 아직 확인하지 못 했습니다.</li>
<li>Erin : 청산 봇(Liquidator bot), Bob과 같이 레버리지 이자 농사를 하는 경우 담보물의 가치 변동에 따른 청산이 발생할 수 있는데, 이 작업을 돕는 봇이며 청산시 보상으로 \(5%\) 를 수수료를 챙기며, 이 수수료로 Alpaca 거버넌스 코는 Alpaca를 소각하는데 활용, Alpaca 토큰의 가격 상승의 동력을 만들어냅니다. 변동성이 강할때 청산이 많이 발생함으로 그 때 Alpaca Finance는 많은 수익 창출이 가능합니다. 코드상 확인이 필요합니다.</li>
<li>Carlos : 보상 헌팅 봇(Bounty Hunter Bot), 각각의 풀에 보상들이 자동으로 재투자되는지 확인하고 감시하는 역할을 담당하는 봇이라고 하는데, 정확하게 확인이 필요할 것 같습니다. 모든 이자 농부들이게 복리 이자를 자동 지급하는 역할을 한다고 하며, 이 역할을 수행함으로서 보상의 약 \(3%\) 의 수수료를 챙긴다고 되어 있습니다. 이 수수료를 Alpaca 개발팀에서 가져가게 됩니다.</li>
</ul>
<p>위 Alpaca Finance내 참여자들의 구성을 볼때, 우리가 집중해서 분석해야할 코드는 Alice와 Bob인 것을 확인할 수 있습니다. 결국 Vault에 큰 돈이될 토큰이 있으므로 Alpaca 서비스에서 돈을 빼낸다면 Vault에 집중해야할 것으로 보이고, Yield Farming쪽에서 돈을 빼낼 방법을 고민할려면 연동된 서비스 코드까지 광범위하게 분석해야할 것입니다.</p>
<p>Alpaca Finance 서비스에서는 일반 시중은행에서 다양한 투자회사의 금융상품을 판매하는 것 처럼 다양한 연동서비스의 상품을 취급하고 있습니다. Alpaca Finance에서 제공하는 상품은 다음과 같습니다.</p>
<ul>
<li>PancakeSwap Farms(BNB)</li>
<li>Mdex Farms(BNB)</li>
<li>Biswap Farms(BNB)</li>
<li>SpookySwap Farms(Fantom)</li>
<li>WaultSwap Farms(Deprecated)</li>
</ul>
<p>Alpaca 서비스의 contract 소스코드에서도 위 서비스를 확인할 수 있습니다.</p>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-06-02-bears-a-survey-on-dex-protocol-leveraged-yield-farming/alpaca_project01.png" alt="Image Alt 텍스트" /></td>
</tr>
<tr>
<td>그림.9 Alpaca Finance 프로젝트 폴더, Alpaca Finance의 경우 외부 서비스의 풀을 그대로 활용하고 있음을 알 수 있다.</td>
</tr>
</tbody>
</table>
<p>또한 <a href="https://docs.alpacafinance.org/leveraged-yield-farming/pool-specific-parameters-1/pool-specific-parameters#pancakeswap-tusd-pairs-1">이곳 문서</a>를 확인하면, PancakeSwap 풀중에서 Alpaca Finance에서 지원하는 서비스별 Contract주소를 확인할 수 있습니다.</p>
<p>Alpaca 서비스의 경우 자신들이 서비스하는 <a href="https://github.com/alpaca-finance/bsc-alpaca-contract/blob/c6fafa2a9f32604464ed3a5116384a476800e45c/.mainnet.json#L709">토큰쌍 풀의 컨트렉트(Contract)주소</a>를 json형태로 유지관리 하고 있는 것을 확인할 수 있습니다.</p>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-06-02-bears-a-survey-on-dex-protocol-leveraged-yield-farming/alpaca_pancake01.jpg" alt="Image Alt 텍스트" /></td>
</tr>
<tr>
<td>그림.10 Alpaca Finance와 PancakeSwap간의 Tokenflow</td>
</tr>
</tbody>
</table>
<p>Alpaca 서비스에 대한 상세한 소스코드 감사기반 분석은 Tokenflow 분석 포스트에서 기술하도록 하겠습니다.</p>
<h1 id="the-difference-between-alpha-alpaca-finance-and-kleva">The Difference between Alpha, Alpaca Finance and Kleva</h1>
<p>본인 자체 풀보다 다양한 DeFi와 연동하여 풀들을 사용자들이 여러 DeFi이 돌아다니지 않고 편하게 이자서비스를 할 수 있도록 하는 것이 핵심이고 자기들 대여풀에서 돈을 인출해서 해당 토큰 쌍 APR를 활용할 수 있도록 하여, 중간에 수수료를 챙기는 구조의 금융 서비스라고 생각하면 될 것 같습니다.</p>
<p>현재까지의 살펴본 결과로는 개인적으로 이 3걔의 서비스 Alpha, Alpaca, Kleva는 거의 동일한 서비스를 하는 것으로 판단되며, Kleva의 경우 Alpaca와 너무 비슷해서 동일한 코드에서 출발한 것으로 판단될 정도입니다.</p>
<h1 id="conclusion">Conclusion</h1>
<p>이 번 글에서는 DeFi Protocol중 Leveraged Yield Farming 서비스를 살펴보았습니다. 랜딩풀(Vault)라는 것을 제외하면 다른 토큰 쌍풀(Pool)의 경우는 다른 Swap서비스를 끌어다 서비스를 제공하는 구조였으며, 고배율 레버리지 기능을 제공 암호화폐시장에서의 변동성을 기반으로 이자 농사꾼들이 청산 및 레버리지 사용에 대한 이자농사를 기반으로 돈을 버는 서비스임을 확인할 수 있었습니다.</p>
<h1 id="references">References</h1>
<ul>
<li><a href="https://medium.com/@versofinance/understanding-leveraged-yield-farming-72b5f8609a0a">https://medium.com/@versofinance/understanding-leveraged-yield-farming-72b5f8609a0a</a></li>
<li><a href="https://alphafinancelab.gitbook.io/alpha-homora-vbsc/what-is-leveraged-yield-farming">https://alphafinancelab.gitbook.io/alpha-homora-vbsc/what-is-leveraged-yield-farming</a></li>
<li><a href="https://docs.alpacafinance.org/help-center/alpaca-academy/lesson-3-liquidation-risk-in-leveraged-yield-farming">https://docs.alpacafinance.org/help-center/alpaca-academy/lesson-3-liquidation-risk-in-leveraged-yield-farming</a></li>
<li><a href="https://alphaventuredao.io/">https://alphaventuredao.io/</a></li>
<li><a href="https://docs.kleva.io/v/copy-of/undefined-1/undefined-3/3">https://docs.kleva.io/v/copy-of/undefined-1/undefined-3/3</a></li>
<li><a href="https://medium.com/alpaca-finance/introducing-alpaca-finance-d6e858896efd">https://medium.com/alpaca-finance/introducing-alpaca-finance-d6e858896efd</a></li>
<li><a href="https://thedefiant.io/leveraged-yield-farming/">https://thedefiant.io/leveraged-yield-farming/</a></li>
<li><a href="https://francium.io/app/calculator">https://francium.io/app/calculator</a></li>
<li><a href="https://github.com/alpaca-finance/bsc-alpaca-contract/tree/main/solidity/contracts">https://github.com/alpaca-finance/bsc-alpaca-contract/tree/main/solidity/contracts</a></li>
<li><a href="https://medium.com/immunefi/belt-finance-logic-error-bug-fix-postmortem-39308a158291">https://medium.com/immunefi/belt-finance-logic-error-bug-fix-postmortem-39308a158291</a></li>
<li><a href="rpc.info">rpc.info</a></li>
</ul>PandaDeFi 취약점 연구를 위한 DeFi 프로토콜 소개 시리즈, 그 첫번째 Leveraged Yield Farming에 대한 글입니다.The Introduction of Ethereum vulnerability Part12022-05-28T22:00:00+00:002022-05-28T22:00:00+00:00https://bears-team.github.io//security/smart%20contract/bears%20team/bears-introduction-legacy-vulnerabilities-part1<h1 id="executive-summary">Executive Summary</h1>
<p>이 자료는 BEARS 스터디 그룹에서 초기에 세미나 했던 Ethereum Solidity기반 취약점을 유형별로 정리한 자료입니다. 슬라이드와 해당 슬라이드에 대한 설명으로 구성할 계획이며, 슬라이드에 대한 설명은 틈틈히 작성하도록 하겠습니다.</p>
<h1 id="presentation">Presentation</h1>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide1.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide2.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide3.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide4.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide5.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide6.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide7.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide8.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide9.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide10.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide11.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide12.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide13.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide14.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide15.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide16.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide17.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide18.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide19.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide20.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide21.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide22.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide23.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide24.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide25.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide26.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide27.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide28.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide29.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide30.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide31.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide32.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide33.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide34.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide35.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide36.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide38.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide39.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide40.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide41.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide42.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide43.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide44.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide45.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide46.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide47.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part1/Slide48.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<h1 id="references">References</h1>
<ul>
<li><a href="https://blog.sigmaprime.io/solidity-security.html">https://blog.sigmaprime.io/solidity-security.html</a></li>
<li><a href="https://dasp.co/">https://dasp.co/</a></li>
<li><a href="https://consensys.github.io/smart-contract-best-practices/known_attacks/#reentrancy">https://consensys.github.io/smart-contract-best-practices/known_attacks/#reentrancy</a></li>
<li><a href="https://consensys.github.io/smart-contract-best-practices/known_attacks/#reentrancy">https://consensys.github.io/smart-contract-best-practices/known_attacks/#reentrancy</a></li>
<li><a href="https://docs.soliditylang.org/en/latest/contracts.html?highlight=fallback#fallback-function">https://docs.soliditylang.org/en/latest/contracts.html?highlight=fallback#fallback-function</a></li>
<li><a href="https://docs.soliditylang.org/en/latest/contracts.html?highlight=fallback#fallback-function">https://docs.soliditylang.org/en/latest/contracts.html?highlight=fallback#fallback-function</a></li>
<li><a href="https://docs.microsoft.com/en-us/azure/security/develop/threat-modeling-tool-threats">https://docs.microsoft.com/en-us/azure/security/develop/threat-modeling-tool-threats</a></li>
<li><a href="https://docs.microsoft.com/en-us/windows-hardware/drivers/driversecurity/threat-modeling-for-drivers#the-dread-approach-to-threat-assessment">https://docs.microsoft.com/en-us/windows-hardware/drivers/driversecurity/threat-modeling-for-drivers#the-dread-approach-to-threat-assessment</a></li>
<li><a href="https://mixbytes.io/blog/collisions-solidity-storage-layouts">https://mixbytes.io/blog/collisions-solidity-storage-layouts</a></li>
<li><a href="https://medium.com/coinmonks/ethernaut-lvl-6-walkthrough-how-to-abuse-the-delicate-delegatecall-466b26c429e4">https://medium.com/coinmonks/ethernaut-lvl-6-walkthrough-how-to-abuse-the-delicate-delegatecall-466b26c429e4</a></li>
<li><a href="s://github.com/randao/randao">s://github.com/randao/randao</a></li>
<li><a href="https://swende.se/blog/Breaking_the_house.html">https://swende.se/blog/Breaking_the_house.html</a></li>
<li><a href="https://blog.positive.com/zeronights-ico-hacking-contest-writeup-63afb996f1e3">https://blog.positive.com/zeronights-ico-hacking-contest-writeup-63afb996f1e3</a></li>
<li><a href="https://blog.positive.com/predicting-random-numbers-in-ethereum-smart-contracts-e5358c6b8620">https://blog.positive.com/predicting-random-numbers-in-ethereum-smart-contracts-e5358c6b8620</a></li>
<li><a href="https://cryptomarketpool.com/front-running-a-solidity-smart-contract/">https://cryptomarketpool.com/front-running-a-solidity-smart-contract/</a></li>
<li><a href="https://medium.com/swlh/exploring-commit-reveal-schemes-on-ethereum-c4ff5a777db8">https://medium.com/swlh/exploring-commit-reveal-schemes-on-ethereum-c4ff5a777db8</a></li>
<li><a href="https://gus-tavo-guim.medium.com/reentrancy-attack-on-smart-contracts-how-to-identify-the-exploitable-and-an-example-of-an-attack-4470a2d8dfe4">https://gus-tavo-guim.medium.com/reentrancy-attack-on-smart-contracts-how-to-identify-the-exploitable-and-an-example-of-an-attack-4470a2d8dfe4</a></li>
<li><a href="tps://github.com/sraj50/unexpected-ether">tps://github.com/sraj50/unexpected-ether</a></li>
<li><a href="s://www.bookstack.cn/read/ethereumbook-en/spilt.5.c2a6b48ca6e1e33c.md">s://www.bookstack.cn/read/ethereumbook-en/spilt.5.c2a6b48ca6e1e33c.md</a></li>
<li><a href="https://medium.com/loom-network/how-to-secure-your-smart-contracts-6-solidity-vulnerabilities-and-how-to-avoid-them-part-1-c33048d4d17d">https://medium.com/loom-network/how-to-secure-your-smart-contracts-6-solidity-vulnerabilities-and-how-to-avoid-them-part-1-c33048d4d17d</a></li>
<li><a href="https://randomoracle.wordpress.com/2018/04/27/ethereum-solidity-and-integer-overflows-programming-blockchains-like-1970/">https://randomoracle.wordpress.com/2018/04/27/ethereum-solidity-and-integer-overflows-programming-blockchains-like-1970/</a></li>
</ul>Panda이더리움 네트워크에서 과거에 주로 발생했던 취약점 유형을 정리한 발표자료입니다.The Introduction of Ethereum vulnerability Part22022-05-28T22:00:00+00:002022-05-28T22:00:00+00:00https://bears-team.github.io//security/smart%20contract/bears%20team/bears-introduction-legacy-vulnerabilities-part2<h1 id="executive-summary">Executive Summary</h1>
<p>이 자료는 BEARS 스터디 그룹에서 Grizzly님이 초기에 세미나 했던 Ethereum Solidity기반 취약점을 유형별로 정리한 자료입니다. 슬라이드와 해당 슬라이드에 대한 설명으로 구성할 계획이며, 슬라이드에 대한 설명은 틈틈히 작성하도록 하겠습니다.</p>
<h1 id="presentation">Presentation</h1>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part2/Slide1.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part2/Slide2.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part2/Slide3.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part2/Slide4.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part2/Slide5.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part2/Slide6.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part2/Slide7.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part2/Slide8.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part2/Slide9.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part2/Slide10.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part2/Slide11.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part2/Slide12.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part2/Slide13.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part2/Slide14.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part2/Slide15.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part2/Slide16.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part2/Slide17.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part2/Slide18.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part2/Slide19.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part2/Slide20.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part2/Slide21.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part2/Slide22.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part2/Slide23.PNG" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<!--
| ![Image Alt 텍스트](/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part2/Slide24.PNG) |
-->Grizzly이더리움 네트워크에서 과거에 주로 발생했던 취약점 유형을 정리한 발표자료입니다.The Introduction of Ethereum vulnerability Part32022-05-28T22:00:00+00:002022-05-28T22:00:00+00:00https://bears-team.github.io//security/smart%20contract/bears%20team/polygon/bears-introduction-legacy-vulnerabilities-part3<h1 id="executive-summary">Executive Summary</h1>
<p>이 자료는 BEARS 스터디 그룹에서 IceBear님이 초기에 세미나 했던 Ethereum Solidity기반 취약점을 유형별로 정리한 자료입니다. 슬라이드와 해당 슬라이드에 대한 설명으로 구성할 계획이며, 슬라이드에 대한 설명은 틈틈히 작성하도록 하겠습니다.</p>
<h1 id="presentation">Presentation</h1>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure1.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure2.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure3.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure4.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure5.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure6.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure7.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure8.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure9.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure10.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure11.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure12.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure13.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure14.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure15.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure16.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure17.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure18.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure19.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure20.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure21.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure22.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure23.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure24.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure25.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure26.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure27.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure28.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure29.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure30.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><img src="/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure31.png" alt="Image Alt 텍스트" /></td>
</tr>
</tbody>
</table>
<!--
| ![Image Alt 텍스트](/assets/images_post/2022-05-24-bears-introduction-legacy-vulnerabilities-part3/figure32.png) |
-->
<h1 id="references">References</h1>
<ul>
<li><a href="https://blog.sigmaprime.io/solidity-security.html">https://blog.sigmaprime.io/solidity-security.html</a></li>
<li><a href="https://docs.soliditylang.org/en/v0.8.9/">https://docs.soliditylang.org/en/v0.8.9/</a></li>
<li><a href="https://ethereum.org/en/developers/docs/evm/">https://ethereum.org/en/developers/docs/evm/</a></li>
<li><a href="https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf">https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf</a></li>
<li><a href="https://medium.com/immunefi/polygon-double-spend-bug-fix-postmortem-2m-bounty-5a1db09db7f1">https://medium.com/immunefi/polygon-double-spend-bug-fix-postmortem-2m-bounty-5a1db09db7f1</a></li>
<li><a href="https://gerhard-wagner.medium.com/double-spending-bug-in-polygons-plasma-bridge-2e0954ccadf1">https://gerhard-wagner.medium.com/double-spending-bug-in-polygons-plasma-bridge-2e0954ccadf1</a></li>
</ul>IceBear이더리움 네트워크에서 과거에 주로 발생했던 취약점 유형을 정리한 발표자료입니다.About Ethereum Blockchain Network Part12022-05-25T22:00:00+00:002022-05-25T22:00:00+00:00https://bears-team.github.io//background/ethereum/bears-about-ethereum-part1<h1 id="executive-summary">Executive Summary</h1>
<p>이 포스트에서는 블록체인과 관련하여 기본적인 개념들을 소개할 계획입니다. 다만, 비트코인(Bitcoin)과 같은 전송코인이 중심이 아니라 이더리움(Ethereum), 스마트컨트렉트(Smart Contract)를 중심으로 내용을 살펴볼 예정이며, <a href="https://ethereum.org/en/developers/docs/intro-to-ethereum/">ethereum.org</a> 사이트에서 기술하고있는 내용을 중심으로, 기타 구글 검색을 통해서 나오는 내용을 추가하는 형식으로 주요 개념들을 정리하였습니다.</p>
<h1 id="what-is-a-blockchain">What is a Blockchain?</h1>
<p>이더리움 공식 홈페이지에서는 블록체인(BlockChain)에 대해서 간단하게 “네트워크상 존재하고 관리되는 공개 데이터베이스(Database)”라고 기술하고 있습니다. 데이터베이스(이하 DB)라면 학부 수업시간에 배운 트렌젝션(Transcation), 동시화(Sychronization), 무결성(Integrity)과 같은 속성이 이 글을 읽으시는 분들도 머리속에 떠오를 겁니다. 기본적으로 블록체인은 기존 DB와 다르게 동시성 문제는 무조건 직렬화(Serialization)으로 해결하고 있습니다. 무결성지원은 블록 체인에서의 체인(Chain)부분이 지원하고 있다고 봐도 될 것 같습니다. 블록체인에서 블록과 블록이 연결되어 있는데 이 연결성은 암호학적 일방향함수(Crytographic oneway function), 쉽게 말하면 해쉬함수를 기반으로 동작하고 있습니다. 변조된 데이터가 동일한 해쉬결과 값을 가지는 것을 충돌현상(Hash Collision)이라고 하는데, 단 하나의 블록에서 이를 발생 시키는 것은 정말 어렵습니다. 물론 구글에서 SHA2 충돌에 성공하였지만, 블록체인은 SHA2보다 매우 안전한 SHA3를 기본 해쉬함수로 사용하고 있습니다. 하나를 블록은 변조하는 것도 어려운데, 자식 블록의 악의적인 데이터 변조를 위해 모든 조상 블록의 데이터를 변조해야 한다면 블록변조는 실용적 관점에서는 불가능합니다. 이 부분에 대해서는 <a href="https://youtu.be/SSo_EIwHSd4">Youtube영상</a>을 확인하시면 쉽게 이해하실 수 있습니다.</p>
<p>블록체인을 DB관점에서 바라본다면, 블록(Block)은 트렌젝션 데이터와 현재 블록의 상태를 저장하는 곳이라고 보면될 것 같습니다. 하나의 블록안에는 여러개의 트렌젝션을 담을 수 있고, 이더리움의 높은 가스비를 해결하는 방법으로 한 블록에 다수의 트렌젝션을 담아서 검증하는 방법을 많이 사용됩니다.</p>
<h2 id="ethereum">Ethereum</h2>
<p>이더리움은 Layer1 불록체인의 일종으로 비트코인과 같이 가치저장용(?), 전송용 블록체인과 구분이 됩니다. 현재 Layer1 블록체인은 여러 종류가 생겼으며, 최근에 가장 문제가 되었던 LUNA(루나) 또한 Layer1 블록체인입니다. 이더리움 블록체인이 단순 가치 저장용 비트코인과 달리, 그 블록체인 위해서 다양한 기능을 가능하게 하는 그 기반은 Smart Contract(스마트 컨트렉트)와 이 스마트 컨트렉트를 실행하는 Ethereum Virtual Machine(EVM)입니다. 여기에 추가하자면 스마트 컨트렉트를 기술하기 위한 Solidity(솔리더티)라는 JavaScript 다소 비슷한 전용 프로그래밍 언어도 존재한다. 스마트 컨트렉트의 실행은 EVM에서 수행되며, 이 스마트 컨트렉트의 수행에 실행, 증명, 검증에 대한 보상으로 ETHER(이더)를 EVM을 구동하는 Miner(마이너)들이 받게 됩니다. 재미있는 것은 대부분의 Layer1 블록체인들이 이더리움 앱을 지원하기 위해 EVM을 다 지원한다는 것입니다. 실제로 암호화폐 시장에서 이더리움외 블록체인에서 EVM출시를 호재로 받아들려, 가격상승이 있기도 하였습니다. 따라서 기존에 이더리움 네트워크에서 구동되던 서비스가 이더리움이 자신들의 서비스와 맞지 않다고 판단할 때, 예를 들면 rust(러스트)기반의 솔라나(Solana)와 같은 블록체인으로 그대로 옮겨갈 수 도 있고. 또한 블록체인 앱 개발 회사의 경우 Solidity로 구현 후 동일한 앱을 다양한 체인위에서 서비스할 수 도 있습니다. 그 만큼 이더리움 블록체인위에 가치있는 Dapp들이 많이 있다라고 생각할 수 도 있을 것 같습니다.</p>
<h2 id="smart-contract">Smart Contract</h2>
<p>그럼 Smart Contract는 무엇인가? 개인적으로는 Smart Contract(스마트 컨트렉트)는 블록체인(이더리움)위에서 돌아가는 하나의 기능(Function) 또는 코드 조각(Code Snippet)이라고 생각합니다. 응용프로그램(Application)이라고 설명하고 있는데도 있지만, 개인적으로는 여러개의 스마트 컨트렉트를 구현해서 하나로 통합한 것을 DApp(Decentralized Application)이라고 개인적으로 이해하고 있습니다. <a href="https://immunefi.com/">Immunefi</a>에 등록된 다양한 프로젝트를 살펴보면 거의 대부분 프로젝트들이 다수의 스마트 컨트렉트를 활용해서 구현하고 있는 것을 알 수 있습니다. 앞에서 언급했던 것과 같이 Smart Contract는 EVM위에서 동작하게 되며, 스마트 컨트렉트는 일종의 Non Von Neumann Virtual Machine이라고 생각할 수 있습니다. 스마트 컨트렉트가 Non Von Neumann 것은 블록체인에서의 핵심 속성인 실행중에 코드를 변경할 수 없기 때문입니다. 즉 코드 및 관련 핵심 데이터들이 오직 ROM만 존재합니다. 따라서 이와 관련된 문제가 있을 수 있는데, 예를 들면 스마트 컨트렉트 업데이트가 필요할 때, 그리고 스마트 컨트렉트의 보안성을 강화하기 위한 난독화를 실시할 때 즉 실제 코드가 변경해야하는 경우 기존 컴퓨터 시스템과 달리 접근해야 하는 어려움이 있습니다.</p>
<p>아래 EVM의 그림을 보면, 스마트 컨트렉트의 코드(바이트코드) 및 상태정보들이 모두 ROM에 위치하여 실행되는 것을 확인할 수 있습니다.</p>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-05-19-bears-about-ethereum-part1/evm.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">그림.1 EVM의 간략한 구조도</td>
</tr>
</tbody>
</table>
<p>스마트 컨트렉트가 실행되기 위해서는 블록체인 네트워크내 배포(Deploy)가 되어야 하는데 일반적으로 배포는 특수한 주소(0x0 번지)로 스마트 컨트렉트를 전송함으로써 이뤄지게 됩니다. 배포가 완료되면 스마트 컨트렉트도 고유한 주소를 가지게 되며 이 주소가 계정(Account)가 됩니다. 바로 이어서 다시 설명이 됩니다.</p>
<h2 id="accounts">Accounts</h2>
<p>이더리움 블록체인에서 계정(Accounts)는 이더(ETHER)를 저장할 수 있는 공간을 의미합니다. 이더리움 블록체인을 이용하는 사용자는 계정(Accounts)을 생성할 수 있고, 이더를 보내거나 받거나 할 수 있습니다. 이렇게 적고보니 계정이라고 번역하는 것 보다 계좌라고 번역하는게 더 가까워 보입니다. 글을 읽으시는 분들이 본인이 더 적절하다고 생각하는 표현으로 사용하셔도 괜찮을 것 같습니다. 이더리움에서 Accounts는 두가지 종류가 있습니다. EOA(Externally Owned Account)라고 해서 일반적으로 사용자가 계정을 만들게 되면 EOA입니다. 그리고 당연하게 스마트 컨트넥트도 Account가 될 수 있습니다. 스마트 컨트렉트로 고유 이더리움 주소를 가질 수 있으며, 이 것은 다양한 DeFi 코드에서 확인이 가능합니다. 따라서 EOA와 EOA, EOA와 스마트 컨트렉트, 스마트 컨트렉트와 스마트 컨트렉드간에 이더의 송수신이 가능합니다.</p>
<p>그럼 이 두 계정의 차이점은 무엇일까요? 이더리움 공식 문서에서는 다음과 같이 이 두 계정의 차이점을 설명하고 있습니다.</p>
<h3 id="eoaexternally-owned-account">EOA(Externally Owned Account)</h3>
<ul>
<li>Creating an account costs nothing</li>
<li>Can initiate transactions</li>
<li>Transactions between EOAs can only be ETH/token transfer</li>
</ul>
<h3 id="cacontract-account--smart-contract">CA(Contract Account) : Smart Contract</h3>
<ul>
<li>Creating a contract has a cost because you’re using network storage</li>
<li>Can only send transactions in reponse to receiving a transaction</li>
<li>Transactions from an EOA to a contract account can trigger code which can execute many different actions, such as transfering tokens or even creating a new contract</li>
</ul>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-05-19-bears-about-ethereum-part1/ca.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">그림.2 모든 CA는 EOA에 의해 동작하게 된다.</td>
</tr>
</tbody>
</table>
<p>EOA와 CA의 가장 차이점은 그림.2에서 설명하듯이 CA는 EOA에 의해 유발된 트렌젝션에 의해서만 수동적으로 동작을 한다.라는 점입니다.</p>
<h2 id="blocks">Blocks</h2>
<p>이더리움 블록체인은 제네시스(최초의 블록)라는 상태에서 시작하며, 제네시스 상태란 어떠한 트렌젝션도 발생하지 않은 최소의 상태입니다. 이 최초의 상태에서 이더리움 블록체인의 상태를 변하게 하는 트렌젝션이 발생하면 t+1 스테이트로 전이(transition)이 발생하게 되며 이런 블록체인 세계의 상태를 변이하는 트렌젝션을 묶어서 검증하고, 기록하게 되는데 이것을 블록이라고 합니다. 이러한 블록들은 이전 블록의 해쉬값을 기반으로 연속적으로 연결되어 있습니다.</p>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-05-19-bears-about-ethereum-part1/blocks01.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">그림.3 모든 블록들은 해쉬값을 기반으로 체인구조로 연결되어 있다.</td>
</tr>
</tbody>
</table>
<p>블록에 대한 검증(Validate)를 PoW를 합의알고리즘으로 사용하는 이더리움에서는 마이너라고 불리는 검증자 노드에서 수행하며, PoS에서는 검증자(Validator)라고 불리는 노드에서 수행하게 됩니다. 두 집단의 목표는 같으며, 검증을 통한 수수료를 목표로 합니다. 이더리움에서 마이너는 트렌젝션이 가지는 가스비와 마이닝의 보상인 이더를 가질수 있고, 이 보상을 획득할려는 마이너의 경쟁을 구도 속에서 분산화라는 목적을 달성할 수 있습니다. PoW, PoS, DPoS 다양한 합의 알고리즘에서 검증자의 집중화를 막는 근간의 더 많은 수수료를 얻기위한 경쟁구도 속의 인간의 욕심이라고 할 수 있습니다.</p>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-05-19-bears-about-ethereum-part1/blocks02.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">그림.4 블록 헤더내 속성(Properties).</td>
</tr>
</tbody>
</table>
<ul>
<li>parentHash : 부모 블록의 해쉬값</li>
<li>nonce : mixHash와 결합하여 현재 블록이 충분한 연산을 행했음을 입증하는 해쉬, PoW에서 nonce값을 찾는 해쉬연산을 마이너들이 수행하게되며, 이는 무작위공격(brute-forcing)을 통해서 획득합니다.</li>
<li>timestamp : 현재 블록 시작시 unix 타임 스탬프</li>
<li>ommersHash : 현재 블록의 ommers 해쉬값의 리스트</li>
<li>beneficiary : 이 블록 채구에 대한 수수료를 받을 account 주소</li>
<li>logsBloom : log 정보를 구성하는 bloom filter라는 자료 구조의 형태</li>
<li>difficulty : 블록 생성 난이도, 난이도는 고정이 아니라 블록체인의 혼잡도와 같은 블록체인 상태에 따라 난이도의 변화합니다.</li>
<li>extraData : 블록과 관련된 정보를 저장하는 임의 바이트 배열</li>
<li>number : 현재 블록의 count(제네시스 블록이 0일 때, 이후 블록들에 대해서 이 값이 하나씩 증가)</li>
<li>gasLimit : 블록 당 현재 GAS 제한량</li>
<li>gasUsed : 현재 블록에서 사용된 가스의 총량</li>
<li>mixHash : nonce와 더블어 현재 블록이 충분한 연산이 실행되었음을 입증하는 해쉬값, Miner들은 mixHash값을 결과로 하는 입력 nonce값을 찾아야 하는 문제를 풀어야하고, 이 문제는 일방향 함수(oneway function) 해쉬 알고리즘을 기반으로 하기 있기 때문에 이런 계산에 최적화된 고성능 GPU가 CPU보다 유리하기 때문에, GPU 품귀 현상을 유발하였던 것 입니다. 좀 더 추가적으로 설명하면, NVidia, Intel, AMD에서 채굴용 AP 제품을 출시 했으나, 인기가 없었는데 그 이유는 채굴 사업이 망했을 때 채굴용 AP는 중고로 판매할 수가 없으나 고성능 GPU의 경우 중고로 판매가 수월하기 때문에 채굴 사업자 관점에서 GPU가 리스크 관리 차원에서 더 좋은 선택이 됩니다.</li>
<li>stateRoot : 상태 트리의 루트 노드 해쉬값</li>
<li>transactionRoot : 이 블록에 포함된 모든 트랜젝션을 포함하는 트리 자료구조의 루트 노드의 해쉬값</li>
<li>receiptsRoot : 이 블록에서의 모든 트랜젝션의 Receipt을 포함한 트리의 루트노드의 해쉬값</li>
</ul>
<h2 id="transcations">Transcations</h2>
<p>이더리움 공식 홈페이지에서는 트렌젝션을 EOA가 유발한 어떠한 행위를 의미한다라고 기술하고 있습니다. <a href="https://github.com/ethereumbook/ethereumbook">Matering Ethereum</a>도서에서는 트렌젝션을 EOA에서 생성한 서명된 메세지로서 이 메세지는 이더리움 네트워크를 통해 전달되며, 이더리움 블록체인에 기록이 된다라고 설명하고 있습니다. 결국 이 트렌젝션에 의해서 블록체인 네트워크의 상태가 변화하게 되는 것이고, 이 블록체인 세계의 상태값들은 EVM에서 스마트 컨트렉트 바이트코드를 실행할 때 영향을 주게 됩니다.</p>
<p>블록체인 네트워크에서의 트렌젝션은 직렬화되어서 처리됩니다. 즉 트렌젝션을 동시에 처리하는 것은 없습니다. 기본적으로 Step By Step으로 처리하게 됩니다. 이더리움내 트렌젝션은 다음과 같은 속성들을 가지고 있습니다.</p>
<ul>
<li>Nonce : x86/x64 시스템에서도 네트워크 프로토콜 관련된 공격중 Replay Acttack을 방지하기 위해 Nonce를 설정하는데, 이더리움 트렌젝션에서도 동일한 목적으로 Nonce를 활용하며, 여기에 추가적으로 순차적인 트렌젝션 처리를 위해서 Nonce를 사용한다. 암호학에서 처럼 의사 랜덤을 활용해서 Nonce값을 설정하기 보다, 이더리움에서는 생성된 트렉젝션 순서에따라 Nonce 값을 1씩 증가시킨다.</li>
<li>Gas price : 발신자가 지급하는 가스의 가격</li>
<li>Gas limit : 이 트랜젝션을 처리하기 위해 소비될 최대 가스양</li>
<li>Recipient : 트렌젝션의 목적이 이더리움 주소</li>
<li>Value : 이 트랜젝션을 통해 전달할 이더(ETHER)</li>
<li>Data : 가변 길이 바이너리 데이터 페이로드</li>
<li>v,r,s : EOA의 ECDSA 딪털 서명의 세가지 구성요소</li>
</ul>
<p>앞에서 Nonce에서 Replay attack을 막기위한 수단으로 사용한다고 설명하였습니다. 이 기능에 추가하여 Nonce는 블록체인에서 트렌젝션 직렬화 역할도 담당하고 있습니다.</p>
<p>사용자 지갑에 10이더가 있고, 아래 그림과 같이 Nonce가 3인 6이더를 보내는 트렌젝션과 Nonce가 4인 8이더를 보내는 트렌젝션을 EOA에서 연속으로 트렌젝션을 생성하였습니다. 블록체인 네트워크에 이 두 트렌젝션이 배포되는 동안 어떤 검증자(또는 마이너) 노드는 Nonce 3인 블록을 받고 이 노드는 이미 Nonce 2도 처리하였습니다., 어떤 검증자 노드는 Nonce 4이 트렌젝션만 받았습니다. Nonce 3인 트렌젝션은 받은 노드는 이미 Nonce 3 이전의 트렌젝션까지를 받아서 처리하였기 때문에 Nonce 3을 받자마자 처리를 하지만, Nonce 4인 트렌젝션을 받은 노드는 이 트렌젝션을 처리하지 않고 무시합니다.</p>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-05-19-bears-about-ethereum-part1/transaction01.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">그림.5 이더리움 블록체인에서 Nonce는 트렌젝션 직렬화 사례</td>
</tr>
</tbody>
</table>
<p>가스는 이더리움 블록체인에서 검증자들이 트렌젝션을 처리해주고 받는 보상이라고 생각하시면 됩니다. 당연히 많은 돈을 벌기위해서 검증자들은 높은 가스비의 트렌젝션을 처리하고 싶어합니다. 이를 노리고 블록체인내에서 수행되는 악성행위를 Front-running 공격이라고 합니다. Front-running 공격은 블록체인 초반에 존재했던 공격으로 생각하고 있으며, 최근에 공격 사례를 보기가 어렵습니다.</p>
<h1 id="conclusion">Conclusion</h1>
<p>이 번 포스트에서는 스마트 컨트렉트 기반 블록체인의 대표인 이더리움에 대해서 알아보고, 관련된 주요 키워드들의 개념을 전체적으로 간단히 알아보았습니다. 다음 포스트에서는 각 개념들이 실제로 어떻게 블록체인 내에서 존재하는지 geth환경내에서 살펴보고 분석해보는 시간을 가지도록 하겠습니다. 읽어주셔서 감사합니다.</p>
<h1 id="references">References</h1>
<ul>
<li><a href="https://ethereum.org/en/developers/docs/intro-to-ethereum/">https://ethereum.org/en/developers/docs/intro-to-ethereum/</a></li>
<li><a href="https://ethereum.org/en/developers/docs/blocks/#:~:text=Blocks%20are%20batches%20of%20transactions,derived%20from%20the%20block%20data.">https://ethereum.org/en/developers/docs/blocks/#:~:text=Blocks%20are%20batches%20of%20transactions,derived%20from%20the%20block%20data.</a></li>
<li><a href="https://ethereum.org/en/developers/docs/dapps/">https://ethereum.org/en/developers/docs/dapps/</a></li>
<li><a href="https://ethereum.org/en/developers/docs/transactions/">https://ethereum.org/en/developers/docs/transactions/</a></li>
<li><a href="https://andersbrownworth.com/blockchain/">https://andersbrownworth.com/blockchain/</a></li>
<li><a href="https://medium.com/@eiki1212/ethereum-block-structure-explained-1893bb226bd6">https://medium.com/@eiki1212/ethereum-block-structure-explained-1893bb226bd6</a></li>
<li><a href="https://medium.com/remix-ide/the-anatomy-of-a-transaction-receipt-d935aacc9fcd">https://medium.com/remix-ide/the-anatomy-of-a-transaction-receipt-d935aacc9fcd</a></li>
<li><a href="https://minstar0410.tistory.com/28">https://minstar0410.tistory.com/28</a></li>
<li><a href="https://immunefi.com/">https://immunefi.com/</a></li>
</ul>Panda이더리움과 관련된 기본 지식, 개념을 세미나용으로 정리한 글입니다.RevestFinance Vulnerabilities: More than Reentrancy 리뷰2022-05-12T22:00:00+00:002022-05-12T22:00:00+00:00https://bears-team.github.io//security/smart%20contract/blocksec/blocksec-revestfinance-vulnerabilities-review<h1 id="executive-summary">Executive Summary</h1>
<p>BlockSec의 경우는 etherscan 서비스를 기반으로하는 공격 탐지 시스템을 개발하여 이를 활용해서 공격을 탐지하고, 공격 당하는 서비스업체에게 알려주는 서비스가 가능한 업체인데, 개인적으로 BlockSec의 글을 읽을 때마가, 공격인지여부를 판단을 어떻게 하는지 궁금합니다. BlockSec은 RevestFinance 서비스 사례에서 두 가지를 자랑하고 있습니다. 첫 번째는 BlockSec사의 공격 알림 시스템의 공격 포착 능력이고 두 번째는 자신들의 유효한 제로데이 탐지능력 이 두가지 입니다. 그럼 이 두가지에 대해서 이 번 블로그를 통해 살펴보로록 하겠습니다.</p>
<h1 id="introudction">Introudction</h1>
<p>22년 3월27일에 이더리움기반 DeFi 서비스인 Revest Finance를 대상으로 ERC-1155 callback에 대한 공격이 있었습니다. 해당 공격으로 약 2백만달러 정도의 토큰(BLOCKS, ECO, LYXe, and RENA)가 탈취되었으며, 첫 번째 공격 분석이후 바로 BlockSec팀의 <a href="https://twitter.com/BlockSecTeam/status/1508065573250678793">트윗</a>이 있었습니다. 이 문장으로 미뤄짐작해보면, 공격에 대한 알람은 자동화된 것으로 추정되고, 분석이후라는 구절을 생각해보면 실제 공격인지 여부는 전문가의 능력에 의존하는게 아닌지 생각해봅니다.</p>
<p>실제 공격에 대한 트위터를 작성하는 동한 BlockSec팀은 Revest ToeknVault 컨트렉트 기능에 대한 의구심을 가지고 있었다라고 기술하고 있는데, 왜 그런 의구심을 가지게 되었는지는 지 이런 가치판단의 기준이 개인적으로 중요하다고 생각합니다. 혼자서 재미로 취약점을 찾고 분석하는 것과 다르게 회사차원에서 인력을 투입하는 것이기 때문에, 결과론 적으로 제로데이를 찾고, 해당 업체에 정보를 제공함으로써 행복한 결말을 맞이하였지만, 인력만 투입하고 아무런 결과도 못 얻는 경우도 생길 수 있기 때문에, 이 때의 BlockSec팀 리더의 판단의 흐름에 대해서 한 번 BEARS 팀에서 한 번 토의해보는 것도 좋을 것 같습니다. 이러한 의구심을 기반으로 Revest Finance의 컨트렉트의 기능을 분석했고, 앞에서 탐지한 취약점 보다 더 쉽게 돈을 탈취할 수 있는 취약점을 찾을 수 있었고, Revest Finance팀의 신속한 대응으로 큰 돈의 유출을 막을 수 있었다.라고 기술하고 있습니다.</p>
<p>도입부 글에서 <span style="background-color:#fff5b1">왜 BlockSec팀을 추가적인 분석을 단행했는가?</span> 이 것에 대한 개인적인 의견은 <span style="background-color:#fff5b1">공격 탐지 시스템에 의해 확인된 공격이 Reentrancy 취약점이기 때문에 아닐까?</span>라는 생각을 해봤습니다. <span style="background-color:#fff5b1">그럼 왜 Reentrancy취약점이 문제인가?</span>라는 질문이 생길 수 있는데 이 것에 대한 제 생각은 Reentrancy취약점은 Solidity 취약점 타입중에 x86/x64에 대입하면 strcpy를 활용한 BoF처럼 <span style="background-color:#fff5b1">지금에 와서는 좀처럼 나오지 않는 아주 기초적인 취약점 유형이기 때문입니다.</span> 즉 너무 기초적인 취약점 조차 걸러낼 수 없는 개발자가 작성한 컨트렉트이기 때문에 충분히 다른 취약점이 존재할 수 있다라는 확신을 가지고 BlockSec팀은 분석을 착수한 것이 아닐까?라는 추정을 해봤습니다. 만약에 그렇다면 개인적으로는 합리적인 의심을 기반으로한 접근이라고 생각이 듭니다.</p>
<h1 id="background-revest-finance-fnft">Background: Revest Finance FNFT</h1>
<p>FNFT에 대해서 아래와 같이 설명하고 있습니다.</p>
<p>The Financial Non-Fungible Token (FNFT) of Revest Finance makes the trustless transfer of the future rights to locked assets possible.</p>
<p>간단히 설명해보면, FNFT는 기존에 Immuefi 사례에서 볼 수 있듯이 예치된 자산에 대한 나의 지분률이라고 생각하면 됩니다. locked라는 표현은 일반적으로 stacking하거나 유동성을 공급하면 기본적인 예치기간이 있기 때문이고, <a href="https://bears-team.github.io/security/smart%20contract/immunefi-apwine-review/">Immuefi의 APWine 사례</a>에서와 같이 예치한 사람이 아니라 다른 사람(대리수령)도 해당 토큰을 기반으로 돈을 찾아 갈 수 있기 때문에 trustless transfer라는 표현을 사용한 것으로 판단됩니다.</p>
<p>FNFT를 생성하는 방법으로 Revest Contract에서 제공하는 함수는 3가지로 소개하고 있습니다.</p>
<ul>
<li>mintTimeLock : 일정한 시간이 지나면 FNFT 토큰(지분) 만틈 Vault에서 예치토큰을 찾아감</li>
<li>mintValueLock : 예치 자산이 사전에 약속된 가격 이상으로 상승하거나 하락할 때 토큰을 찾아 갈 수 있음</li>
<li>mintAddressLock : 예치 자산을 지정된 주소만 해제할 수 있음</li>
</ul>
<p>기초가산 해제를 위해 Revest 컨트렉트와 연결된 컨트렉트는 3개이며, 각각의 역활은 다음과 같습니다.</p>
<ul>
<li>FNFTHandler : ERC-1155(엔진코인에서 MultiToken관련 표준)를 상속받은 컨트렉트로 유니크 아이로 fnfid를 사용하는데, 토큰을 Lock을 걸어 FNFT를 민팅할 때마다 1씩 증가한다. 새로운 FNFT을 생성/소각하는 방법은 기준토큰 예치를 통한 생성과 기초자산 출금을 통한 소각말고는 방법이 없다.</li>
<li>LockManager : 묶여있는 기초자산을 출금할 때 락(lock)을 해제할 조건을 기록하고 출금시 해제조건의 부합여부 확인과 같은 기능을 담당함</li>
<li>TokenVault : 기초자산 토큰에 대한 송수신을 담당하고 각각의 FNFT에 대한 메타데이터 기록을 담당함</li>
</ul>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-04-29-blocksec-revestfinance-vulnerabilities-review/figure01.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">그림.1 기초자산에 대한 Lock과정</td>
</tr>
</tbody>
</table>
<p>그림 1에서는 사용자 A가 100WETH를 최초 예치하는 과정을 그리고 있습니다. 맨처음 예치하는 것이기 때문에 fntfid는 1이되고, FNFT 토큰은 1:1 교환비율로 Unlock할 수 있는 대상 User A, User B, User C에 각각 50, 25, 25 생성됩니다. 즉 <span style="background-color:#fff5b1">1FNFT = 1WETH</span>가 됩니다.</p>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-04-29-blocksec-revestfinance-vulnerabilities-review/figure02.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">그림.2 기초자산에 대한 Unlock및 출금과정</td>
</tr>
</tbody>
</table>
<p>그림 2는 출금과정을 표현하고 있습니다. 사용자 X는 Unlock할 수 있는 대상이 아니기 때문에 거부되는 것을 보여주고 사용자 B의 경우 정당한 Unlock권한이 있으므로, 자기 지분 FNFT 25개 만큼 기초자산 25WETH를 찾아가게 됩니다.</p>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-04-29-blocksec-revestfinance-vulnerabilities-review/figure03.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">그림.3 추가적인 기초자산 예치시 Revest Finance 동작(depositAdditionalToFNFT) 흐름도</td>
</tr>
</tbody>
</table>
<p>그림1, 2를 통해 기초적인 동작흐름을 살펴보았습니다. 이제 부터 Revest Finance취약점과 관련 있는 부분을 살펴보도록 하겠습니다. 일반적으로 거의 모든 DeFi들이 동일한 기능을 지원하고 있습니다. 추가적으로 스와핑 풀에 유동성을 공급하거나, 추가적인 스테이킹을 하는 것이 지금 Revest Finance의 경우와 유사한 기능이라고 할 수 있습니다. 우리가 지금부터 살펴볼 그림 3.에서는 <span style="background-color:#fff5b1">함수는 depositAdditionalToFNFT</span> 동작 과정을 그리고 있습니다. 그림 2.에서 사용자 B는 25 WETH만큼의 기초자산을 가져갔습니다. 그래서 Vault에는 75WETH가 남아 있으며, 이 지분을 표현하기 위해 75FNFT가 발행되어 있습이다. 사용자 A가 이 자산에 추가적으로 기초자산을 더 할려고 depositAdditionalToFNFT 함수를 호출 합니다. depositAdditionalToFNFT의 함수 파라미터를 보면 <span style="background-color:#fff5b1">amount</span>이라는게 있습니다. 우리말로 번역하면 amount는 양이 되는데, 그 다음 변수 quantity도 번역하면 양입니다. 저는 개인적으로 이 부분이 조금 헷갈렸습니다. 그래서 이 부분을 실제 <a href="https://github.com/Revest-Finance/RevestContracts/blob/59b533221f62a9a422a2443f2c34060b4c3fd3d1/hardhat/contracts/Revest.sol#L214">Github에서 소스코드</a>로 확인하고 명확하게 이해할 수 있었습니다. 그림 3.에서 quantity는 amount를 추가할 FNFT 토큰의 개수를 의미합니다. 그림 3.에서 75개면 지금 현재 Vault에 남아있는 전체 fnftid 1을 의미합니다. 그 다음 <span style="background-color:#fff5b1">amount는 한 개의 FNFT에 추가할 가치라고 생각하시면 됩니다.</span> depositAdditionalToFNFT가 호출되지간 1 FNFT는 1WETH였습니다. 이제 1FNFT를 1.5WETH로 만들고 싶습니다. 각 1FNFT의 가치가 0.5WETH씩 더해져야 하는데, 그 때의 양(amount)입니다. amount에 대해서 다들 이해가 되셨을거라 생각합니다. 그러면 사용자 A가 위와 같이 FNFT의 가치를 올릴려고 하면 Vault에 추가해야할 전체 금액은 \({0.5}_{WETH} * 75 = {37.5}_{WETH}\) 입니다. 사용자 C가 A가 추가적으로 가치를 더 한 다음에 자기 지분만큼 찾아가게 되면 그림 2.의 사용자 B와 다르게 동일한 지분 25FNFT를 출금함에도 \({25}_{FNFT} * {1.5}_{WETH/FNFT} = {37.5}_{WETH}\) 을 출금할 수 있습니다. {25}_{WETH}를 찾아간 사용자 B가 왠지 손해본 느낌이네요… ㅎㅎ</p>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-04-29-blocksec-revestfinance-vulnerabilities-review/figure04.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">그림.4 추가적인 기초자산 예치시 Revest Finance 동작(depositAdditionalToFNFT) 흐름도(depositAdditionalToFNFT의 quantity가 현재 발행양 보다 작을 경우)</td>
</tr>
</tbody>
</table>
<p>그림.3의 경우는 민팅된 토큰 양만큼 추가하는 과정을 표현한 것이라면, 그림.4의 경우는 민팅된 코인 양보다 작은 양에 대해서 추가적인 예치를 할 때의 과정을 표현하고 있습니다. 이 경우는 먼저 <span style="background-color:#fff5b1">quantity</span>만큼 옛코인(fnftid가 1코인)을 소각처리를 하고 새로운 FNFT(fnftid가 2)를 <span style="background-color:#fff5b1">quantity</span>만큼 발금하고 이 새로운 FNFT의 각 토큰의 가치는 <span style="background-color:#fff5b1">1.5 + 0.5</span>해서 2.0WETH로 설정합니다.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>// Now, we transfer to the token vault
if(fnft.asset != address(0)){
IERC20(fnft.asset).safeTransferFrom(_msgSender(), vault, quantity * amount);
}
ITokenVault(vault).handleMultipleDeposits(fnftId, newFNFTId, fnft.depositAmount + amount);
emit FNFTAddionalDeposited(_msgSender(), newFNFTId, quantity, amount);
</code></pre></div></div>
<h1 id="case1-re-entrancy-vulnerability">CASE#1: Re-entrancy Vulnerability</h1>
<p>이 번 절에서는 Re-entrancy취약점에 대해서 살펴보겠습니다. Re-entrancy 취약점은 그림.4에서 그림.7까지의 그림으로 설명되며, 기본적인 개념은 callback 함수 구조와 validation로직의 부재를 기반으로 특정 함수(대부분 출금함수)를 특정조건(Vault내 기초자산을 0)을 만족할 때까지 호출하는 취약점입니다. Solidity 초기에 많이 유행했던 취약점이고 지금 현재 학계에서 많이 연구되고 있는 Solidity 취약점 탐지에서 많이 거론되는 취약점 유행입니다. 지금 현재도 학계에서 많이 다뤄지고 있는 Solidity 버전은 0.4XX 입니다.</p>
<h2 id="step1">STEP1</h2>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-04-29-blocksec-revestfinance-vulnerabilities-review/figure05.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">그림.5 공격자가 가치가 0인 FNFT를 민팅(가장 최근 fnftid가 1로 가정)</td>
</tr>
</tbody>
</table>
<p>첫번째 단계에서는 <span style="background-color:#fff5b1">depositAmount값을 0으로 하여</span> 두 번 RENA토큰을 기반으로 FNFT를 민팅합니다. 첫 번째에는 2개, 두 번째에는 360,000개 depositAmount값이 0이기 때문에 실제 돈이 들어가야 하는 것은 아닙니다. 웹과 같은 일반 사용자 인터페이스가 아닌 Attacking contract를 통해 직접 mintAddressLock을 호출하는 것으로 판단됩니다. 일단 다음 단계로 넘어가기에 앞서 depositAmount값이 0인 것에 대한 검증을 하지 않는다는게 가장 큰 문제라고 생각이 됩니다. 과거 윈도우 R3와 달리 R0 드라이버 같은 경우 검증을 소흘히 해서 쓰기 버퍼의 주소가 유저영역인이 확인을 하지 않는다는지, 버퍼의 길이가 0인 것을 확인 하지 않는다는지 이런 경우가 있었는데, 요즘은 볼 수 없는 유형의 취약점이 되었는데, depositAmount가 0인지 확인하지 않는 것은 거의 앞에서 언급한 과거 윈도우 커널 취약점과 동일한 수준이라고 생각합니다. <span style="background-color:#fff5b1">뒤에 부분을 확인할 필요가 없이 아주 기본적인 함수 파라미터에 대한 검증이 없다는 것 자체가 가장 문제라고 봅니다.</span></p>
<h2 id="step2">STEP2</h2>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-04-29-blocksec-revestfinance-vulnerabilities-review/figure06.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">그림.6 공격자가 두번째 민팅할 때 콜백함수내에서 Revest contract의 depositAdditionalToFNFT함수를 재호출한다.</td>
</tr>
</tbody>
</table>
<p>두 번째 단계에서는 _mint함수가 아직 완료되기 전에 depositAdditionalToFNFT함수를 <span style="background-color:#fff5b1">fnftid=1, amount=\(1*1e18\), quantity=1</span>으로 호출합니다. 여기서 중요한 것은 아직 fnftid(2)로 민팅이 완료되지 않았기 fnftid의 1 증가가 발생하지 않은 상태이기 때문에 앞에서 quantity가 전체 민팅 개수 2보다 작기 조건을 활용하여 다시 fnftid가 2인 토큰을 민팅할 수 있습니다. 앞서 만든 fnfid(1)의 amount가 0이기 때문에 fnftid(2)인 토큰 1개는 <span style="background-color:#fff5b1"> \(0 + 1*1e18\)</span>의 amount로 업데이트 됩니다. 그리고 공격자는 \(1*1e18 {RENA}\)를 실제 입금하고, depositAdditionalToFNFT함수에서 fnftid가 하나 증가하고 최후의 _mint 함수에 의해 fnftid가 하나 증가하게 됩니다. 여기서 조금 아쉬운 것은 fnftid의 업데이트 위치가 아쉽습니다. 아마도 mint가 정상적으로 완료되는 것을 확인하고 fnftid를 1증가 시키는 것 이 논리적으로 깔끔하기 때문에 이렇게 구현한 것 같은데, _mint함수 호출전에 fnftid를 1증가 시키면 어떨까? 생각을 해봅니다.(실제 패치를 확인해본 결과 과거 Re-entrancy취약점 패치와 유사하게 검증로직 추가, fnftid 업데이트 코드 위치변경을 주요 내용으로 패치를 하였습니다.)</p>
<p>그리고 마지막으로 mint함수가 완료되면서 quantity가 360,000으로 업데이트 됩니다. 다시 정리하면 depositAdditionalToFNFT로 amount를 업데이트 하고 mintAddressLock을 통해 quantity를 업데이트 한 것입니다. 이 모든게 mintAddressLock에서 amount가 0인 경우에 대해서 핸들리하지 않아서라고 판단합니다. 과연 amount가 0인 경우가 필요할 때가 언제인지 개인적으로 잘 생각이 나지 않습니다.</p>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-04-29-blocksec-revestfinance-vulnerabilities-review/mint.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">그림.7 OpenZepplelin내 ERC-1150의 mint함수 설명.account가 컨트렉트(contract)면 callback함수 핸들러는 구현할 것을 설명하고 있다.</td>
</tr>
</tbody>
</table>
<h2 id="step3">STEP3</h2>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-04-29-blocksec-revestfinance-vulnerabilities-review/figure07.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">그림.8 공격자가 기초자산을 출금한다.</td>
</tr>
</tbody>
</table>
<p>이제 모든것이 준비되었습니다. Lock자체도 공격자 주소기반으로 Lock을 걸었기 때문에, 공격자는 언제든지 편안하게 기초 자산을 출금할 수 있습니다.</p>
<h2 id="security-patch">Security Patch</h2>
<p>패치를 보면 mint함수에서 _mint함수를 호출하기 전에 검증 및 fnftid 증가등을 하고 있는 것을 확인할 수 있습니다.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>function mint(
address account,
uint id,
uint amount,
bytes memory data
) external override onlyRevestController {
require(amount > 0, "Invalid amount");
require(supply[id] == 0, "Repeated mint for the same FNFT");
supply[id] += amount;
fnftsCreated += 1;
_mint(account, id, amount, data);
}
</code></pre></div></div>
<h1 id="case2-new-zeroday">CASE#2: New Zeroday</h1>
<p>두 번째 취약점은 BlockSec팀에서 자체적으로 찾은 Zeroday에 대한 설명입니다. 아마도 BlockSec팀에서 지금 Solidity 0.8.XX 시대에 Re-entrancy취약점이라고? 그럼 뭔가 더 첫번째 수준의 취약점이 더 존재하지 않을까? 이런 관점에서 Revest Finance의 코드를 분석하지 않았을까? 추가적인 코드 감사이유를 생각해봤습니다.</p>
<p>BlockSec팀은 TokenVault 컨트넥트내의 <span style="background-color:#fff5b1">handleMultipleDeposits</span>함수내에 있는 depoitAmount를 업데이트 하는 부분을 언급하고 있습니다. 아마도 BlockSec팀은 amount를 업데이트하는 모든 함수를 다 뒤져본게 아닌가?라는 생각이 듭니다.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>function handleMultipleDeposits(
uint fnftId,
uint newFNFTId,
uint amount
) external override onlyRevestController {
require(amount >= fnfts[fnftId].depositAmount, 'E003');
IRevest.FNFTConfig storage config = fnfts[fnftId];
config.depositAmount = amount;
mapFNFTToToken(fnftId, config);
if(newFNFTId != 0) {
mapFNFTToToken(newFNFTId, config);
}
}
</code></pre></div></div>
<p>depositAdditionalToFNFT함수에서 handleMultipleDeposits 함수가 호출되는데, 새로운 토큰의 amount업데이트 하는 부분입니다. BlockSec팀에서 전체 프로토콜을 분석했을 때 이 함수의 목적은 신규 NewFNFId의 토큰의 amount를 업데이트 하는게 이 함수의 목적인데, 위 코드를 보면 Old fnftid의 depoitAmount또한 업데이트하는 것을 확인할 수 있습니다.</p>
<h2 id="step1-1">STEP1</h2>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-04-29-blocksec-revestfinance-vulnerabilities-review/figure08.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">그림.9 공격자는 amount 0로 360,000 RENA를 민팅한다.</td>
</tr>
</tbody>
</table>
<p>이 공격에서도 시작은 amount 0으로 민팅하는 것입니다. 토큰을 한 개도 예치하지 않고 FNFT를 민팅할 수 있습니다. 앞에서도 언급했지만 가치가 0인 토큰을 민팅할 이유가 무엇진지 모르겠습니다. 왜 이런 기능이 있는지…</p>
<h2 id="step2-1">STEP2</h2>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-04-29-blocksec-revestfinance-vulnerabilities-review/figure09.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">그림.10 공격자는 depositAdditionalToFNFT 함수를 호출한다.</td>
</tr>
</tbody>
</table>
<p>두 번째 단계에서는 TotalSuppliedFNFT 개수보다 작을 때 depositAdditionalToFNFT함수의 로직을 활용합니다. depositAdditionaToFNFT를 그림과 같이 파마리터 설정해서 호출하면 당연히 전체 발행량보다 적기 때문에 새로운 NewNFTId를 만들게 되고, 그림에서와 같이 fnftid(2)로 새로운 lock을 만들게 됩니다. 그런데 문제가 기존의 Old fnftid(1)의 amount을 0에서 \(1*1e18\) RENA로 업데이트 하게 됩니다. amount가 \(1.0*1e18\) 인 36만개의 RENA가 생겼습니다. 첫 번째 Re-entrancy취약점 보다 더 쉽습니다.</p>
<h2 id="step3-1">STEP3</h2>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-04-29-blocksec-revestfinance-vulnerabilities-review/figure10.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">그림.11 공격자는 편안한 마음으로 토큰을 찾는다.</td>
</tr>
</tbody>
</table>
<p>마지막 단계는 편안하게 출금을 하면 됩니다.</p>
<h2 id="security-patch-1">Security Patch</h2>
<p>Old FNFTId의 amount를 업데이트 하든지, New FNFTId의 amount를 업데이트 하든지 둘 중에 한 경우만 업데이트 하도록 변경되었습니다. 제가 볼때에는 amount 0으로 민팅하는 것도 막아야할 것 같은데, 그 내용이 없어서 조금 아쉽습니다.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>function handleMultipleDeposits(
uint fnftId,
uint newFNFTId,
uint amount
) external override onlyRevestController {
require(amount >= fnfts[fnftId].depositAmount, 'E003');
IRevest.FNFTConfig memory config = fnfts[fnftId];
config.depositAmount = amount;
if(newFNFTId != 0) {
mapFNFTToToken(newFNFTId, config);
} else {
mapFNFTToToken(fnftId, config);
}
}
</code></pre></div></div>
<h1 id="conclusion">Conclusion</h1>
<p>이 번 블로그에서는 BlockSec팀의 Revest Finance 취약점 분석 및 탐지 내용을 살펴봤습니다.
BlockSec 팀의 분석 글을 처음으로 리뷰를 해봤는데, Immuefi쪽 분석글 보다, 내용이 한결 이해하기 편했습니다. 분석도 그림을 직관적으로 잘 그려서 그런 것 같은데, 앞으로 BlockSec팀의 분석 글중 괜찮은 것을 가능한 많이 리뷰할 수 있도록 하겠습니다.</p>
<p>오랜만에 만난 Re-entrancy취약점 및 이해가 너무 쉬운 취약점을 살펴봤습니다. 블록체인 프로젝트는 수만개가 존재하고, 바이너리 리버싱 기반 취약점 탐지와 같이 코드 감사기반으로 취약점을 탐지할 여지는 아직 많다고 이번 사례를 통해 느꼈으며, 이 글을 읽는 모든 분들이 <a href="https://immunefi.com/explore/">immunefi bounty</a>에 도전해 봄직 하지 않을까? 생각을 해봤습니다.</p>
<h1 id="references">References</h1>
<ul>
<li><a href="https://blocksecteam.medium.com/revest-finance-vulnerabilities-more-than-re-entrancy-1609957b742f">https://blocksecteam.medium.com/revest-finance-vulnerabilities-more-than-re-entrancy-1609957b742f</a></li>
<li><a href="https://twitter.com/BlockSecTeam/status/1508065573250678793">https://twitter.com/BlockSecTeam/status/1508065573250678793</a></li>
<li><a href="https://docs.openzeppelin.com/contracts/3.x/erc1155">https://docs.openzeppelin.com/contracts/3.x/erc1155</a></li>
<li><a href="https://eips.ethereum.org/EIPS/eip-1155">https://eips.ethereum.org/EIPS/eip-1155</a></li>
<li><a href="https://docs.openzeppelin.com/contracts/3.x/api/token/erc1155#ERC1155-_mint-address-uint256-uint256-bytes-">https://docs.openzeppelin.com/contracts/3.x/api/token/erc1155#ERC1155-_mint-address-uint256-uint256-bytes-</a></li>
<li><a href="https://immunefi.com/explore/">https://immunefi.com/explore/</a></li>
</ul>PandaBlockSec팀 3월31일에 작성한 RevestFinance Vulnerabilities 글에 대한 리뷰입니다.A survey on private smart contract construction method (Part2)2022-04-27T22:00:00+00:002022-04-27T22:00:00+00:00https://bears-team.github.io//security/smart%20contract/a-survey-on-private-smart-contract-contruction-method-part2<h1 id="executive-summary">Executive Summary</h1>
<p>이 문서는 <a href="https://bears-team.github.io/system%20trading/smart%20contract/ccs-cyclic-arbitrage-in-dex-review/">Cyclic Arbitrage in Decentralized Exchanges</a> 논문에서 언급이된 smart contract의 보안성을 높인 private smart contract와 관련된 현재 공개된 기술(기법)에 대해서 조사 및 분석한 결과를 공유하는 글입니다. 지난번 <a href="https://medium.com/iovlabs-innovation-stories/private-smart-contract-execution-7df89e28eb30">Medium 블로그</a> 글에 이어서 이번에는 Smart Contract의 코드 기밀성을 향상기키기 위한 방법으로 우리에게 익숙한 코드 난독화(Code Obfuscation)을 중심으로 관련 논문 2편을 정리할려고 합니다. 해당 글은 BEARS 팀 세미나에서 발표된 내용이며 BEARS팀 블록체인 스터디에 참여하고 싶으신 분들은 bears.team.kr[AT]gmail.com으로 연락주시면 감사하겠습니다.</p>
<h1 id="introudction">Introudction</h1>
<p>Private Smart Contract관련 기술조사 1부에서 우리는 여러개의 Private Smart Contract를 지원하는 프레임워크를 아주 간단히 살펴보았다. Private Smart Contract를 지원하기 위한 프레임워크는 기본적인 이더리움과 같은 메인넷 위해서 Private Smart Contract를 지원하기 위한 Layer-2 기능을 수행하는 것으로 파악되었고, 대부분이 이더리움 위에서 동작하는 것으로 판단이 됩니다.</p>
<p>Private Smart Contract를 지원하는 프레임들은 기본적인 큰 틀에서 접근방향이 유사하다고 볼 수 있습니다. 기존의 Solidity 기반 Smart Contract를 두 개로 구분, 사용자 입력, 주요 데이터 코드의 경우 Private한 장소(TEE, VM, 별도의 네트워크)에서 계산하고 이후 암호화된 계산된 결과를 Public 네트워크(예: 이더리움)에 검증을 받는 구조였습니다. 동작, 금액, 사용자에 대한 기밀성을 보장하기위한 서비스입니다. 이러한 동작방식은 Cyclic Arbitrage in DEX 조사시에는 예상하지 못 했던 것입니다. 이 논문을 분석할 때에는 x86/x64에서의 Themida, VMProtect와 같은 코드 난독화 정도의 기술이 적용된 Smart Contract를 Private Smart Contract라 생각했었습니다. 지금와서 생각해보면 난독화(Obfuscation) 기술의 취지 목적(분석자를 지치게 해서 역공학을 포기하게 만들자!)를 생각해보면 Private Smart Contract와는 약간의 거리가 있을 수도 있다라고 생각이 들었어야 했는데 말이죠…</p>
<p>그러나 금액 및 송수신자에 대한 정보는 노출되어도 상관이 없고 보호해야할 대상이 Smart Contract내 존재하는 코드, 핵심 알고리즘으로 제한될 경우 Smart Contract 코드 난독화 또한 충분한 가치가 있다고 생각이 듭니다. 예를 들어, 여러분들이 윈도우에서 어떤 프로그램의 기능을 역공학을 통해 알아내야한다고 생각해봅다면, 비슷한 기능을 하는 윈도우 기반 프로그램이 다수 존재할 때 지금 현재 분석을 할려고 하는 프로그램이 Themida로 팩킹이 되어있다면, 팩된 프로그램을 분석하기 보다, 비슷한 기능을 하는 다른 프로그램을 살펴볼 것이며 가능한 팩킹되지 않는 대상을 리버싱을 통해 기능을 분석할 것입니다. 비슷한 예를 블록체인에 찾아보면 다음과 같습니다. 이더리움, 솔라나와 같은 핫한 메인넷에는 시세차익 거래를 하는 다양한 봇들이 있습니다. 이 봇들을 개발하는 회사들은 자기를 봇의 시세차익 거래 알고리즘을 지키고 싶을 것입니다. 만약 x86/x64에서의 UPX 정도로 팩킹된 봇이 있다면 해당 봇은 알고리즘을 다른 경쟁회사에서 헌납하는 경우와 동일한 것입니다. 만약에 Themida나 VMProtect 수준으로 난독화 되어 있다면, 역공학 분석자는 그 시간에 다른 회사 봇을 분석할 것입니다. 상대적인 난이도 차이로 봇의 핵심 기술을 지킨 것입니다.</p>
<p>저는 기본적으로 1부에서 목록화한 Private Smart Contract 서비스대비 코드 난독화 기술이 실제 메인넷에서 스마트컨트렉트가 배포되기까지 과정이 간단하기 때문에 Private Smart Contract 서비스 사용하는 경우대비 속도적 측면에서 이점이 있을 것으로 판단됩니다. 다만 앞에서도 언급하였지만 코드 난독화가 가지고 있는 태생적인 한계점이 존재하기 때문에 이 점은 Solidity 난독화에서도 동일하게 적용됩니다.</p>
<p>본 블로그에서는 두 편의 Solidity기반 Smart Contract 코드 난독화 논문을 살펴볼 것이고, 한 논문의 경우는 github에 소스코드 또한 공개한 상태입니다. 두 편의 논문을 먼저 읽어본 저 개인적인 느낌은 두 편 모두 뭔가 좀 부족한데?라는 것이며, 그 부족한 부분을 우리 스터디 그룹에서 채워서 괜찮은 난독화 도구를 만들면 되지 않을까?라는 생각을 해봤습니다.</p>
<h1 id="source-code-obfuscation-for-smart-contracts">Source Code Obfuscation for Smart Contracts</h1>
<h2 id="motivation">Motivation</h2>
<p>이 논문의 경우 Solidity 코드 난독화 연구를 착수한 동기가 기존의 보안연구의 목적과 사뭇 다릅니다. 저자들이 Solidity 코드 난독화 연구를 착수한 동기는 기존의 EVM 바이트코드를 Solidity 코드로 변환해주는 도구를이 있는데 이들의 성능을 공정하게 평가할 적절한 테스트을 만드는 것이 어려워서 다양한 테스트 세트를 만들기한 도구를 만드는 것입니다. 그래서 난독화된 코드에 대한 가독화를 기준으로 여러 디스어셈 도구들 간에 깊이있는 평가에 기여한다는 것입니다. 이러만 목적으로 개발한 Solidity 도구 난독화 도구로 BiAn을 제안하며, BiAn이 Solidity 난독화를 위해 지원하는 기법으로 아래의 것들을 나열하고 있습니다.</p>
<ul>
<li>obfuscating a contract’s control flow</li>
<li>obfuscating a contract’s data flow</li>
<li>obfuscating a contract’s layout</li>
</ul>
<p>논문에서 BiAn 도구의 활용법으로 3가지를 제안하고 있습니다.</p>
<ul>
<li>Generate obfuscated test cases to evaluate static analysis tool(직접적인 연구동기)</li>
<li>Obfuscate contracts to protect the contracts from reversing</li>
<li>Generate the obfuscated versions of public datasets to expand the size of public datasets</li>
</ul>
<h2 id="proposed-modelapproach">Proposed Model(Approach)</h2>
<p>이 논문에서는 Solidity 코드에 대한 난독화(Obfuscation)과정을 3단계로 구성하고 있습니다.</p>
<h3 id="step1-control-flow-obfuscation">STEP1: Control flow obfuscation</h3>
<p>첫번째 단계에서는 Control flow obfuscation입니다. Control flow obfuscation의 과정은 다음과 같습니다.</p>
<ul>
<li>Parsing the source code based on control flow graph(CFG)</li>
<li>inserting opaque predicates : 어떤 더미코드를 삽입하는지 소스코드 분석을 통해서 확인이 필요할 것 같습니다. 개인적으로 IDA Pro를 예로하면 한 바이트 삽을 통해 디스어셈블리가 어렵게 만드는 것과 동일하다고 생각했었는데, 논문에서는 더미 분기문을 많이 만들어내는 코드 조작을 삽입하는 것으로 판단되며, 아마도 분석자가 보기에 지나치게 함수를 복잡하게 만들어 심리적으로 분석에 대한 부담을 주면서, 쓸데없는 코드 해석에 시간을 많이 소모하게 만드는 접근을 논문의 저자들은 생각한 것 같습니다.</li>
<li>flattening the control flow : 일반적인 x86/x64에서는 반복문과 같은 코드를 쭉 풀어서 길게 늘려놔서, IDA Pro내 그래프뷰(Graph View)에서 함수를 구조적으로 분석하기 힘들게 하는 것을 의미합니다. 논문에서는 이부분에 Basic Block Logic(BBL)을 마구 흐트려서(scramble) 코드 블록간의 관계를 약하게 한다라고 기술하고 있는데, 이 것이 정확하게 어떻게 하겠다는 건지는 추후에 BiAn 코드 분석을 통해 확인이 필요할 것 같습니다.
<h3 id="step2-data-flow-obfuscation">STEP2: Data flow obfuscation</h3>
<p>두 번째 단계는 데이터 흐름(Data flow)에 대한 난독화입니다. 호출 흠름에서 CFG기반으로 분석했던 것 처럼 데이터 흐름 분석을 위해 abstract syntax tree(AST)기반으로 스마트컨트렉트를 분석하게 됩니다. CFG분석 AST분석의 경우 solidity 퍼징에서 기본적으로 스마트 컨트렉트를 분석할 때 기본적으로 사용하는 기법으로 구글 검색을 하면 다양한 오픈소스 프로젝트를 확인할 수 있습니다. 현재 BEARS팀에서 개발한 Solidity 퍼저의 경우에도 퍼징을 위해 CFG, AST 분석을 기본적으로 하고 있습니다. 따라서 이 글을 읽으시는 여러분들도 CFG, AST 분석의 경우는 쉽게 구현할 수 있습니다.</p>
</li>
</ul>
<p>데이터 흐름 난독화는 크게 3가지 부분으로 구성되어 있습니다.</p>
<ul>
<li>Changing coding style</li>
<li>Replacing constants</li>
<li>Modifying storage types</li>
</ul>
<p>Change coding style 단계에는 저자달은 변수의 의미를 제거하였다라고 설명하고 있는데 예로 b라는 boolean 변수가 존재할 때, 이 변수를 다른 두개의 boolean 변수 p, q로 쪼개어 b를 p&q로 변경하는 것을 들고 있습니다. 기존식에서 양쪽에 동일한 의미의 다항식을 다양하게 추가함으로써 분석자의 혼란을 가중할 수 있을 것 같습니다. Replacing constants에 대해서는 적분상수(integral constant)를 산술식(arithmetic) 형식으로 변경 시켰다라고 설명하고 있습니다. 아지막 Modifying storage types에서는 Solidity에 존재하는 상태변수에 대해서 구조체 형태로 변경하여 구조체의 멤버로 접근하는 구조로 변경하고, 또한 로컬 변수로 재선언하여 사용하는 등 역공학 도구로 분석시 최대한 혼란을 가중시키는 방법을 제안하고 있습니다.</p>
<h3 id="step3-layout-obfuscation">STEP3: Layout obfuscation</h3>
<p>Layout obfuscation의 의미는 역공하는 분석자가 디스어셈을 기반으로 코드를 분석할 때의 부담을 증가시키는 것을 의미한다고 논문에 기술하고 있습니다. 이 것을 위해서 저자들은 코드에서 추가적인 정보가 될 수 있는 모든 것을 제거했다라고 하고 예로 소스코드 주석을 제거했다하고 언급하고 있으며, Solidity의 주소조합 공식에 따르면 40bit의 해쉬를 사용하고 있는데, 임의의 40비트 해쉬값으로 모든 식별자를 변경하는 기능이 있다라고 기술하고 있습니다. 이렇게 함으로서 얻을 수 있는 이득은 역공학 분석자에게 40비트 해쉬값중 주소를 식별하는 부담을 가중시키는 효과가 있을 것 같습니다.</p>
<h2 id="evaluation">Evaluation</h2>
<h3 id="experimental-dataset의-구성-및-실험과정">Experimental Dataset의 구성 및 실험과정</h3>
<p>논문의 실험 데이터는 10가지의 오랜된 유형의 취약점을 가지고 있는 44개의 스마트컨트렉트를 입수하여 각 스마트 컨트렉트별 취약점 유형을 태깅(Tagging)후, 모든 실험 대상 스마트컨트렉트를 난독화 합니다. 난독화 스마트 컨트렉트와 난독화 하지 않은 스마트컨트렉트를 대상으로 정적분석도구를 돌려서 취약점을 잘 탐지하는지 여부를 확인하는 방식으로 난독화 성능을 평가하였습니다. 이렇게 실험을 구성하는게 과연 난독화 성능을 잘 평가하는 방법인지는 약간의 토의를 해봐야 할 것 같지만, 스마트컨트렉트의 고전 취약점을 정적분석 도구를 활용해 빠르게 탐지하여 토큰을 훔칠려는 공격자를 대상으로 한다면 의미가 있는 실험으로 볼 수 있으나, 대부분 공격자들은 직접 리버싱을 할 가능성이 높기 때문에, 난독화된 코드를 실제로 살펴봄으로서 평가를 해야할 것으로 판단됩니다. 마지막으로 스마트컨트렉트는 solc로 컴파일하여 바이트코드를 생성하였습니다.</p>
<h3 id="evaluate-the-effeciency-of-bian-with-respect-to-complexity">Evaluate the effeciency of BiAn with respect to complexity</h3>
<p>메인 실험이전에 논문에서는 본인들이 개발한 BiAn도구가 얼마나 많이 스마트컨트렉트를 복잡하게 만드는지 확인하는 실험을 실시하였습니다. 얼마나 복잡하냐?라는 질문에 대한 판단기준으로 컨트렉트내 패스의 개수를 계산하였고, 이 계산을 하는 도구로 Vandal이라는 스마트컨트렉트 디컴파일러를 활용하였습니다. 실험 결과를 보면 BiAn 결과물들이 원 스마트컨트렉트 대비 복잡도(Path의 개수)가 많이 높아진 것을 확인 할 수 있고, 패스의 복잡도 향상대비 가스비의 증가는 상대적으로 낮아, 비용대비 복잡도 증가는 효율적이다라고 평가할 수 있습니다. 복잡도(complexity)에 대한 평가를 경로 개수의 증가만으로 평가하는 것이 올바른지는 논란이 있을 수 있지만,</p>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-04-28-a-survey-on-private-smart-contract-contruction-method-part2/bian_figure1.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">그림.1 Change in complexity and gas consumption</td>
</tr>
</tbody>
</table>
<h3 id="evaluate-the-effectiveness-of-bian-against-9-solidity-static-analysis-tools">Evaluate the effectiveness of BiAn against 9 solidity static analysis tools</h3>
<p>논문의 그림2는 논문의 그림을 두개로 나누어서 재구성했습니다. 실제 논문의 그림은 너무 작아서 컬러 출력해서 종이로 논문을 보면 글자가 확인이 안 될 정도입니다. 그래서 글자를 확인할 수 있는 수준으로 그림을 확대한 후, 그림을 재구성하였습니다. 그림 2-1과 2-2를 살펴보면 바로 결과를 알 수 있는데, 난독화한 코드의 경우 정적분석 도구들이 취약점 탐지에 상당히 실패하는 것을 확인할 수 있습니다.</p>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-04-28-a-survey-on-private-smart-contract-contruction-method-part2/bian_figure2_1.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">그림.2-1 The experimental results of smart contract detection using statis analysis tools</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-04-28-a-survey-on-private-smart-contract-contruction-method-part2/bian_figure2_2.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">그림.2-2 The experimental results of smart contract detection using statis analysis tools</td>
</tr>
</tbody>
</table>
<p>일차적으로 BiAn 논문에 대한 정리는 이정도로 실시하고, 이후에 BiAn을 사용하면서 실제 EVM 바이트 코드가 얼마나 복잡해지는지는 추가적으로 다뤄볼 계획입니다.(BiAn과 EShield에 대한 내용은 이 포스트에 점진적으로 계속 추가하겠습니다.) 아래 그림은 BiAn 사용 전/후의 스마트컨트렉트 변화이며, Layout obfuscation에서 말한 40bit 해쉬로 변수 이름을 대체한다는 것에 대한 명확한 뜻을 이해하는데 도움이 될 것입니다.</p>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-04-28-a-survey-on-private-smart-contract-contruction-method-part2/bian_figure3.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">그림.3 The comparison between before and after using BiAn</td>
</tr>
</tbody>
</table>
<h1 id="eshield">EShield</h1>
<p>두 번째로 살펴볼 논문은 “EShield: Protect Smart Contracts against Reverse Engineering” 입니다. 첫번째 논문과 같이 중국 대학에서 연구한 논문입니다. EShield의 목표는 스마트 컨트렉트 난독화를 통해 리버싱 공격에 대비하여 스마트컨트렉트의 본안성을 높이는 것입니다. 실험도 첫번째 논문대비 약 2만개의 스마트 컨트렉트를 대상으로 3가지 종류의 역공학 도구(reverse engineering)에 대해서 얼마나 스마트컨트렉트를 보호할 수 있는지를 실험하였습니다. 상대적으로 첫 번째 논문대비 실험에 대한 신뢰가 높다고 할 수 있습니다. 다만 EShield의 경우 BiAn과 달리 소스코드를 공개하고 있지 않기 때문에, 실제적인 구조 및 실험결과에 대한 재검증이 어려울 것으로 판단됩니다.</p>
<h2 id="motivation--contribution">Motivation & Contribution</h2>
<p>논문에서 얘기하고 있는 Solidity 보안관련 상황을 다음과 같이 설명하고 있습니다.</p>
<ul>
<li>Erays와 같은 EVM 바이트코드를 리버싱할 수 있는 역공학 도구가 발전하고 있으며, 이러한 도구를 활용하여 정당하지 않은 이익을 얻기위한 시도가 많이 발생하고 있다.</li>
<li>그러나 이와 관련해서 기존에공개된 Anti-reversing 기술들은 비효과적이고 또한 가스비적 측면에서 비효율적이다.</li>
</ul>
<p>이러한 환경에서 역공학(reverse engineering)기술로 부터 스마트컨트렉트를 보호하기 위한 기술개발에서 사전에 풀어야할 문제를 2가지로 요약하고 있습니다.</p>
<ul>
<li>Challenge 1(Non Von Neumann Virtual Machine) : EVM은 표준 폰 노이만 구조를 따르지 않기 때문에 실행중에 코드 수정이 불가능하기 때문에, 암호화된 코드를 동적으로 복호화 하면서 실행할 수 가 없다.</li>
<li>Challenge 2(Gas Cost) : 일반적으로 난독화(Obfuscation)은 실행 코드양을 증가시킴으로 자연스럽게 이더리움 가스비의 증가로 이러진다. 지금 현재는 문제인 것은 맞는데, 만약 이더리움이 PoS체계로 전환이되면, 가스비문제는 자연스럽게 해결될 가능성도 있습니다. 하지만 지금의 이더리움에서는 높은 가스비는 난독화 기술을 적용하는데 장애물인 것은 틀림없습니다.</li>
</ul>
<p>그래서 이러난 어려움을 다 해결하고, 스마트컨트렉트의 코드 보안을 향상사킬 수 있는 기술로 이 논문에서 EShield를 제안하고 있습니다.</p>
<h2 id="proposed-model">Proposed Model</h2>
<p>Solidity 소스코드를 입력으로 받아서 난독화하여 코드 복잡도를 증가시키는 접근을 사용하는 것에 반하여, EShield의 경우에는 컴파일된 바아티코드를 입력 데이터로 사용, 이를 기반으로 난독화를 하게 됩니다.</p>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-04-28-a-survey-on-private-smart-contract-contruction-method-part2/eshield_figure1.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">그림.1 The framework of EShield</td>
</tr>
</tbody>
</table>
<p>그림 1.을 살펴보면 가장 중요한 역활을 담당하는 것은 Bytecode Analysis과 Pattern Contruct라고 할 수 있습니다. Bytescode Analysis는 입력된 바이트코드로 부터 CFG 정보를 생성해서, 이를 기반으로 anti-pattern을 삽입할 적절한 포지션을 찾아내고, Pattern Construct는 해당 위치에 삽입할 적절한 anti-pattern를 생성합니다. 이를 기반으로 Orignal Construct는 anti-pattern을 삽입할 적절한 공간을 만들고 Bytescode Reconstruct에서 제공받은 anti-pattern를 삽입하여 난독화된 컨트렉트를 만들게 됩니다.</p>
<p>여기서 우리가 가장 중요하게 봐야할 것은 Bytescode Analysis가 어떻게 적절한 anti-pattern 지점을 선정하는지, 그리고 Pattern Construct가 Byteacode Analysis가 선정한 위치에 들어갈 적절한 anti-pattern을 어떻게 생성하는지 이 두가지 포인트입니다.</p>
<h3 id="bytecode-analysis">Bytecode Analysis</h3>
<p>EShield에서 CFG를 생성하기 위해 기존에 오픈소스 <a href="https://github.com/crytic/evm_cfg_builder">evm cfg-builder</a>를 사용합니다. CFG를 만들면서 jump-pairs를 만들게 되는데, jump-pairs는 단순하게 JUMP, JUMPI 명령어와 점프 명령과 주소의 쌍을 key-value(예, 파이썬 사전형 자료구조) 형태로 저장한 것입니다. 추가적으로 3가지의 데이터를 더 추가되는데, 세가지 데이터는 다음과 같습니다.</p>
<ul>
<li>the function address of JUMP(I)</li>
<li>the position between JUMP(I) and its jump address</li>
<li>the length of jump address</li>
</ul>
<p>그리고 entry-pair라는 것도 생성하는 하는데, entry는 x86/x86에서 함수의 prologue라고 생각하면 되고 EVM에서는 EQ-PUSH-JUMPI의 패턴을 가집니다. 모든 entry 인스트럭션을 분석해서 JUMPI에 함수 주소와 함께 마킹을 한 것이 entry-pair입니다. 모든 entry-pair는 anti-pattern이 삽입되는 위치로 사용된다고 논문은 기술하고 있습니다.</p>
<h3 id="anti-pattern-construct">Anti-pattern Construct</h3>
<p>EShield에서 지원하는 anti-pattern의 종류는 4가지입니다. 각 anti-pattern을 간단하게 요약정리하면 다음과 같습니다.</p>
<ul>
<li>Pattern1: jump 주소에 대한 난독화(MSTORE/MLOAD 명령과 스택 사용)</li>
<li>Pattern2: jump 주소에 대한 난독화(SSTORE/SLOAD 명령과 스토리지 사용)</li>
<li>Pattern3: SHA3와 EShield 특수 명령조합을 통한 함수주소 난독화</li>
<li>Pattern4: 외부 스마트 컨트렉트의 함수 호출을 활용한 JUMP 주소 생성</li>
</ul>
<p>EShield의 모든 난독화 기술이 호출 흐름을 난독화하기 위한 JUMP 주소 난독만 패턴만 지원하는 것을 확인할 수 있습니다. <span style="background-color: #fff5b1">일단 단순한 접근으로 호출 주소 난독화 + BiAn의 몇가지 난독화를 합쳐도 괜찮은 난독화 도구가 될 수 있을 것 같습니다.</span> 두개의 난독화 입력이 다른데, BiAn으로 소스코드 수준에서 난독화 후 solc로 EVM 바이트 코드로 컴파일하고 이 바이트코드를 입력으로 EShield의 JUMP 주소 난독화를 한다면 괜찮은 결과를 얻을 수 있을 것 같습니다.</p>
<h3 id="original-construct">Original Construct</h3>
<p>Original constructor의 역활은 원본 바이트코드를 anti-pattern 삽입이 가능한 형태로 변경하는 역활을 담당합니다. 바이트코드 재구축은 3단계로 구성되어 있으며, 각 단계별 내용은 다음과 같습니다.</p>
<ul>
<li>If the jump address is behind the position of entry, the constructor will add extra length and the address value</li>
<li>calculate all the extra length produced by increasing length of jump address</li>
<li>calculate the change of length in other addressses : x86/x64에 대입해보면 코드 패치를 하는 중에 추가적으로 바이트가 더해졌기 때문에, 전체적으로 JUMP 오프셋이 변경됨으로 오프셋 값을 수정해주는 것과 동일한 과정입니다.</li>
</ul>
<h2 id="implementation">Implementation</h2>
<p>EShield의 구현부분은 크게 4가지로 구분되어 있으며, 그 구조는 그림 2.에 표현되어 있습니다. 개인적으로 그림 1.과 크게 다른 점은 없다고 판단되며, 그림 1. 설명에서 언급이 되었던 evm cfg-builder같은 것들이 그림으로 표현되어 있다.정도 말고는 차이점이 없다고 생각됩니다.</p>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-04-28-a-survey-on-private-smart-contract-contruction-method-part2/eshield_figure2.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">그림.2 The architecture of EShield in implementation</td>
</tr>
</tbody>
</table>
<ul>
<li>Bytecode Analyzer : evm-cfg-builder + entry detector</li>
<li>Pattern Constructor : Bytecode Analyzer로 부터 entry pairs정보를 받아 적절한 anti-pattern을 생성함</li>
<li>Original constructor : anti-pattern 삽입이 용이하게, 입력 바이트코드를 수정하는 역활을 담당</li>
<li>Bytecode Constructor : Insert the anti-patterns into the modified bytecode to replace the old entry bytecode.</li>
</ul>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-04-28-a-survey-on-private-smart-contract-contruction-method-part2/eshield_figure3.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">그림.3 EShield Screenshot</td>
</tr>
</tbody>
</table>
<h2 id="experiments">Experiments</h2>
<ul>
<li>Download 20,266 smart contracts</li>
<li>EShield generates 4 different patterns of protected bytescodes for each smart contract</li>
<li>User VM(1 vCPU, 6G RAM, Ubuntu 18.04)</li>
<li>Reverse Engineering Tools : <a href="https://github.com/teamnsrg/erays">Erays</a>, <a href="https://github.com/usyd-blockchain/vandal">Vandal</a>, <a href="https://github.com/nevillegrech/gigahorse-toolchain">Gigahorse</a> 위 도구들중 IDA Pro와 같은 상용화 도구는 없으며, 다 오픈소스이며, 학계에서 제안된 도구들입니다.</li>
<li>Matrix : Partially Failed(PF), Entirely Failed(EF)
<ul>
<li>PF : 역공학 도구들이 잘못된 결과를 출력하는 경우</li>
<li>EF : 역공학 도구들이 어떤한 결과도 출력하지 못 하는 경우(역공학 자체가 실패)</li>
</ul>
</li>
</ul>
<h2 id="evaluation-1">Evaluation</h2>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-04-28-a-survey-on-private-smart-contract-contruction-method-part2/eshield_figure4.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">표.1 Evaluation Results, P:Patterns</td>
</tr>
</tbody>
</table>
<p>표.1을 보면, Vandal, Gigahosrse를 보면 EF가 낮고, PF가 높은 것을 확인할 수 있다. 즉 부분적으로 실패했다는 것인데, 부분적으로 실패했다는 것이 정적분석기가 정상적으로 동작하지 않았다는 것을 의미함으로, 도구를 활용한 정적분석을 실패했다라고 볼 수 있다. 부분적으로 분석이 성공한 부분의 수준이 어느정도의 수준인지 분석하는 부분도 있으면 더욱 가치가 있었을 것 같은데, 그 부분에 대한 분석은 이 논문에 없었습니다. PF, EF 두 개를 더하면 100%로 임으로 그 어떤 정적분석기도 정적분석에 성공한 케이스가 없었다는 것도 의미있는 결론이라고 판단됩니다. 마지막으로 etherscan과 같은 사이트에서 제공하는 EVM 바이트 디스어셈블리 수준에서 해당 컨트렉트를 사람이 분석 가능한지에 대한 여부를 개인적으로 확인해 보고 싶은데, EShield의 경우 소스가 공개되지 않아 확인할 수 없는게 조금 아쉽습니다.</p>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images_post/2022-04-28-a-survey-on-private-smart-contract-contruction-method-part2/eshield_figure4.png" alt="Image Alt 텍스트" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">표.2 Cost of Using EShield. P:Patterns \({Extra}_{Create}\): Extra gas cost of Creating protected contract, \({Extra}_{Dollars}\): Extra cost in dollars, \({Extra}_{call}\): Extra gas cost of Calling protected contracts, \({Extra}_{Dollar}\): Extra cost in dollars, Time: average Time cost of running EShield.</td>
</tr>
</tbody>
</table>
<p>표.2에서 확인할 수 있는 사실은 일단 난독화(Obfuscation)하면 무조건 가스비가 증가한다. Pattern4 외부 컨트텍트를 활용해서 난독화하는 패턴이 가장 가스비 증가가 높다고 볼수 있지만 하지만 4가지 패턴의 수행시간 측면에서는 별 차이가 없다라고 볼 수 있습니다. 4가지 패턴중에 어는 패턴이 보안적으로 더욱 안전한가? 이 것에 대한 실험이 없는게 개인적으로 아쉬웠습니다. 보안성 대비, 가스비의 비율값을 도출할 수 있다면, 앞으로 난독화를 할 때 Complexity우선 난독화 가스비우선 난독화와 같은 다양한 모드 개발도 가능하고, 기능적 측면에서 보다 완성도 있는 도구 개발이 가능하지 않을까? 생각해봤습니다.</p>
<h1 id="conclusions">Conclusions</h1>
<p>우리는 이번 포스트에서 Solidity기반 스마트컨트렉트의 난독화관련 논문 2개를 살펴보았습니다. 첫번째 살펴본 BiAn의 경우는 소스코드 기반이였으며, 주소 난독화를 포함하여 소스코드 수준에서 난독화할 수 있는 4가지 패턴의 난독화를 사용하였습니다. 비록 논문의 목적이 난독화 자체 기술 개발이 아니라 정적분석기를 올바르게 성능평가할 수 있는 테스트 세트를 생성할 수 있는 도구개발이였지만, 소스코드 수준에서의 난독화 최초의 연구라는 점에서 의의가 있다라고 생가됩니다. 두 번째 난독화 연구는 EShield는 BiAn과 달리 EVM 바이트코드를 입력으로받아 JUMP 명령어와 관련된 주소를 난독화하는데 초점을 두고, 주소 난독화만 서로다른 4가지 패턴으로 수행하였습니다. 실험 깊이면에서는 EShield가 좀 더 많은 대상으로 실시하여, 신뢰도는 상대적으로 높아보이지만, 두 도구다 난독화 측면에서는 공개된 정적분석기를 대상으로 의미있는 결과를 도출했다고 보입니다. 앞에서도 이미 말했지만, 소스코드 난독화 BiAn와 EShield를 연결하여, 소스코드 수준에서 한 번 난독화하고, 이를 컴파일하여 바이트코드 수준에서 주소 난독화까지 한다면 강력한 난독화 도구 개발이 가능할 것으로 판단됩니다. 실제로 난독화 도구에 대한 소스분석을 통하여 아이디어 도출을 하고, 이를 바탕으로 접근하면 디스어셈블리 기반의 수동 분석에도 대응할 수 있을 것으로 판단됩니다.</p>
<h1 id="references">References</h1>
<ul>
<li><a href="https://github.com/xf97/BiAn">Source Code Obfuscation for Smart Contracts</a></li>
<li>EShield: Protect Smart Contracts against Reverse Engineering</li>
<li><a href="https://github.com/crytic/evm_cfg_builder">https://github.com/crytic/evm_cfg_builder</a></li>
</ul>PandaPrivate smart contract를 생성하는 방법에 중하나인 Solidity 코드 난독화에 대한 논문 2개를 요약정리한 글입니다.A survey on private smart contract construction method (Part1)2022-04-20T22:00:00+00:002022-04-20T22:00:00+00:00https://bears-team.github.io//security/smart%20contract/a-survey-on-private-smart-contract-contruction-method<h1 id="executive-summary">Executive Summary</h1>
<p>이 문서는 <a href="https://bears-team.github.io/system%20trading/smart%20contract/ccs-cyclic-arbitrage-in-dex-review/">Cyclic Arbitrage in Decentralized Exchanges</a> 논문에서 언급이된 smart contract의 보안성을 높인 private smart contract와 관련된 현재 공개된 기술(기법)에 대해서 조사 및 분석한 결과를 공유하는 글입니다. 글의 전체적인 흐름은 공개 <a href="https://medium.com/iovlabs-innovation-stories/private-smart-contract-execution-7df89e28eb30">Medium 블로그</a>을 요약하는 정리한 것입니다. 대상 블로그에서는 정말 간단히 Private Smart Contract관련 솔류션들을 소개하고 있고, 앞으로 추가적으로 개별 시스템에 대한 세부적인 분석 조사가 필요해 보입니다. 해당 글은 BEARS 팀 세미나에서 발표된 내용이며 BEARS팀 블록체인 스터디에 참여하고 싶으신 분들은 bears.team.kr[AT]gmail.com으로 연락주시면 감사하겠습니다.</p>
<h1 id="introudction">Introudction</h1>
<p>이 글을 읽고있는 분들이라면, 블록체인내 스카트컨트렉트의 속성으로 가장 중요한 것이 투명성이라는 것은 모두들 알고 있으리라 생각합니다. 이러한 투명성을 기반으로 DeFi와 같은 불특정 다수에 의해 금융거래 또한 가능한 것이고, 블록체인 사업이 처음에 기존 사업에 대한 차별성을 이러한 투명성을 바탕을 두고 강조하여 왔습니다. 그런데 이율배반적으로 최근에 블록체인 스마트컨트렉트 생태계에서 “Privacy” 문제가 대두되기 시작했습니다. 즉 블록체인 네트워크를 사용하는 사용자 가운데, 스마트컨트렉트의 내용을 보호하고 싶은 필요성이 생겼습니다. 간단하게 생각해볼 수 있는 예가 지난시간에 제가 정리한 <a href="https://bears-team.github.io/system%20trading/smart%20contract/ccs-cyclic-arbitrage-in-dex-review/">Cyclic Arbitrage in DEX</a> 글에 나와있는 시세차익 봇들이 좋은 예가 될 수 있습니다. 해당 봇을 운영하는 업체측에서는 자신들이 어렵게 찾아내고 개발한 알고리즘이 대중에 의해 노출되는 것은 회사의 핵심 기술을 잃어 버리는 것임으로, 해당 업체 입장에서는 블록체인의 투명성은 해당 업체관점에서는 가장 큰 위협이라고 판단할 수 있습니다.</p>
<p>스마트 컨트렉트에서의 프라이버시의 구성요소를 3가지로 구분하고 있습니다.</p>
<ul>
<li>Privacy of the specification: Private Contract(적절한 번역을 찾지 못 했음)의 소스코드는 배포, 실행, 동기화 동안 은닉되어야 한다.</li>
<li>Privacy of the execution: Private Contract의 활성화 이후, 실제 해당 컨트렉트에 대한 호출 변수 및 리턴 값들은 은닉되어야 한다.</li>
<li>Privacy of the state: Private Contract의 내부변수의 상태 값은 특히 사용자 주요 정보는 소중히 다뤄야 한다.</li>
</ul>
<p>이 후 섹션에서는 해당 블로그에서 소개하는 스마트컨트렉트 프라이버시 관련 서비스를 소개하는 내용을 정리하면서 1부 내용을 마치고, 2부에서는 BEARS 팀에서 관심을 많이 가지고 있는 기존 x86/64 시스템에서 코드 난독화(Obfuscation)와 유사한 성격을 가지고 있는 Ethereum Virtual Machine(EVM) 코드 난독화를 중심으로 관련 논문의 내용을 정리할 계획입니다. 이후 시간을 가지고 <a href="https://medium.com/iovlabs-innovation-stories/private-smart-contract-execution-7df89e28eb30">Private Smart Contract Execution</a>에서 소개하고 있느 사용 서비스들에 관해 심도 있게 조사하는 글을 작성하도록 하겠습니다.</p>
<h1 id="hawk-and-zkhawk">Hawk and zkHawk</h1>
<h2 id="hawk">Hawk</h2>
<p><a href="https://eprint.iacr.org/2015/675.pdf">Hawk</a> 원래 목적은 <a href="http://zerocash-project.org/">Zerocash 프로토콜</a>을 향상하기 위해 설계되었지만, 암호화폐내 프라이버시 트렌젝션을 위해서도 사용될 수 있습니다. Zerocash 찾아보면 <a href="https://zerocoin.org/media/pdf/ZerocoinOakland.pdf">Zerocoin</a> 연구에서 시작했으며, 소개 글을 읽어보면 익명화 비트코인 개발을 목표로 하고 있음을 알 수 있습니다. 기존에 있던 모네로(Monero)와 목적은 동일한 프로젝트라 생각이 됩니다.</p>
<p>Hawk 솔루션은 기본적인 접근은 기존의 스마트 컨트렉트를 일단 두 개로 나눕니다. 하나는 public smart contract(이하 공개 스마트컨트렉트)이고 이 스마트컨트렉트는 on-chain 즉 공개 블록체인 네트워크에서 동작하게 됩니다. 다른 하나는 private smart contract(이하 비공개 스마트컨트렉트)이며, 이 스마트컨트렉트는 독자적인 개별 네트워크에서 동작하게 됩니다. 이런 구조로 운영되는 서비스가 실제로 존재하는데 EOSIO기반으로 구현된 기관대상 거래소를 표방하고 있는 Bullish 거래소라고 할 수 있습니다. 기관들은 자기들 거래가 공개되는 것을 왜 꺼려하는지 모르겠으나, 실제 매매행위는 독립 네트워크에서 운영되며, 거래 트렌젝션의 해쉬값만 EOS 네트워크에서 검증하고 있습니다. 믈론 Hawk 프레임워크는 이 작업을 자동으로 지원해 주겠다가 주요 핵심입니다.</p>
<p>여기서 문제인 것은 비공개 네트워크에서의 검증자가 필요로 하게 됩니다. 그리고 이 검증자는 신뢰할 수 있는 대상이어야 하는 것은 당연하고, 해당 트렌젝션을 볼 수 도 있어야 합니다. 단 off-chain 네트워크의 관리자는 비공개 스마트 컨트렉트의 실행 결과에는 영향을 줘서는 안됩니다.</p>
<p>중요한 것은 이 것들을 세부적으로 어떻게 구현했는가? 인데, 이 부분에 대해서는 해당 블로그에서는 소개하지 않고 있습니다. 즉 개별 논문을 다 분석해야할 것으로 생각이 됩니다. 개별 프로토콜 논문에 대한 분석을 코드에 대한 난독화 정리가 끝나는데로 할 계획입니다. 앞으로 계속 소개되는 솔루션(프레임워크)의 내용은 위에 소개한 Hawk 수준이며, 이 번 글에서는 이런 것들이 있구나 하는 수준으로만 확인하시면 되고, 기술적인 세부사항은 이러지는 글을 통해 확인하시면 될 것 같습니다.</p>
<h2 id="zkhawk">zkHawk</h2>
<p><a href="https://eprint.iacr.org/2021/501.pdf">zkHawk</a>는 Hawk에서의 관리자 기능의 불편함을 <a href="https://en.wikipedia.org/wiki/Secure_multi-party_computation">multi-party protocol(MPC)</a>를 활용해 해결한 프로토콜입니다. 이후 여러 솔루션에서 MPC가 계속 언급이 됩니다. 또한 밸랜스 합계와 같은 기능을 블록체인내에서 증명하기 위한 알고리즘으로 \(\sigma\)-protocol과 homomorphic commitments를 사용했다라고 하는데, 이 부분에 대해서는 논문을 확인해야 정확하게 알 수 있을 것 같습니다.</p>
<p>MPC(다자간 연산)는 1982년 앤드류 야오가 두 명의 백만장자의 재산 대결이라는 문제 기반으로 처음 제시했습니다. 간단히 그 내용을 살펴보면, 백만장자 A와 B 중 누구의 재산이 더 많은지 비교할 때 자신의 재산을 직접 노출시키고 싶지 않은 경우 신뢰가 있는 제3자를 두고 확인하는게 일반적인 방법입니다. 하지만 제3자도 신뢰할 수 없는 경우는 어떻게 해야 할까요? 이때 MPC가 솔루션이 될 수 있습니다. 백만장자 A와 B가 MPC 시스템에 각각 자신의 자산을 공유하지 않고 등록하면, 시스템이 자산의 총량을 연산하여 누구의 재산의 크기가 더 큰지 출력해줍니다. 이런 경우 서로의 재산을 공개하지 않은채 원하는 결과값인 재산의 크기만을 얻을 수 있습니다. 결국 MPC 문제는 위 양자간계산(2PC) 문제를 N명으로 확대한 경우이고, 이를 해결하기 위한 알고리즘이 여러개 존재하는 것으로 알고 있습니다. 이 부분에 대해서는 추후에 좀 더 조사하도록 하겠습니다. 구글의 <a href="https://github.com/Google/private-join-and-compute">Private Join and Compute</a>도 MPC를 기반으로 한 데이터 공유 기술로 알려져 있습니다.</p>
<h1 id="enigma상용화-서비스">Enigma(상용화 서비스)</h1>
<p><a href="https://web.media.mit.edu/~guyzys/data/enigma_full.pdf">Enigma</a> 또한 위 zkHawk와 유사하게 MPC기술을 기반으로 기존의 블록체인을 보완하는 프레임워크로 알려져 있습니다. 그런데 zkHawk와 다르게 그냥 MPC가 아니라 distributed secure MPC로 소개하고 있습니다. distributed와 secure 단어가 Enigma의 특징을 잘 설명해주고 있는데, 암호화된 사용자 정보들이 작게 쪼개 비신뢰 노드에서 계산되어 그 암호화된 계산결과과 다음 단계로 진행되고 오직 사용자만이 암화화된 결과를 복호화 가능한 구조로 설계되어 있습니다.</p>
<h1 id="raziel">Raziel</h1>
<p><a href="https://eprint.iacr.org/2017/878.pdf">Raziel</a> 또한 위에서 소개한 방식과 유사한 시스템입니다. 해당 논문에서 주요 기여를 다음과 같이 소개하고 있습니다. 그냥 블로그 원분을 그대로 가져오겠습니다. 이 쪽으로 지식이 깊지 않기 때문에 세미나 참석자분들의 집단 지성을 빌리겠습니다.</p>
<ul>
<li>Practical formal verification of smart contracts: the proofs accompanying the smart contracts can be used to prove functional correctness of computations as well as other properties such as termination, invariants and any other requirements for well-behaved code.</li>
<li>The code producer can convince the executing party of the smart contract of the existence and validity of proofs about the code without revealing any actual information about the proofs themselves or the code of the smart contract.</li>
<li>A protocol for secure computation that allows offline parties and private parameter reuse.</li>
<li>Using zero-knowledge proofs to prove the validity of smart contracts before execution.</li>
</ul>
<p>그리고 Raziel역시 블록체인 네트워크를 공개/비공개 영역으로 구분하고 있고, 각 영역별 담당하는 역할 역시 위의 시스템과 유사합니다. 여기까지 보면 상용화된 서비스들이 논문으로 시작해서 사업화에 성공한 것 처럼 보이며, 개인적으로 차별화가 잘 보이지 않습니다. 다 비슷비슷해 보입니다.</p>
<h1 id="zether">Zether</h1>
<p><a href="https://crypto.stanford.edu/~buenz/papers/zether.pdf">Zether</a> 시스템은 3가지 정보를 은닉하는데 이 3가지 정보는 전송되는 자산의 크기, 송신자, 수신자입니다. 논문의 참여자의 이메일 주소내 도메인 정보 visa.com을 기반으로 생각해보면 기존 금융거래중 기관과 같이 노출을 꺼리는 대상을 염두하고 설계된 구조인 것으로 추정됩니다. Zether Smart Contract 및 Zether(ZTH)이라는 토큰을 기반으로 설계되어 있습니다. 해당 블로그에서는 기존의 Layer-1 블록체인 위에서 동작하는 Polygon과 같은 구조인지, 아니면 아예 독자적인 Layer-1 체인을 구성하는지에 대해서는 명확하게 설명하고 있지는 않습니다. 그러나 Zether 동작의 예시에서 이더리움 주소가 언급이 되는 것으로 봐서 Polygon과 같이 이더리움기반의 Layer-2가 아닐까?라는 생각이듭니다.</p>
<p>이더리움 주소 A의 사용자 A는 키쌍을 만들고, ZSC내 공개키를 동봉하여 예치할 이더와 함께 트렌젝션을 생성합니다. 그러면 ZSC는 공개키를 활용하여 익명의 계정을 하나 만들고 예치할 이더와 동일한 가치의 ZTH를 해당 계정에 민팅합니다. 사용자 A는 ZTH를 Zether계정으로 보내게 됩니다.</p>
<h1 id="zexe">Zexe</h1>
<p><a href="https://eprint.iacr.org/2018/962.pdf">Zxex</a>는 앞에서 소개한 시스템들과 본질적으로 동일합니다. off-chain에서 계산, 해당 계산의 검증은 on-chain이라는 앞의 시스템과 유사한 구조를 가지고 있습니다. 단 이 논문의 저자는 decentralized private computation(DPC)라는 것을 소개하고 있는데, 핵심은 효율적인 구현을 위해 zk-SNARK라는 최적화 알고리즘을 사용하였고, 타원곡선과 recursive proof composition을 활용하였다라고 되어 있습니다. 이 부분은 논문을 자세히 확인해야할 것 같습니다.</p>
<h1 id="zkayv1-and-v2">Zkay(v1 and v2)</h1>
<h2 id="zkay-v1">Zkay v1</h2>
<p><a href="https://files.sri.inf.ethz.ch/website/papers/ccs19-zkay.pdf">zkay</a> 논문에서 소개하는 핵심 아이디어는 사용자가 은닉변수를 정의할 수 있다, 그리고 이 변수는 public smart contract에서는 암호문 형태로 나타날 것이다.라는 겁니다. 해당 변수에 대한 업데이트는 non-interactive zero-knowledge proofs(NIZKs)를 기반으로 이뤄지게 됩니다. zkay는 자체 컴파일러는 가지고 있는데, 해당 컴파일러를 이용해서 스마트 컨트렉트를 두개로 나누게 되며 <a href="https://eprint.iacr.org/2017/540.pdf">zk-SNARK</a>기반으로 실행이 됩니다.</p>
<h2 id="zkay-v2">Zkay v2</h2>
<p>Zkay v1은 아래와 같은 한계점을 가지고 있다라고 <a href="https://arxiv.org/pdf/2009.01020.pdf">Zkay v2</a>를 소개하고 있습니다. 참고로 Zkay v2논문은 v1논문보다 훨씬 내용이 많습니다.</p>
<p>Zkay v1 한계점</p>
<ul>
<li>Insecure encryption : NIZK기반 증명을 위해 ZoKrate 프레임워크를 사용했는데, 해당 프레임워크는 실전 암호화 기능을 지원하지 않기 때문에 암호화 관련해서 미약한 점이 있다라고 소개하고 있습니다.</li>
<li>Missing integrity verification : 배포된 스마트 컨트렉트 바이트코드에 대한 증명을 지원하지 않는 한계점이 존재합니다.</li>
<li>Undefined behavior : Zkay가 트렌젝션을 변환할 때 Integer underflow/overflow에 검증이 없기 때문에 사용자가 직접 이 부분을 검증해야 한다는 단점이 존재합니다.</li>
<li>Initialization : Zkay v1은 변수들이 0으로 초기화 되어 있다라고 가정하는데, Solidity는 변수가 선언시 0으로 초기화 되어있는 것을 보장하지 않기 때문에, 초기화 되지 않은 변수는 Zkay v1내에서 예상하지 못 한 결과를 생성할 수 있습니다.</li>
</ul>
<p>그래서 위 문제를 해결하기 위해서 저자들은 아래의 기능을 Zkay v2에 추가했다라고 합니다.</p>
<ul>
<li>최신 비대칭 하이브리드(asymmetric hybrid) 암호화 기능 추가</li>
<li>함수호출과 같은 언어적인 기본적인 기능 추가(암호화폐관련 기능, 은닉 호출 흐름제어, 확장된 데이터 타입 등)</li>
<li>zk-SNARKs 프레임워크 지원, 아마도 NIZK관련인 것 같습니다.</li>
<li>손쉬운 설치과 향상된 에러 메세지</li>
<li>컴파일 소요 시간 및 on-chain 비용 감소</li>
</ul>
<h1 id="shadoweth">ShadowEth</h1>
<p><a href="https://link.springer.com/article/10.1007/s11390-018-1839-y">ShadowEth</a> 논문은 아쉽게도 Springer에 판권을 가지고 있는데 구글 검색을 하면 <a href="https://www.trustkernel.com/uploads/pubs/shadoweth.pdf">이곳</a>에서 논문 PDF를 구할 수 있습니다. ShadowEth도 앞에 소개한 것들과 크게 다르지 않습니다. 단계를 2개로 구분하고 어떤 비밀정보가 밝혀지지 않도록 공개 블록체인에서 검증을 진행한다.</p>
<p>실제 스마트컨트렉트의 로직들은 off-chain의 trusted executed environments(TEE)에서 실행된다고 합니다. 여기서 얘기하는 TEE가 ARM Cortex의 TrustZone과 같은 것을 의미하는 지는 논문에서 직접확인해야 할 것 같습니다.</p>
<p>ShadowEth는 이름에서 유추할 수 있듯이 이더리움(Ethereum) 스마트 컨트렉트를 사용합니다. 다만 스마트컨트렉트의 코드 및 데이터의 기밀성을 보장(확보)하기위해 사용자와 TEE사이에 안전한 채널을 구축해야합니다. 실제 스마트컨트렉트가 전송되기전에 암호화 되어야 하며, 정당한 권한을 지닌 수신자에 의해서만 복호화 되어야 합니다.</p>
<p>TEE는 키쌍을 생성하고, 컨트렉트네 중요 정보는 해당 공개키로 암호화되고, 정당한 사용자만 복호화 할 수 있습니다.</p>
<h1 id="ekiden">Ekiden</h1>
<p><a href="https://arxiv.org/pdf/1804.05141.pdf">Ekiden</a>는 위의 ShadowEth와 유사하게 블록체인에서 부족한 기밀성 확보를 위해 Trusted Execution Environments(TEE)를 활용하는 것을 제안하고 있습니다. 기본적인 구성은 2단계 구성으로 앞에서 설명한 모든 블록체인 해결책과 그 궤를 같이합니다. 스마트 컨트렉트의 실행은 TEE의 지원을 받아서 수행하게 되며, 이 실행이 올바르게 되었느지에 대한 검증은 on-chain에서 이뤄지게 됩니다.</p>
<p>Ekiden은 블록체인과 TEE의 하이브리드 시스템으로 소개하고 있으며, CIA를 보장한다고 주장하고 있습니다. Ekiden 시스템의 경우 3가지 구성요소를 가진다고 소개하고 있는데, 각 구성요소는 다음과 같습니다.</p>
<ul>
<li>Clients: 스마트컨트렉트의 최종 사용자를 의미합니다. 비밀 정보를 포함하고 있는 스마트컨트렉트를 생성하고 실행하는 주체이며, 스마트컨트렉트 실행에 필요한 계산을 Compute nodes에게 위임합니다.</li>
<li>Compute nodes: Client로 부터의 요청을 처리하는 부분이며, contract TEE내에서 요청받은 스마트컨트렉트를 실행합니다.</li>
<li>Consensus nodes: 합의 알고리즘을 수행하는 블록체인 네트워크를 유지하는 기능을 지원합니다. 상태 업데이트 및 TEE 증명에 대한 유효함을 확인에 대한 가장 중요한 역할을 담당합니다.</li>
</ul>
<p>블로그에서는 Ekiden의 특징으로 아래의 3가지를 언급하고 있습니다.</p>
<ul>
<li>Proof of publication: proof of publication은 검증자 E(TEE contract)와 비신뢰 증명자 P간의 상호작용적 증명을 뜻한다. 증명자 P는 제한된 횟수의 메세지를 publish(적절한 한글 단어가 생각나지 않음)할 수 있기 때문에, 공격자가 쉽게 위조하기가 어렵ㄴ다.</li>
<li>Key management: 각각의 Ekiden 컨트렉트는 키쌍과 연결되어 있으며, 또한 내부상태 암호화 및 사용자 입력 암호화를 위한 대칭키 또한 가지고 있다.</li>
<li>Atomic delivery: TEE가 실행되면 두 개의 메세지를 생성하게 됩니다. m1 메세지는 호출자에게 결과를 전달하는 것이고, m2 메세지는 블록체인의 상태를 업데이트하게 됩니다. 여기서 atomic하게 전달되는게 되는게 중요하다고 언급하면서 atomic delivery의 뜻은 m1, m2가 반드시 전달되든지, 전달되지 않았다면 전체 네트워크가 영원히 불가능하던지를 의미한다고 합니다. 즉 네트워크에 문제가 없으면 \(100%\) 반드시 전달되어야 한다는 의미입니다.</li>
</ul>
<h1 id="arbitrum">Arbitrum</h1>
<p><a href="https://www.usenix.org/system/files/conference/usenixsecurity18/sec18-kalodner.pdf">Arbitrum</a>은 미리 선정된 관리자그룹의 통제내 존재하는 분리된 Virtual Machine(VM)에서 스마트컨트렉트를 구현하게 됩니다. 조사를 해보니깐 실제로 구현되어서 동작하고 있으며 CoinMarketCap에서 토큰이 구현되어 있고, 브릿지 서비스로도 활용되고 있는 것으로 나옮니다.</p>
<p>검증과정을 위해서 bisection protocol이라는 것을 기반으로 하고 있습니다. bisection protocol에 대해서도 좀 더 자세한 분석이 필요해 보입니다. 일단 블로그 내용을 기반으로 이해를 해보면 bisection protocol은 피자를 공평하게 나누는 문제와 동일한 것 같습니다. 두 사람이 불만이 없이 피자를 나누는 방법은 피자를 자르는 사람과 피자를 나눴을 때 조작을 선택하는 사람을 구분하는 것인데, Arbitrum의 관리자 두명이 있습니다. 그리고 관리자가 증명해야할 대상이 있습니다. 참과 거짓을 두고 두 관리자가 논쟁을 시작하게 되는데, 논쟁 시작전 두 관리자가 약간의 돈을 예치합니다. 증명해야할 대상을 제안하는 쪽인 주장자(asserter)가 되고 다른 한 쪽이 도전자(challenger)가 됩니다. 주장자는 논쟁을 2개로 나눌수 있고, 도전자는 2개로 나눠진 논쟁중에서 하나를 선택할 수 있습니다. 이런 식으로 더 이상 논쟁을 나눌수 없을 때까지 진행하고, 마지막으로 도전자가 선택한 논쟁을 검증자가 검증을 하게됩니다. 만약에 검증결과가 참이되면 주장자가 이기게 되는 것이고 반대의 경우에는 도전자가 이기게 됩니다. 이긴사람은 자기가 예치한 돈을 가져올 수 있고, 또한 진 쪽의 예치금도 절반 가져올 수 있습니다. 진 사람의 나머지 반 예치금은 검증가가 가져가게 됩니다.</p>
<p>위 알고리즘의 경우 참여자가 제한되기 때문에 관리자중 한 사람은 무조건 올바르지 않으면 전체 프로토콜이 무너질 수 있습니다.</p>
<p>여기서 쟁점, 논쟁이 추상적인 개념인데, 이게 코드로는 무엇인지를 확인하는 과정이 필요할 것 같습니다. Arbitrum 프로토콜 시스템에서 필요한 4가지 역할(구성요소)를 살펴보고 다음과 같습니다.</p>
<ul>
<li>Verifier: 증명기능을 담당하는 전역 객체(Global Entity)이라고 설명하고 있는데, Global Entity 어떤 의미인지 정확하게 확인이 필요해 보입니다. 검증자는 중앙화된 객체가 될 수 도 있고 다중그룹 합의 시스템(비트코인, 이더리움의 마이너를 의미하는 것 같음)이 될 수 도 있습니다.</li>
<li>Key: 프로토콜에서 유동성(화폐, currency)를 보유하고 있으면서 트렌젝션을 제안하는 참가자로 공개키의 해쉬값을 이용한 ID를 사용합니다. 공개키와 대응된 비밀키로 서명한 트렌젝션을 제안합니다.</li>
<li>Virtual Machine(VM): 프로토콜내의 가상 참여자이다.라고 기술되어 있는데 너무 추상적으로 설명하고 있는 것 같습니다. 모든 VM은 자신만의 코드와 데이터를 가지고 있으면, 해당 코드에 기술된 기능을 수행한다고 합니다. 일종의 특별한 트렌젝션으로 생성하고, 자신만의 화폐(currency)를 가지고 있으며 메세지와 이 화폐를 주고 받는다고 합니다.</li>
<li>Manager: 관리자 그룹은 VM의 진행상황을 모니터링하는 집단을 의미합니다. VM이 만들어지면 해당 VM의 트렌젝션은 관리자집단을 지정하게 됩니다. 각 매니저들은 자신들의 공개키를 기반으로 식별됩니다.</li>
</ul>
<h1 id="kachina">Kachina</h1>
<p><a href="https://eprint.iacr.org/2020/543.pdf">Kachina</a>은 Universial Composability(UC)를 기반으로한 이론적인 시스템입니다. 기본적인 개념을 제안하는 논문이라고 보면되고, 이를 실제로 확장해서 구현한 것이 Zkay라고 보면 됩니다. Zkay와 내용이 대동소이함으로 내용 요약은 스킵하겠습니다.</p>
<h1 id="conclusions">Conclusions</h1>
<p>이 블로그에서 소개하는 시스템들은 우리 학습팀의 관심범위를 벗어나는 것이 아닌가 생각이 들며, 거의 구성자체가 별도의 네트워크 환경을 구축하는 수준이라서 조금 당황스럽습니다.</p>
<p><a href="https://bears-team.github.io/system%20trading/smart%20contract/ccs-cyclic-arbitrage-in-dex-review/">Cyclic Arbitrage in Decentralized Exchanges</a>에서 Private Smart Contract를 보고 단순 Solidity 코드의 난독화 정도 생각한 것이 오판이였습니다. Arbitrages 봇을 제작해서 저런 서비스를 사용한다면, 해당 서비스 사용비용까지 포함하여 수익을 창출해야 할 것 같습니다. 생각해보면 코드 난독화라는 것이 시간을 지연할 뿐, 실제적으로 가독화를 애초에 못 하게하는 개념이 아니기 때문에 위 시스템처럼 암화화를 통해 기밀성을 확보하면 확실하게 시세차익 봇의 핵심 알고리즘을 지킬 수 있지 않을까? 싶습니다.</p>
<p>그리고 위 시스템들의 제출 학회를 보면 CCS, USENIX같이 보안쪽으로 Top수준에 제출된 논문인 것을 확인할 수 있으며, 블록체인내에서의 기밀성 확보가 핵심 시버시가 될 것 같은 개인적인 느낌을 받았습니다. 블록체인에서의 검증 기능의 힘만 빌리고 내부 내용은 보호하고 싶은 사람의 욕구는 분명히 존재하기 때문에, 소스코드가 공개되어 있는 모델을 기반으로 심도 있는 분석을 하는 것도 저희 팀에 도움이 될 것 같습니다.</p>
<p>이 후 파트에서는 Solidity 난독화관련 논문에 대한 리뷰를 진행할 계획이며, 난독화도 어떻게 얼마나 복잡하게 하느냐에 따라 분석자를 포기하게 만들어 어느 정도 수준의 기밀성을 확보할 수 있다고 생각합니다. x86/x64에서의 Themida같은 패커를 생각해보면 충분히 납득하실 수 있을 겁니다.</p>
<h1 id="references">References</h1>
<ul>
<li><a href="https://medium.com/iovlabs-innovation-stories/private-smart-contract-execution-7df89e28eb30">https://medium.com/iovlabs-innovation-stories/private-smart-contract-execution-7df89e28eb30</a></li>
<li><a href="https://arxiv.org/pdf/2104.09180.pdf">https://arxiv.org/pdf/2104.09180.pdf</a></li>
<li><a href="https://eprint.iacr.org/2015/675.pdf">Hawk: The Blockchain Model of Cryptography and Privacy-Preserving Smart Contracts</a></li>
<li><a href="https://eprint.iacr.org/2021/501.pdf">zkHawk: Practical Private Smart Contracts from MPC-based Hawk</a></li>
<li>Source Code Obfuscation for Smart Contracts</li>
<li>EShield: Protect Smart Contracts against Reverse Engineering</li>
<li><a href="https://github.com/eth-sri/zkay">https://github.com/eth-sri/zkay</a></li>
<li><a href="https://www.bao-bab.co.kr/column_board/154887">Arbitrum 브릿지 사용법</a></li>
</ul>PandaPrivate smart contract를 생성하는 방법에 대한 정리한 공개블로그 내용을 살펴봄으로써 Private smart contract관련 추가적인 조사 소요를 확인해보는 글