sherlock-2025-04-burve-m04

[M-04] The value of each closure is not the same, and the same ValueToken cannot be used for all cids

보고서

Summary

ValueTokenFacet 에서 mint, burn 함수로 발행하는 ValueToken은 클로저의 종류와 무관하게 동일한 ERC20이다. 이로 인해 공격자가 저가 클로저(가격이 떨어진 클로저)에 유동성을 추가하여 ValueToken을 얻고, 고가 클로저에서 유동성을 인출하여 더 가치 있는 토큰을 얻을 수 있다.

Keyword

depegging, crypto theft, defi, erc20

Vulnerability

유저는 mint 함수를 이용하여 클로저 예치금을 유동화(토큰화)할 수 있다. 또한 burn 함수를 이용하여 다시 입금할 수 있다. 이때 처음 예치했던 클로저와 다시 입금한 클로저는 서로 다를 수 있다. 단, 클로저를 변경하고 싶다면 옮기고자 하는 클로저에서 토큰화한 사용자가 있어야 한다(빈 자리가 있어야 한다).

    function mint(uint256 value, uint256 bgtValue, uint16 _cid) external {
        require(bgtValue <= value, InsufficientValueForBgt(value, bgtValue));
        ClosureId cid = ClosureId.wrap(_cid);
        Closure storage c = Store.closure(cid); // Validates cid.
        c.unstakeValue(value, bgtValue);
        Store.assets().remove(msg.sender, cid, value, bgtValue);
        _mint(msg.sender, value);
    }
 
    function burn(uint256 value, uint256 bgtValue, uint16 _cid) external {
        require(bgtValue <= value, InsufficientValueForBgt(value, bgtValue));
        _burn(msg.sender, value);
        ClosureId cid = ClosureId.wrap(_cid);
        Closure storage c = Store.closure(cid); // Validates cid.
        c.stakeValue(value, bgtValue);
        Store.assets().add(msg.sender, cid, value, bgtValue);
    }

프로토콜은 한 토큰의 가격이 폭락하더라도 해당 토큰을 포함하는 클로저에 유동성을 추가하지 않은 사용자에게는 영향을 미치지 않기를 원한다. 하지만 이러한 가치 설계 하에서는 실현 불가능하다.

예를 들어, 사용자 A가 15개의 토큰에 유동성을 추가했지만 aBTC 토큰은 추가하지 않았다고 가정하자. 이후 aBTC가 급락하더라도 사용자 A에게는 영향을 미치지 않아야 한다. 그러나 다른 클로저의 사용자들은 사용자 A가 위치한 클로저의 유동성으로 교환하기 위해 ValueToken을 이용할 수 있으며, 이는 그들의 손실을 피하기 위한 것이다. 이 손실은 사용자 A와 같은 사용자들이 부담하게 된다.

세 개의 클로저(ETH <> aETH, ETH <> bETH, ETH <> cETH )가 있다고 가정하자. 각 토큰의 가격은 1000 USD로 동일하다고 하자.

  1. Alice가 첫번째 클로저에 1 ETH 와 1 aETH 입금
  2. Bob이 두번째 클로저에 1 ETH 와 1 bETH 입금
  3. Charlie가 두번째 클로저에 1 ETH 와 1 bETH 입금
  4. Danny가 세번째 클로저에 1 ETH 와 1 cETH 입금
  5. Charlie가 세번째 클로저로 이동하고 싶다. 따라서 ValueToken으로 변환한다.
  6. aETH가 디페깅되어 500 USD로 가격이 떨어졌다. Alice는 손해를 피하기 위해 ValueToken을 통해 두번째 클로저로 이동한다. Charlie가 ValueToken으로 나갔으므로 Alice가 들어올 수 있다.
  7. Alice 와 Bob 이 1 ETH 와 1 bETH를 출금한다.
  8. Danny가 1 ETH 와 1 cETH를 출금한다.
  9. 페깅이 회복되지 않고, Charlie가 출금하기 위해서는 첫번째 클로저로 이동하여 1 ETH 와 1 aETH을 출금할 수밖에 없다. 이는 1500 USD 가치를 가지며, Charlie가 처음 입금했던 가치인 2000 USD(1 ETH 와 1 bETH) 보다 적다. 즉 Charlie가 손해를 부담한다.

Impact

공격자가 아무 비용 없이 예치된 토큰을 훔칠 수 있다. 유동성 공급자가 손해를 보게 된다.

Mitigation

속한 클로저마다 서로 다른 ValueToken 을 발행한다.

Memo

에스컬레이션 논쟁이 좀 있었다. 클로저 사이를 이동하는 것은 의도된 기능이기 때문이다. 일반적인 경우 차익거래를 통해 페깅이 곧 회복되지만, 해킹등으로 인해 디페깅이 너무 크게 된다면 가격이 돌아오지 않을 수 있다는 점을 감안하여 평가하였다.

공격 시나리오가 발생할 수는 있지만 조건을 타고, 디페그가 회복되지 않는다는 가정을 했을 때 위험하므로 특수한 경우라고 보았다. 따라서 High가 아니라 Medium으로 분류했다.


tags: bughunting, burve, smart contract, solidity, severity medium, solo issue, erc20, depegging, defi, crypto theft