Skip to content

Ampleforth Exchange Integration Guide

Aalavandhan edited this page Aug 23, 2024 · 48 revisions

We are happy to assist, please reach out to us at dev-support@ampleforth.org

With Ampleforth team’s support, Bitfinex was able to complete integration with one engineer over the course of 1 week.

Table of Contents


1. Overview

The Ampleforth AMPL token is a standard ERC-20 token deployed on Ethereum, with one unique piece of behavior: it has a rebase function that adjusts the total supply up or down. The size of this adjustment is calculated automatically. For full context about the economic motivation for this solution please see the whitepaper.

Each time a rebase changes the total supply, all user wallets holding AMPL tokens adjust up or down globally by the same scaling factor. This global balance update happens atomically for all wallets in a single transaction. Ultimately, this means that when an exchange's pooled wallet balance is adjusted, user balances need to be adjusted accordingly.

1.1  Rebase Output

Each time a rebase executes succesfully, the function emits a log message that includes an updated totalSupply

event LogRebase(
  uint256 indexed epoch,
  uint256 totalSupply
);

This new totalSupply value from the log output, can be used to safely update user balances on centralized exchanges.

1.2  Rebase Rules

The rebase method strictly adheres to a simple set of rules. Specifically, rebases:

  1. Occur at most once per day.
  2. Only occur within the block timestamp window: 2:00AM UTC - 2:20AM UTC.
  3. Can execute with zero supply adjustment.

Please note that block timestamps may have slight deviation from wall timestamps. Continue reading below to learn about the integration steps in greater detail.


2. Integration Steps

All integration steps derive from the observation that user-balances may change in the rebase window. For centralized exchanges, there are two key things to note: 1) When a user’s balance changes on-chain it must be propagated to off-chain accounting, and 2) If a user’s balance decreases, some orders may then be unable to be filled. To safely manage this, centralized exchanges need to sequentially:

  1. PAUSE withdrawals and trading
  2. UPDATE balances
  3. RESUME withdrawals and trading

2.1  Example Timeline

Below is a sample timeline of events that safely propagates supply changes to users on a centralized exchange.

1:50am UTC - AMPL deposits and withdrawals are paused
1:55am UTC - AMPL trading is paused
1:56am UTC - Begin watching for rebase event
2:04am UTC - Rebase is detected
2:06am UTC - Rebase event has passed X confirmations. Balances are updated
2:07am UTC - Trading unpaused, deposits/withdrawals unpaused

2.2  Watching for Rebase Events

It is recommended that the exchange listens for or polls the rebase log message (LogRebase) and wait for X confirmations before applying the result.

Listening should begin with the first block whose timestamp is within the window. If the exchange listening process uses wall time, they should begin watching X minutes before window start to account for block timestamp drift.

Listening should go until at least X confirmation blocks after the last block whose timestamp is within the window. This accounts for any uncle blocks or chain reorganizations.

2.3  Deposits & Withdrawals

  • Deposits and withdrawals of AMPLs should be paused X minutes before the window start. This ensures there’s no race condition between balance adjustments onchain and offchain.
  • These can be unpaused after the window end or rebase transaction is confirmed, after all balances have been updated and trading has resumed.
  • If there are pending withdrawals, they must either be cancelled or scaled when balances are scaled.

Note that if an incoming deposit were to happen during a pause window, the block timestamp of that deposit should be observed. Before crediting a user’s account, check if the transfer happened before or after the rebase operation, because the scaling factor may need to be applied.

2.4  Balance Updates

If balance updates are a non-atomic operation in your infrastructure, AMPL trading should be paused before updating user balances. Every balance is then adjusted by the same, global scaling factor. The scaling factor S is calculated as follows:

S = new_supply / old_supply

The old_supply is the last supply that was used for exchange balance updates. This is important, in case a previous rebase event was missed. The new_supply is simply the current totalSupply(), X confirmations after the rebase.

2.5  Trading Pause

AMPL trading should be paused before balance and order book updates.

  • During pause window, it is recommended that trades are cancellable.
  • During pause window, it is recommended that when a user tries to place a new order a helpful message is displayed.

2.6  Order Book

In the case where balances decrease, there may be some open orders in the book which cannot be filled. For example:

1. Alice has 10 AMPL
2. Alice places a sell order for 9.9 AMPL
3. Supply decreases, and Alice has 9.5 AMPL
4. The sell amount is greater than Alice’s balance.

There are three options for handling these orders:

  1. Orders are left unchanged. When matched, they are filled as much as possible with the rest being cancelled.
  2. During trading pause and after balance updates, orders which cannot be filled are cancelled.
  3. Alice can only place orders up to X% of her balance, so the order couldn't be placed to begin with.

The first option is the least disruptive and may also be the easiest if the exchange supports margin trading. The second option can be done with a linear scan over the order book. The third option works best with "time in force" for order expiration.


3. Integration Testing

To test and deploy your integration, please refer to:

For assistance, please reach out to us at dev-support@ampleforth.org