sherlock-2025-04-burve-m01

[M-01] User can backrun an admin calling setEX128 and steal the difference in tokens

보고서

Summary

관리자 함수 setEX128로 가격 계산에 사용되는 esX128를 변경했을 때, 또한 가격 계산에 사용되며 영향을 받는 클로저 목표 잔고액 targetX128 변수를 함께 업데이트 하지 않았다. 이로 인해 가격이 잘못 계산된다. 관리자 함수를 백러닝하여 바로 공격 트랜잭션을 보내면 토큰을 탈취하는 등의 공격이 가능하다.

Keyword

backrunning, arithmetic error, dex, crypto theft, admin function

Vulnerability

setEX128 함수는 esX128를 변경하는 관리자 함수이다. 각 토큰의 효율성 계수를 설정한다. 그런데 targetX128는 업데이트 하지 않는다.

function setEX128(uint8 idx, uint256 eX128) internal {
    Simplex storage s = Store.simplex();
@>  s.esX128[idx] = eX128;
    s.minXPerTX128[idx] = ValueLib.calcMinXPerTX128(eX128);
}

각 토큰의 가치 v를 계산하는 공식은 (e+2)t − (e+1)^2 * t^2 / (x + et) 이다. e는 각 토큰의 효율성 계수(esX128)이고, t는 각 클로저의 target balance(해당 클로저가 목표로 하는 잔고, targetX128)이다.

균형 잡힌 풀을 유지하려면 모든 토큰(n개)의 가치 v의 합이 targetX128 * n 과 같아야 한다. 하지만 관리자 함수로 변경 시 esX128 만 업데이트 되고 targetX128는 업데이트 되지 않으므로 차이가 발생한다.

이렇게 발생한 가격 차이를 이용하여 공격을 할 수 있다.

  1. removeTokenForValue 를 호출하여 초과 토큰(원래라면 Reserve로 옮겨져야 할)을 훔칠 수 있음
  2. addTokenForValue를 호출하여 차액만큼을 무료로 예치할 수 있음
function removeTokenForValue( // 소각해야 하는 share의 양을 계산
    Closure storage self,
    VertexId vid,
    uint256 amount,
    uint256 bgtPercentX256,
    SearchParams memory searchParams
) internal returns (uint256 value, uint256 bgtValue, uint256 tax) {
    ...
@>   self.balances[idx] -= taxedRemove; // 공격자가 특정 값을 amount로 넣어 newTargetX128 가 현재 targetX128와 일치하도록 한다.
    uint256 newTargetX128;
    {
        (uint256[] memory mesX128, uint256[] memory mxs) = ValueLib
            .stripArrays(self.n, esX128, self.balances);
@>      newTargetX128 = ValueLib.t( // 현재의 targetX128 와 일치하게 맞춤
            searchParams,
            mesX128,
            mxs,
            self.targetX128 // TODO: Add better starting estimate logic
        );
    }
    // The pool is now entirely correct by just updating the target and value balances.
@>  uint256 valueX128 = ((self.targetX128 - newTargetX128) * self.n); // newTargetX128 와 targetX128 가 일치하므로 유저는 아주 작은 금액만 사용하여 초과 토큰을 인출할 수 있음
    value = valueX128 >> 128;
    if ((value << 128) > 0) value += 1; // We need to round up.
    ...
}

관리자가 setEX128를 호출했을 때 백러닝하여 removeTokenForValueaddTokenForValue를 호출해 공격한다.

Impact

초과 토큰을 Reserve로 이동하는 대신 공격자가 탈취할 수 있다. 프로토콜측이 손해를 보는 차익거래 기회가 발생한다. 풀이 잠재적으로 불안정해진다.

Mitigation

setEX128 함수에서 e를 변경하면 즉시 잔고를 조정하여 targetX128를 유지한다. e를 증가시켰을 시 해당 값만큼을 Reserve로 이동한다. e를 감소시켰을 시 추가 토큰을 넣는다. 또는 targetX128를 함께 업데이트한다.

Memo

토큰을 탈취할 수 있으므로 이슈의 심각도는 높지만, 관리자 함수가 호출되는 일이 흔하지 않을 것으로 보아 Medium으로 판정했다.


tags: bughunting, burve, smart contract, solidity, severity medium, backrunning, arithmetic error, dex, crypto theft