Is it possible for a smart contract to fill a 0x order by itself as a taker? If then, how to achieve it?


Is it possible for a smart contract to fill a 0x order by itself as a taker? If then, how to achieve it?


Yep, a smart contract can call any public function in the Exchange contract. It would look something like this: IExchange(exchangeAddress).fillOrder(order, order.takerAssetAmount, signature);


But doesn’t the taker have to sign the order? If then how can a smart contract sign it?


The taker does not have to sign the order. In 0x v2 there are options where the taker can sign an order so that it can be submitted by a different sender, but being the account that calls Exchange.fillOrder() is generally sufficient to prove you wanted to fill the order.

function fill(address[6] addresses, uint[12] values, uint8[2] v, bytes32[2] r, bytes32[2] s) onlyOwner {
    EXCHANGE = IExchange(0x479cc461fecd078f766ecc58533d6f69580cf3ac);
    Token token = Token(0xc778417e063141139fce010982780140aa0cd5ab);
    token.approve(0x4e9aad8184de8833365fea970cd9149372fdf1e6, MAX_UINT);
    address[5] memory orderAddresses = [
        addresses[0], // maker
        addresses[1], // taker
        addresses[2], // makerToken
        addresses[3], // takerToken
        addresses[4] // feeRecepient
    uint[6] memory orderValues = [
        values[0], // makerTokenAmount
        values[1], // takerTokenAmount
        values[2], // makerFee
        values[3], // takerFee
        values[4], // expirationTimestampInSec
        values[5]  // salt
    uint fillTakerTokenAmount = values[6];
    EXCHANGE.fillOrder(orderAddresses, orderValues, fillTakerTokenAmount, true, v[0], r[0], s[0]);

I am not sure what I am doing wrong here.


That looks pretty correct (though I’m a bit unclear on what some of the extra arguments to your fill() function are for).

You’re using the Ropsten exchange addresses. I assume your contract is deployed to Ropsten?

The other thing that jumps out at me is that you’ve hard coded the token for approvals to be Ropsten WETH - are you sure the order you’re attempting to fill has WETH as the taker token?

Some other things to check:

  • Does your contract hold the WETH tokens you’re trying to trade?
  • You also need to double check things like fees - does the order you’re attempting to fill require fees? If so, does your contract hold ZRX, and has it set allowances?
  • Is the order you’re trying to fill expired?
  • Does the maker have the required tokens (maker token and fee token) to be able to fill the order?

Lastly, that “true” you have in fillOrder() tells it to revert the transaction if the order cannot be filled. Try setting that to false, and it will emit an event with some indication of why the transfer failed.


Thank you for helping out. I am using v1 smart contracts.
Yes, it’s deployed on ropsten.
Yes, it has WETH as the taker token, I had tested the addressed by filling the order using metamask wallets, the transfer happened fine.

  1. Yes, It holds the WETH tokens.
  2. It doesn’t require fees.
  3. Yes the maker has required tokens.
    In V1, the true value stands for “shouldThrowOnInsufficientBalanceOrAllowance”.


Hey, It worked at last, there was an issue with the signature argument. Thanks for the help.