Skip to content
Evan Kuo edited this page Jul 10, 2019 · 6 revisions

For assistance, please reach out to us at [email protected]

Table of Contents

1. Introduction

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.

When 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: 8:00PM UTC - 8:20PM UTC.
  3. Can execute with zero supply adjustment.
  4. If a rebase fails within the time window, the protocol waits until the next window to accept another rebase call.

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

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

2.1 Example Timeline

7:50pm UTC - AMPL deposits and withdrawals are paused
7:55pm UTC - AMPL trading is paused
7:56pm UTC - Begin watching for rebase event
8:04pm UTC - Rebase is detected
8:06pm UTC - Rebase event has passed X confirmations. Balances are updated
8:07pm 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 and 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 the pause window, it is recommended that trades are cancellable. During the pause window, it is recommended that when a user tries to place a new order a helpful message is displayed to the user.

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 two options for handling these sell 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.

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.

3. Integration Testing

To test and deploy your integration, please refer to:

  • Deployment Info
  • Test Case Checklist

For assistance, please reach out to us at [email protected]

Clone this wiki locally