# Reposting an offer in the posthook

In the [smart offer tutorial](https://docs.mangrove.exchange/dev/strat-lib/getting-started/post-a-smart-offer) the offer was fully taken by the taker at the end.

In case an offer is [partially taken](https://docs.mangrove.exchange/dev/quick-links/glossary#maker-partial-fill), the maker may want to repost a new offer for the residual.

### Repost in posthook[​](https://old.docs.mangrove.exchange/developers/strat-lib/guides/howToResidual#repost-in-posthook) <a href="#repost-in-posthook" id="repost-in-posthook"></a>

In the tutorial, the [posthook](https://docs.mangrove.exchange/dev/getting-started/post-a-smart-offer#emit-in-posthook) emitted an event. However, since reposting is such a common action, it is already implemented for the simple cases - if you invoke `super` like below, then the base implementation of [`__posthookSuccess__`](https://docs.mangrove.exchange/dev/technical-references/api-preferences/strats/src/strategies/mangroveoffer#posthooksuccess) will repost the residual.

OfferMakerTutorial.sol

```
  function __posthookSuccess__(MgvLib.SingleOrder calldata order, bytes32 makerData)
    internal
    virtual
    override
    returns (bytes32)
  {
    emit OfferTakenSuccessfully(42);
    // repost offer residual if any
    return super.__posthookSuccess__(order, makerData);
  }
}
```

[See entire file on GitHub](https://github.com/mangrovedao/mangrove-strats/blob/508bc8ace7f1d2ab54397611875306dc1ec31754/src/toy_strategies/offer_maker/tutorial/OfferMakerTutorialResidual.sol#L90-L100)

When writing posthooks to repost residuals there are both caveats and points to be aware:

* Use [`_updateOffer`](https://docs.mangrove.exchange/dev/technical-references/api-preferences/strats/src/strategies/offer_maker/abstract/direct#updateoffer) instead of posting a new offer. The old offer is not alive and can be reused (and the storage is possibly hot during the execution of the offer logic), this is [cheaper](https://docs.mangrove.exchange/dev/strat-lib/guides/determining-gas-requirements) than using [`_newOffer`](https://docs.mangrove.exchange/dev/technical-references/api-preferences/strats/src/strategies/offer_maker/abstract/direct#newoffer).
* Use the helper method [`__residualvalues__`](https://docs.mangrove.exchange/dev/technical-references/api-preferences/strats/src/strategies/mangroveoffer#residualvalues) supplied to calculate the residual (see example below).
* Beware that updates can fail, e.g., due to too low density.
* Make sure to refer to the guidelines on [Safe offer logic guidelines](https://docs.mangrove.exchange/dev/strat-lib/guides/safe-offer-logic-guidelines).
* Note that the parameters to `__posthookSuccess__` already point out the old offer. This can save storage since we do not have to store [IDs](https://docs.mangrove.exchange/dev/quick-links/glossary#offer-id) of posted offers.
* Beware of gas usage changes on different code paths. As an example, the [gas requirements](https://docs.mangrove.exchange/dev/strat-lib/guides/determining-gas-requirements) for the tutorial increases to 80,000 to be able to repost.

If you need to write a custom hook, for instance, for reposting multiple offers, then it can be a good idea to look at the base implementation of `__posthookSuccess__` (from `MangroveOffer`) below. A good exercise is to change the code above to emit the value returned from `super` and trigger the `reposted` and `dust` (see [density](https://docs.mangrove.exchange/dev/quick-links/glossary#density)) scenarios.

MangroveOffer.sol

```
function __posthookSuccess__(MgvLib.SingleOrder calldata order, bytes32 makerData)
  internal
  virtual
  returns (bytes32 data)
{
  // now trying to repost residual
  (uint newGives, Tick newTick) = __residualValues__(order);
  // Density check at each repost would be too gas costly.
  // We only treat the special case of `gives==0` or `wants==0` (total fill).
  // Note: wants (given by `inboundFromOutbound`) can be 0 due to rounding given the price. We could repost to get rid of the last gives at 0 wants,
  // but the maker does not need to give away these tokens for free, so we skip it.
  // Offer below the density will cause Mangrove to throw so we encapsulate the call to `updateOffer` in order not to revert posthook for posting at dust level.
  if (newGives == 0 || newTick.inboundFromOutbound(newGives) == 0) {
    return COMPLETE_FILL;
  }
  data = _updateOffer(
    OfferArgs({
      olKey: order.olKey,
      tick: newTick,
      gives: newGives,
      gasreq: order.offerDetail.gasreq(),
      gasprice: order.offerDetail.gasprice(),
      noRevert: true,
      fund: 0
    }),
    order.offerId
  );
  // logs if anything went wrong
  logRepostStatus(order, makerData, data);
}
```

[See entire file on GitHub](https://github.com/mangrovedao/mangrove-strats/blob/508bc8ace7f1d2ab54397611875306dc1ec31754/src/strategies/MangroveOffer.sol#L205-L234)
