Using `batchOffer()` and `batchQuote()` functions malicious user can disrupt the whole order book in his benefit and can drain the whole contract balance.
Audit: 2023-04-rubicon-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2023-04-rubicon/blob/511636d889742296a54392875a35e4c0c4727bb7/contracts/RubiconMarket.sol#L887-L933


# Vulnerability details

## Impact
Both the `batchOffer()` and `batchRequote()` function use the `this.offer()` to create the offer but the problem with that is this changes the context of msg.sender and owner and recipient for those offers is set to contract address itself, so a malicious user can create multiple orders in orderbook using the assets availible in the contract itself, by listing them for pennies user can take away all the balance of the contract.

## Proof of Concept
By calling the function like `this.offer()` in following code, developer what i assume is wanted to call the offer function of this contract instead of parent but in solidity this works different from other OOP languages and even this intuition was unnecessary as signature of child offer meant to be called here is different from the parents one that take 6 args.

So in this case msg.sender that goes into the offer function is set to address(this) that is contract address. So this offer function than calls the https://github.com/code-423n4/2023-04-rubicon/blob/511636d889742296a54392875a35e4c0c4727bb7/contracts/RubiconMarket.sol#L761
function and the offer is created with the msg.sender as the contract address so now offer is created in the order book using the contracts itself balance that belongs to other users held in escrow.

Now malicious user fills all those orders( that can be listed for either free or pennies) and get away with whole contract balance.

And no one can now cancel these orders even the user that created them.



```
    // *** Batch Functionality ***
    /// @notice Batch offer functionality - multuple offers in a single transaction
    function batchOffer(
        uint[] calldata payAmts,
        address[] calldata payGems,
        uint[] calldata buyAmts,
        address[] calldata buyGems
    ) external {
        require(
            payAmts.length == payGems.length &&
                payAmts.length == buyAmts.length &&
                payAmts.length == buyGems.length,
            "Array lengths do not match"
        );
        for (uint i = 0; i < payAmts.length; i++) {
            this.offer(
                payAmts[i],
                ERC20(payGems[i]),
                buyAmts[i],
                ERC20(buyGems[i])
            );
        }
    }

    function batchRequote(
        uint[] calldata ids,
        uint[] calldata payAmts,
        address[] calldata payGems,
        uint[] calldata buyAmts,
        address[] calldata buyGems
    ) external {
        for (uint i = 0; i < ids.length; i++) {
            cancel(ids[i]);
            this.offer(
                payAmts[i],
                ERC20(payGems[i]),
                buyAmts[i],
                ERC20(buyGems[i])
            );
        }
    }

```

## Tools Used
Manual Review
## Recommended Mitigation Steps
instead of using `this.offer(