337:         /// @dev Fee logic added on taker trades
338:         uint256 fee = mul(spend, feeBPS) / 100_000;
339:         require(
340:             _offer.buy_gem.transferFrom(msg.sender, feeTo, fee),
341:             "Insufficient funds to cover fee"
342:         );
343: 
344:         // taker pay maker 0_0
345:         if (makerFee() > 0) {
346:             uint256 mFee = mul(spend, makerFee()) / 100_000;
347: 
348:             /// @dev Handle the v1 -> v2 migration case where if owner == address(0) we transfer this fee to _offer.recipient
349:             if (_offer.owner == address(0) && getRecipient(id) != address(0)) {
350:                 require(
351:                     _offer.buy_gem.transferFrom(
352:                         msg.sender,
353:                         _offer.recipient,
354:                         mFee
355:                     ),
356:                     "Insufficient funds to cover fee"
357:                 );
358:             } else {
359:                 require(
360:                     _offer.buy_gem.transferFrom(msg.sender, _offer.owner, mFee),
361:                     "Insufficient funds to cover fee"
362:                 );
363:             }
364: 
365:             emit emitFee(
366:                 bytes32(id),
367:                 msg.sender,
368:                 _offer.owner,
369:                 keccak256(abi.encodePacked(_offer.pay_gem, _offer.buy_gem)),
370:                 _offer.buy_gem,
371:                 mFee
372:             );
373:         }
578:     function calcAmountAfterFee(
579:         uint256 amount
580:     ) public view returns (uint256 _amount) {
581:         require(amount > 0);
582:         _amount = amount;
583:         _amount -= mul(amount, feeBPS) / 100_000;
584: 
585:         if (makerFee() > 0) {
586:             _amount -= mul(amount, makerFee()) / 100_000;
587:         }
588:     }
Logs:
  Bob BTC balance: 225000000000000
function test_RubiconMarket_buy_IncorrectFeeInclusivity() public {
    // Alice has 30k USDC, bob has 1 BTC
    USDC.mint(alice, 30_000 ether);
    BTC.mint(bob, 1 ether);

    // Alice creates the offer to sell USDC for BTC
    vm.prank(alice);
    USDC.approve(address(market), type(uint256).max);
    vm.prank(alice);
    bytes32 id = market.make(
        USDC, // pay
        BTC, // buy
        30_000 ether, // pay_amount
        1 ether // buy_amount
    );

    // Bob trades his BTC for USDC
    vm.prank(bob);
    BTC.approve(address(market), type(uint256).max);
    vm.prank(bob);
    market.buy(uint256(id), 30_000 ether);

    console.log("Bob BTC balance:", BTC.balanceOf(bob));
}
result = amount / (100% + protocol fee + maker fee)
