.then((gasEstimate) => {
   const { sellHowMuchAbsolute, sellWhichTokenAddress, buyHowMuchAbsolute, buyWhichTokenAddress, userHigherId } =
     Offers.offerContractParameters(sellHowMuch, sellWhichToken, buyHowMuch, buyWhichToken);
   Dapple['maker-otc'].objects.otc.offer['uint256,address,uint256,address,uint256,bool'](sellHowMuchAbsolute, sellWhichTokenAddress,
     buyHowMuchAbsolute, buyWhichTokenAddress, userHigherId, true,
     { gas: Math.min(gasEstimate[0] + 500000, gasEstimate[1]) }, (error, tx) => {
       callback(error, tx);
       if (!error) {
         Offers.updateOffer(tx, sellHowMuchAbsolute, sellWhichTokenAddress, buyHowMuchAbsolute, buyWhichTokenAddress,
           web3Obj.eth.defaultAccount, Status.PENDING);
         Transactions.add('offer', tx, { id: tx, status: Status.PENDING });
       }
     });
 })
Offers.newOfferGasEstimate = async (sellHowMuch, sellWhichToken, buyHowMuch, buyWhichToken) => {
  const { sellHowMuchAbsolute, sellWhichTokenAddress, buyHowMuchAbsolute, buyWhichTokenAddress, userHigherId } =
    Offers.offerContractParameters(sellHowMuch, sellWhichToken, buyHowMuch, buyWhichToken);

  const data = Dapple['maker-otc'].objects.otc.offer['uint256,address,uint256,address,uint256,bool'].getData(sellHowMuchAbsolute, sellWhichTokenAddress,
    buyHowMuchAbsolute, buyWhichTokenAddress, userHigherId, true);

  const latestBlockPromise = Offers.getBlock('latest');
  const estimateGasPromise = new Promise((resolve, reject) => {
    web3Obj.eth.estimateGas({ to: Dapple['maker-otc'].environments[Dapple.env].otc.value, data }, (error, result) => {
      if (!error) {
        resolve(result);
      } else {
        reject(error);
      }
    });
  });

  return Promise.all([estimateGasPromise, latestBlockPromise]).then((results) => [results[0], results[1].gasLimit]);
};