_Docs/
Get StartedModulesPlatformDeployCookbookChangelogReference
_Stack
_Modules
  • Ledger
  • Numscript
    • Program Structure
    • Selecting an Interpreter
    • Unambiguous Monetary Notation
    • CLI
    • Numscript specs format
    • Reference
      • Send
      • Sources
      • Destinations
      • Rounding
      • Save
      • Overdraft
      • Variables
      • Metadata
      • oneofexp
      • Account Interpolationexp
      • get_assetexp
      • get_amountexp
      • Mid-script Function Callsexp
      • Asset Colorsexp
  • Connectivity
  • WalletsEE
  • FlowsEE
  • ReconciliationEE
  1. Modules
  2. Numscript
  3. Reference
  4. Overdraft
Numscript

Overdraft

The overdraft directive lets you instruct the Numscript interpreter that an account post-transaction balance is allowed to be less than zero.

Unbounded#

The overdraft directive allows for the account to go below zero without any limit, by using the unbounded keyword:

Numscript
send [USD/2 100] (
  source = @foo allowing unbounded overdraft
  destination = @bar
)

Bounded#

The exact amount below zero at which the account is allowed to go can be specified by using the up to keyword with a monetary value:

Numscript
send [USD/2 100] (
  source = @foo allowing overdraft up to [USD/2 50]
  destination = @bar
)

The overdraft() function#

The overdraft() function is an experimental feature. While it is expected to remain available either in its current form or through an equivalent mechanism in future versions, you need to enable experimental features to use it.

When working with asset accounts that have negative balances, you can use the overdraft() function to safely check balances and perform transactions atomically.

Overview#

The overdraft() function returns the positive amount of overdraft when an account's balance is negative, or 0 if the balance is positive. This is particularly useful when working with asset accounts, which by design have negative balances in Formance.

Usage#

Here's how to use the overdraft function:

Numscript
vars {
  monetary $acc_overdraft = overdraft(@account, USD/2)
}

// Use $acc_overdraft in your transaction logic
send $acc_overdraft (
  source = @world
  destination = @account
)

In this example:

  • If @account has a balance of [USD/2 -50], $acc_overdraft will be [USD/2 50]
  • If @account has a balance of [USD/2 100], $acc_overdraft will be [USD/2 0]

Enabling the experimental feature#

To use overdraft(), you need to enable two experimental features:

  1. The experimental rewrite feature
  2. The experimental-overdraft-function flag

See the Numscript embedding documentation for instructions on enabling these features.

Alternative: Using balance()#

If you cannot use the experimental features, note that the standard balance() function only works with non-negative balances and will fail if the account balance is negative.

Numscript
vars {
  // This will fail if @account has a negative balance
  monetary $bal = balance(@account, USD/2)
}

For accounts that may have negative balances (like asset accounts), use the overdraft() function instead.

Setting Overdrafts via API#

In addition to specifying overdrafts in Numscript, you can also configure overdraft limits directly via the API when creating transactions.

Using the transaction endpoint#

When sending a transaction via the API, you can specify overdraft allowances in the script's vars section:

JSON
{
  "script": {
    "vars": {
      "amount": "USD/2 1000"
    },
    "plain": "send $amount ( source = @customers:123 allowing unbounded overdraft destination = @merchants:456 )"
  }
}

Bounded overdrafts via API#

For bounded overdrafts, include the limit in the Numscript:

JSON
{
  "script": {
    "vars": {},
    "plain": "send [USD/2 1000] ( source = @customers:123 allowing overdraft up to [USD/2 500] destination = @merchants:456 )"
  }
}

When using the API, the overdraft behavior is the same as when using Numscript directly. The API is simply a transport mechanism for the Numscript execution.

Overdraft Validation with Backdated Transactions#

When inserting backdated transactions with overdrafts, the ledger validates the final state rather than intermediate states. See bi-temporality for details on how backdated transactions interact with overdraft limits

SaveVariables
On This Page
  • Unbounded
  • Bounded
  • The overdraft() function
  • Overview
  • Usage
  • Enabling the experimental feature
  • Alternative: Using balance()
  • Setting Overdrafts via API
  • Using the transaction endpoint
  • Bounded overdrafts via API
  • Overdraft Validation with Backdated Transactions