mintExactCost function
Mint a lot-rounded position within an all-in max_cost budget.
Unlike mint_exact_amount, fees are sized inside the budget: the quantity
search evaluates the all-in withdrawal the mint charges
(premium + trader-paid fee + builder_fee + EWMA penalty + inventory_impact_charge)
against the fee-incentive, congestion, and book state at execution, so the debit
never exceeds max_cost. max_cost is first capped to the account's available
USDC after settlement, so std::u64::max_value!() sizes against the whole
balance.
The budget search finds the largest fitting quantity. If that quantity costs more than its maximum payout, a conservative search tries a smaller fill; rounding can make that fallback miss a larger admissible fill. Only when the budget is the limiting constraint is the remainder less than the incremental all-in cost of one more lot. Payout-limited fills and lot-cap saturation can leave more. Insufficient expiry cash backing aborts the mint; sizing does not shrink the fill to available backing, and the quote does not preflight it.
min_quantity is this entrypoint's slippage guard. The budget is fixed, so
every adverse move between building the transaction and executing it — the
price, the congestion surcharge, the sponsor subsidy, the inventory-impact
charge — shows up as fewer contracts, and a fill below min_quantity aborts
EMintQuantityBelowMin. It bounds the all-in price per contract at
max_cost / min_quantity, which is why the shape carries no separate
probability cap; passing 0 accepts any fill the budget buys. A budget too
small to admit constants::min_premium aborts EPremiumBelowMinimum rather
than minting nothing, and zero is such a budget: unlike mint_exact_amount
there is no max_cost cap to require, because here the budget IS the sizing
input. Other requirements match mint_exact_quantity. Returns the minted order
ID.
Implementation
MoveCallBuilder mintExactCost(
{dynamic arguments, String? package, Map<String, dynamic>? config}) {
final packageAddress = package ??
(config?['predictPackageId'] as String?) ??
'@local-pkg/deepbook_predict';
return (tx) => tx.moveCall(
'$packageAddress::expiry_market::mint_exact_cost',
arguments: normalizeMoveArguments(
tx,
withConfigDefaults(
arguments, config, const {'config': 'protocolConfig'}),
[
null,
null,
null,
null,
null,
'u64',
'u64',
'u64',
'u64',
'0x2::accumulator::AccumulatorRoot',
'0x2::clock::Clock'
],
[
'market',
'wrapper',
'auth',
'config',
'pricer',
'lowerTick',
'higherTick',
'maxCost',
'minQuantity'
]),
);
}