Dex Two

Drain all funds from the DexTwo contract, which uses a slightly different price calculation but is still vulnerable.

Vulnerable Code
Analyze the Solidity code below to find the vulnerability.
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/utils/math/SafeMath.sol"; // Identical Dex contract as Dex 1, but potentially different tokens contract DexTwo { using SafeMath for uint; address public token1; address public token2; address owner; // Implicit Ownable constructor(address _token1, address _token2) { token1 = _token1; token2 = _token2; owner = msg.sender; } // Functions like approve, addLiquidity, setTokens are assumed similar to Dex 1 // Slightly different price calculation (uses 'from' balance in numerator) function getSwapAmount(address from, address to, uint amount) public view returns(uint){ // Example: price = (amount * balance_from) / balance_to <-- Different! return((amount * IERC20(from).balanceOf(address(this))).div(IERC20(to).balanceOf(address(this)))); } // Swaps tokens using the new price calculation function swap(address from, address to, uint amount) public { require(IERC20(from).transferFrom(msg.sender, address(this), amount), "TransferFrom failed"); uint swapAmount = getSwapAmount(from, to, amount); require(IERC20(to).balanceOf(address(this)) >= swapAmount, "Insufficient balance"); require(IERC20(to).transfer(msg.sender, swapAmount), "Transfer failed"); } } // Additional Twist for DexTwo: // The vulnerability often involves introducing a *third*, malicious ERC20 token // that the attacker controls fully.
Submit Explanation
Explain the vulnerability and how to exploit it.
Hints (4)
Just a little peak
Hint 1
Hint 2
Hint 3
Hint 4
Explanation
Discomfort = Learning