code4rena-2021-06-pooltogether-h05

[H-05] IdleYieldSource doesn’t use mantissa calculations

보고서

Summary

부동소수점으로 처리하지 않아 _tokenToShares 나눗셈 결과가 0이 나오면 토큰을 예치해도 share를 받을 수 없다.

Keyword

floating point, mantissa calculation, division, arithmetic error, calcutation, rounding error

Vulnerability

부동소수점으로 계산하지 않았기 때문에 _tokenToShares 함수와 _sharesToToken 함수가 0을 리턴할 수 있다.

  function _tokenToShares(uint256 tokens) internal view returns (uint256 shares) {
    shares = (tokens * ONE_IDLE_TOKEN) / _price();
  }
 
  function _sharesToToken(uint256 shares) internal view returns (uint256 tokens) { 
    tokens = (shares * _price()) / ONE_IDLE_TOKEN;
  }

_sharesToToken 함수는 토큰을 입출금할 시 영수증 토큰을 얼마나 mint 또는 burn할지를 계산한다. 만약 나눗셈 결과로 0이 나온다면 토큰을 입금했음에도 영수증 토큰을 받지 못하게 된다.

    function supplyTokenTo(uint256 mintAmount, address to) external nonReentrant override {
        uint256 mintedTokenShares = _tokenToShares(mintAmount);
        _depositToIdle(mintAmount);
        _mint(to, mintedTokenShares);
        emit SuppliedTokenTo(msg.sender, mintedTokenShares, mintAmount, to);
    }
 
    /// @notice Redeems tokens from the yield source from the msg.sender, it burn yield bearing tokens and return token to the sender.
    /// @param redeemAmount The amount of `token()` to withdraw.  Denominated in `token()` as above.
    /// @return redeemedUnderlyingAsset The actual amount of tokens that were redeemed.
    function redeemToken(uint256 redeemAmount) external override nonReentrant returns (uint256 redeemedUnderlyingAsset) {
        uint256 redeemedShare = _tokenToShares(redeemAmount);
        _burn(msg.sender, redeemedShare);
        redeemedUnderlyingAsset = IIdleToken(idleToken).redeemIdleToken(redeemedShare);        
        IERC20Upgradeable(underlyingAsset).safeTransfer(msg.sender, redeemedUnderlyingAsset);
        emit RedeemedToken(msg.sender, redeemedShare, redeemAmount);
    }

Impact

토큰을 예치해도 share를 받을 수 없다.

Mitigation

동일 프로젝트의 다른 컨트랙트 구현(ATokenYieldSource)처럼 부동소수점(mantissa calculation)을 이용한다.


tags: bughunting, pooltogether, smart contract, solidity, arithmetic error, rounding error, severity high