sherlock-audit / 2024-03-goat-trading-judging

3 stars 2 forks source link

Thanos - Missing check if address (to) in burn function is authorized to redeem _weth/_token. #71

Closed sherlock-admin2 closed 8 months ago

sherlock-admin2 commented 8 months ago

Thanos

high

Missing check if address (to) in burn function is authorized to redeem _weth/_token.

Summary

The burn function missing check that address (to) has indeed Liquidity. This allows anyone to call the function and potentially steal _weth and _token.

https://github.com/sherlock-audit/2024-03-goat-trading/blob/main/goat-trading/contracts/exchange/GoatV1Pair.sol#L191-L217

Vulnerability Detail

the vulnerability in burn function that allow any one to pass his address (to) to get free tokens _weth/_token this is because burn function doesn't check if address (to) has indeed provided liquidity so it just calculate the amountWeth/amountToken and checks if (amountWeth == 0 || amountToken == 0) if this condition pass it transfers amountWeth/amounToken to address (to).

    // @audit missing check if address(to) is allowed to get _weth/_token.
    function burn(address to) external returns(uint256 amountWeth, uint256 amountToken) {
        uint256 liquidity = balanceOf(address(this));

        // initial lp can bypass this check by using different
        // to address so _lastPoolTokenSender is used
        if (_vestingUntil == _MAX_UINT32) revert GoatErrors.PresalePeriod();

        uint256 totalSupply_ = totalSupply();
        amountWeth = (liquidity * _reserveEth) / totalSupply_;
        amountToken = (liquidity * _reserveToken) / totalSupply_;
        if (amountWeth == 0 || amountToken == 0) {
            revert GoatErrors.InsufficientLiquidityBurned();
        }

        _updateFeeRewards(to);
        _burn(address(this), liquidity);

        // Transfer liquidity tokens to the user
        // @audit it transfers amountWeth/amountToken to address(to)
        IERC20(_weth).safeTransfer(to, amountWeth);
        IERC20(_token).safeTransfer(to, amountToken);

        uint256 balanceEth = IERC20(_weth).balanceOf(address(this));
        uint256 balanceToken = IERC20(_token).balanceOf(address(this));

        _update(balanceEth, balanceToken, true);
        emit Burn(msg.sender, amountWeth, amountToken, to);
    }

Impact

Attackers can exploit this vulnerability to steal _weth and _token, this will damage the protocol and cause losing funds.

Code Snippet

Tool used

Manual Review

Recommendation

add a mechanism to check if address (to) indeed has the right to redeem _weth/_token from the pool if not revert.