# Reposting an offer in the posthook

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

In case an offer is [partially taken](/dev/quick-links/glossary.md#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](/dev/strat-lib/getting-started/post-a-smart-offer.md#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__`](/dev/strat-lib/technical-references/api-preferences/strats/src/strategies/mangroveoffer.md#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`](/dev/strat-lib/technical-references/api-preferences/strats/src/strategies/offer_maker/abstract/direct.md#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](/dev/strat-lib/guides/determining-gas-requirements.md) than using [`_newOffer`](/dev/strat-lib/technical-references/api-preferences/strats/src/strategies/offer_maker/abstract/direct.md#newoffer).
* Use the helper method [`__residualvalues__`](/dev/strat-lib/technical-references/api-preferences/strats/src/strategies/mangroveoffer.md#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](/dev/strat-lib/guides/safe-offer-logic-guidelines.md).
* Note that the parameters to `__posthookSuccess__` already point out the old offer. This can save storage since we do not have to store [IDs](/dev/quick-links/glossary.md#offer-id) of posted offers.
* Beware of gas usage changes on different code paths. As an example, the [gas requirements](/dev/strat-lib/guides/determining-gas-requirements.md) 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](/dev/quick-links/glossary.md#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)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.mangrove.exchange/dev/strat-lib/guides/reposting-an-offer-in-the-posthook.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
