0x0::history
History module tracks the volume data for the current epoch and past epochs. It also tracks past trade params. Past maker fees are used to calculate fills for old orders. The historic median is used to calculate rebates and burns.
Volumes
History
empty
update
reset_volumes
calculate_rebate_amount
update_historic_median
add_volume
balance_to_burn
reset_balance_to_burn
historic_maker_fee
add_total_fees_collected
use 0x0::balances;
use 0x0::constants;
use 0x0::math;
use 0x0::trade_params;
use 0x1::u128;
use 0x2::table;
use 0x2::tx_context;
Volumes
Volumes
represents volume data for a single epoch.
Using flashloans on a whitelisted pool, assuming 1_000_000 * 1_000_000_000
in volume per trade, at 1 trade per millisecond, the total volume can reach
1_000_000 * 1_000_000_000 * 1000 * 60 * 60 * 24 * 365 = 8.64e22 in one epoch.
struct Volumes has copy, drop, store
total_volume: u128
total_staked_volume: u128
total_fees_collected: balances::Balances
historic_median: u128
trade_params: trade_params::TradeParams
History
History
represents the volume data for the current epoch and past epochs.
struct History has store
epoch: u64
epoch_created: u64
volumes: history::Volumes
historic_volumes: table::Table<u64, history::Volumes>
balance_to_burn: u64
const EHistoricVolumesNotFound: u64 = 0;
empty
Create a new History
instance. Called once upon pool creation. A single blank
Volumes
instance is created and added to the historic_volumes table.
public(friend) fun empty(trade_params: trade_params::TradeParams, epoch_created: u64, ctx: &mut tx_context::TxContext): history::History
public(package) fun empty(
trade_params: TradeParams,
epoch_created: u64,
ctx: &mut TxContext,
): History {
let volumes = Volumes {
total_volume: 0,
total_staked_volume: 0,
total_fees_collected: balances::empty(),
historic_median: 0,
trade_params,
};
let mut history = History {
epoch: ctx.epoch(),
epoch_created,
volumes,
historic_volumes: table::new(ctx),
balance_to_burn: 0,
};
history.historic_volumes.add(ctx.epoch(), volumes);
history
}
update
Update the epoch if it has changed. If there are accounts with rebates, add the current epoch’s volume data to the historic volumes.
public(friend) fun update(self: &mut history::History, trade_params: trade_params::TradeParams, ctx: &tx_context::TxContext)
public(package) fun update(
self: &mut History,
trade_params: TradeParams,
ctx: &TxContext,
) {
let epoch = ctx.epoch();
if (self.epoch == epoch) return;
if (self.historic_volumes.contains(self.epoch)) {
self.historic_volumes.remove(self.epoch);
};
self.update_historic_median();
self.historic_volumes.add(self.epoch, self.volumes);
self.epoch = epoch;
self.reset_volumes(trade_params);
self.historic_volumes.add(self.epoch, self.volumes);
}
reset_volumes
Reset the current epoch’s volume data.
public(friend) fun reset_volumes(self: &mut history::History, trade_params: trade_params::TradeParams)
public(package) fun reset_volumes(
self: &mut History,
trade_params: TradeParams,
) {
self.volumes =
Volumes {
total_volume: 0,
total_staked_volume: 0,
total_fees_collected: balances::empty(),
historic_median: 0,
trade_params,
};
}
calculate_rebate_amount
Given the epoch’s volume data and the account’s volume data, calculate and returns rebate amount, updates the burn amount.
public(friend) fun calculate_rebate_amount(self: &mut history::History, prev_epoch: u64, maker_volume: u128, account_stake: u64): balances::Balances
public(package) fun calculate_rebate_amount(
self: &mut History,
prev_epoch: u64,
maker_volume: u128,
account_stake: u64,
): Balances {
assert!(
self.historic_volumes.contains(prev_epoch),
EHistoricVolumesNotFound,
);
let volumes = &mut self.historic_volumes[prev_epoch];
if (volumes.trade_params.stake_required() > account_stake) {
return balances::empty()
};
let maker_volume = maker_volume as u128;
let other_maker_liquidity = volumes.total_volume - maker_volume;
let maker_rebate_percentage = if (volumes.historic_median > 0) {
constants::float_scaling_u128() - constants::float_scaling_u128().min(
math::div_u128(other_maker_liquidity, volumes.historic_median),
)
} else {
0
};
let maker_rebate_percentage = maker_rebate_percentage as u64;
let maker_volume_proportion = if (volumes.total_staked_volume > 0) {
math::div_u128(maker_volume, volumes.total_staked_volume)
} else {
0
};
let maker_fee_proportion =
math::mul_u128(
maker_volume_proportion,
volumes.total_fees_collected.deep() as u128,
) as u64;
let maker_rebate = math::mul(maker_rebate_percentage, maker_fee_proportion);
let maker_burn = maker_fee_proportion - maker_rebate;
self.balance_to_burn = self.balance_to_burn + maker_burn;
balances::new(0, 0, maker_rebate)
}
update_historic_median
Updates the historic_median for past 28 epochs.
public(friend) fun update_historic_median(self: &mut history::History)
public(package) fun update_historic_median(self: &mut History) {
let epochs_since_creation = self.epoch - self.epoch_created;
if (epochs_since_creation < constants::phase_out_epochs()) {
self.volumes.historic_median = constants::max_u128();
return
};
let mut median_vec = vector<u128>[];
let mut i = self.epoch - constants::phase_out_epochs();
while (i < self.epoch) {
if (self.historic_volumes.contains(i)) {
median_vec.push_back(self.historic_volumes[i].total_volume);
} else {
median_vec.push_back(0);
};
i = i + 1;
};
self.volumes.historic_median = math::median(median_vec);
}
add_volume
Add volume to the current epoch’s volume data. Increments the total volume and total staked volume.
public(friend) fun add_volume(self: &mut history::History, maker_volume: u64, account_stake: u64)
public(package) fun add_volume(
self: &mut History,
maker_volume: u64,
account_stake: u64,
) {
if (maker_volume == 0) return;
let maker_volume = maker_volume as u128;
self.volumes.total_volume = self.volumes.total_volume + maker_volume;
if (account_stake >= self.volumes.trade_params.stake_required()) {
self.volumes.total_staked_volume =
self.volumes.total_staked_volume + maker_volume;
};
}
balance_to_burn
public(friend) fun balance_to_burn(self: &history::History): u64
public(package) fun balance_to_burn(self: &History): u64 {
self.balance_to_burn
}
reset_balance_to_burn
public(friend) fun reset_balance_to_burn(self: &mut history::History): u64
public(package) fun reset_balance_to_burn(self: &mut History): u64 {
let balance_to_burn = self.balance_to_burn;
self.balance_to_burn = 0;
balance_to_burn
}
historic_maker_fee
public(friend) fun historic_maker_fee(self: &history::History, epoch: u64): u64
public(package) fun historic_maker_fee(self: &History, epoch: u64): u64 {
assert!(self.historic_volumes.contains(epoch), EHistoricVolumesNotFound);
self.historic_volumes[epoch].trade_params.maker_fee()
}
add_total_fees_collected
public(friend) fun add_total_fees_collected(self: &mut history::History, fees: balances::Balances)
public(package) fun add_total_fees_collected(
self: &mut History,
fees: Balances,
) {
self.volumes.total_fees_collected.add_balances(fees);
}