Skip to content
1 change: 1 addition & 0 deletions changelog.d/coinbase-intervals.changed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Updated coinbase intervals for pox-5
Comment thread
rob-stacks marked this conversation as resolved.
Outdated
57 changes: 14 additions & 43 deletions stacks-common/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,21 +183,16 @@ pub struct CoinbaseInterval {
pub effective_start_height: u64,
}

// From SIP-029:
//
// | Coinbase Interval | Bitcoin Height | Offset Height | Approx. Supply | STX Reward | Annual Inflation |
// |--------------------|----------------|---------------------|------------------|------------|------------------|
// | Current | - | - | 1,552,452,847 | 1000 | - |
// | 1st | 945,000 | 278,950 | 1,627,352,847 | 500 (50%) | 3.23% |
// | 2nd | 1,050,000 | 383,950 | 1,679,852,847 | 250 (50%) | 1.57% |
// | 3rd | 1,260,000 | 593,950 | 1,732,352,847 | 125 (50%) | 0.76% |
// | 4th | 1,470,000 | 803,950 | 1,758,602,847 | 62.5 (50%) | 0.37% |
// | - | 2,197,560 | 1,531,510 | 1,804,075,347 | 62.5 (0%) | 0.18% |
// | Coinbase Interval | Bitcoin Height | Offset Height | STX Reward |
// |--------------------|---------------------------------------|---------------|------------|
// | Current | - | 0 | 1000 |
// | 1st | 945,000 | 278,950 | 500 |
// | 2nd | BITCOIN_MAINNET_STACKS_40_BURN_HEIGHT | 346,810 | 1000 |
Comment thread
rob-stacks marked this conversation as resolved.
Outdated
//
// The above is for mainnet, which has a burnchain year of 52596 blocks and starts at burnchain height 666050.

/// Mainnet coinbase intervals, as of SIP-029
Comment thread
rob-stacks marked this conversation as resolved.
pub static COINBASE_INTERVALS_MAINNET: LazyLock<[CoinbaseInterval; 5]> = LazyLock::new(|| {
/// Mainnet coinbase intervals
pub static COINBASE_INTERVALS_MAINNET: LazyLock<[CoinbaseInterval; 3]> = LazyLock::new(|| {
let emissions_schedule = [
CoinbaseInterval {
coinbase: 1_000 * u128::from(MICROSTACKS_PER_STACKS),
Expand All @@ -208,16 +203,9 @@ pub static COINBASE_INTERVALS_MAINNET: LazyLock<[CoinbaseInterval; 5]> = LazyLoc
effective_start_height: 278_950,
},
CoinbaseInterval {
coinbase: 250 * u128::from(MICROSTACKS_PER_STACKS),
effective_start_height: 383_950,
},
CoinbaseInterval {
coinbase: 125 * u128::from(MICROSTACKS_PER_STACKS),
effective_start_height: 593_950,
},
CoinbaseInterval {
coinbase: (625 * u128::from(MICROSTACKS_PER_STACKS)) / 10,
effective_start_height: 803_950,
// BITCOIN_MAINNET_STACKS_40_BURN_HEIGHT (1_012_860) - genesis (666_050)
Comment thread
rob-stacks marked this conversation as resolved.
Outdated
coinbase: 1_000 * u128::from(MICROSTACKS_PER_STACKS),
effective_start_height: 346_810,
},
];
assert!(CoinbaseInterval::check_order(&emissions_schedule));
Expand Down Expand Up @@ -325,35 +313,18 @@ pub struct SIP031EmissionInterval {
pub start_height: u64,
}

// From SIP-031:
//
// | Bitcoin Height | STX Emission |
// |----------------|------------ |
// |----------------|--------------|
// | 907,740 | 475 |
// | 960,300 | 1,140 |
// | 1,012,860 | 1,705 |
// | 1,065,420 | 1,305 |
// | 1,117,980 | 1,155 |
// | 1,170,540 | 0 |
// | 1,012,860 | 1,000 |

/// Mainnet sip-031 emission intervals
pub static SIP031_EMISSION_INTERVALS_MAINNET: LazyLock<[SIP031EmissionInterval; 6]> =
pub static SIP031_EMISSION_INTERVALS_MAINNET: LazyLock<[SIP031EmissionInterval; 3]> =
LazyLock::new(|| {
let emissions_schedule = [
SIP031EmissionInterval {
amount: 0,
start_height: 1_170_540,
},
SIP031EmissionInterval {
amount: 1_155 * u128::from(MICROSTACKS_PER_STACKS),
start_height: 1_117_980,
},
SIP031EmissionInterval {
amount: 1_305 * u128::from(MICROSTACKS_PER_STACKS),
start_height: 1_065_420,
},
SIP031EmissionInterval {
amount: 1_705 * u128::from(MICROSTACKS_PER_STACKS),
amount: 1_000 * u128::from(MICROSTACKS_PER_STACKS),
start_height: 1_012_860,
},
SIP031EmissionInterval {
Expand Down
120 changes: 26 additions & 94 deletions stacks-common/src/types/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,11 @@ fn test_stacks_epoch_id_display_fromstr_tryfrom_roundtrip() {

#[test]
fn test_mainnet_coinbase_emissions() {
assert_eq!(COINBASE_INTERVALS_MAINNET.len(), 5);
assert_eq!(COINBASE_INTERVALS_MAINNET.len(), 3);
assert_eq!(COINBASE_INTERVALS_MAINNET[0].coinbase, 1_000_000_000);
assert_eq!(COINBASE_INTERVALS_MAINNET[1].coinbase, 500_000_000);
assert_eq!(COINBASE_INTERVALS_MAINNET[2].coinbase, 250_000_000);
assert_eq!(COINBASE_INTERVALS_MAINNET[3].coinbase, 125_000_000);
assert_eq!(COINBASE_INTERVALS_MAINNET[4].coinbase, 62_500_000);
assert_eq!(COINBASE_INTERVALS_MAINNET[2].coinbase, 1_000_000_000);

// heights from SIP-029
Comment thread
rob-stacks marked this conversation as resolved.
assert_eq!(
COINBASE_INTERVALS_MAINNET[0].effective_start_height,
666_050 - 666_050
Expand All @@ -59,15 +56,7 @@ fn test_mainnet_coinbase_emissions() {
);
assert_eq!(
COINBASE_INTERVALS_MAINNET[2].effective_start_height,
1_050_000 - 666_050
);
assert_eq!(
COINBASE_INTERVALS_MAINNET[3].effective_start_height,
1_260_000 - 666_050
);
assert_eq!(
COINBASE_INTERVALS_MAINNET[4].effective_start_height,
1_470_000 - 666_050
1_012_860 - 666_050
);
}

Expand All @@ -93,111 +82,52 @@ fn test_get_coinbase_at_effective_height() {
assert_eq!(
CoinbaseInterval::get_coinbase_at_effective_height(
&*COINBASE_INTERVALS_MAINNET,
944_999 - 666050
944_999 - 666_050
),
1_000_000_000
);
assert_eq!(
CoinbaseInterval::get_coinbase_at_effective_height(
&*COINBASE_INTERVALS_MAINNET,
945_000 - 666050
945_000 - 666_050
),
500_000_000
);
assert_eq!(
CoinbaseInterval::get_coinbase_at_effective_height(
&*COINBASE_INTERVALS_MAINNET,
945_001 - 666050
945_001 - 666_050
),
500_000_000
);

assert_eq!(
CoinbaseInterval::get_coinbase_at_effective_height(
&*COINBASE_INTERVALS_MAINNET,
1_049_999 - 666050
1_012_859 - 666_050
Comment thread
rob-stacks marked this conversation as resolved.
Outdated
),
500_000_000
);
assert_eq!(
CoinbaseInterval::get_coinbase_at_effective_height(
&*COINBASE_INTERVALS_MAINNET,
1_050_000 - 666050
),
250_000_000
);
assert_eq!(
CoinbaseInterval::get_coinbase_at_effective_height(
&*COINBASE_INTERVALS_MAINNET,
1_050_001 - 666050
),
250_000_000
);

assert_eq!(
CoinbaseInterval::get_coinbase_at_effective_height(
&*COINBASE_INTERVALS_MAINNET,
1_259_999 - 666050
),
250_000_000
);
assert_eq!(
CoinbaseInterval::get_coinbase_at_effective_height(
&*COINBASE_INTERVALS_MAINNET,
1_260_000 - 666050
),
125_000_000
);
assert_eq!(
CoinbaseInterval::get_coinbase_at_effective_height(
&*COINBASE_INTERVALS_MAINNET,
1_260_001 - 666050
),
125_000_000
);

assert_eq!(
CoinbaseInterval::get_coinbase_at_effective_height(
&*COINBASE_INTERVALS_MAINNET,
1_469_999 - 666050
1_012_860 - 666_050
Comment thread
rob-stacks marked this conversation as resolved.
Outdated
),
125_000_000
);
assert_eq!(
CoinbaseInterval::get_coinbase_at_effective_height(
&*COINBASE_INTERVALS_MAINNET,
1_470_000 - 666050
),
62_500_000
);
assert_eq!(
CoinbaseInterval::get_coinbase_at_effective_height(
&*COINBASE_INTERVALS_MAINNET,
1_470_001 - 666050
),
62_500_000
);

assert_eq!(
CoinbaseInterval::get_coinbase_at_effective_height(
&*COINBASE_INTERVALS_MAINNET,
2_197_559 - 666050
),
62_500_000
1_000_000_000
);
assert_eq!(
CoinbaseInterval::get_coinbase_at_effective_height(
&*COINBASE_INTERVALS_MAINNET,
2_197_560 - 666050
1_012_861 - 666_050
),
62_500_000
1_000_000_000
);
assert_eq!(
CoinbaseInterval::get_coinbase_at_effective_height(
&*COINBASE_INTERVALS_MAINNET,
2_197_561 - 666050
2_000_000 - 666_050
),
62_500_000
1_000_000_000
);
}

Expand All @@ -212,17 +142,19 @@ fn test_epoch_coinbase_reward() {
assert_eq!(epoch.coinbase_reward(true, 666050, 945_000), 500_000_000);
assert_eq!(epoch.coinbase_reward(true, 666050, 945_001), 500_000_000);

assert_eq!(epoch.coinbase_reward(true, 666050, 1_049_999), 500_000_000);
assert_eq!(epoch.coinbase_reward(true, 666050, 1_050_000), 250_000_000);
assert_eq!(epoch.coinbase_reward(true, 666050, 1_050_001), 250_000_000);

assert_eq!(epoch.coinbase_reward(true, 666050, 1_259_999), 250_000_000);
assert_eq!(epoch.coinbase_reward(true, 666050, 1_260_000), 125_000_000);
assert_eq!(epoch.coinbase_reward(true, 666050, 1_260_001), 125_000_000);

assert_eq!(epoch.coinbase_reward(true, 666050, 1_469_999), 125_000_000);
assert_eq!(epoch.coinbase_reward(true, 666050, 1_470_000), 62_500_000);
assert_eq!(epoch.coinbase_reward(true, 666050, 1_470_001), 62_500_000);
assert_eq!(epoch.coinbase_reward(true, 666050, 1_012_859), 500_000_000);
assert_eq!(
epoch.coinbase_reward(true, 666050, 1_012_860),
1_000_000_000
);
assert_eq!(
epoch.coinbase_reward(true, 666050, 1_012_861),
1_000_000_000
);
assert_eq!(
epoch.coinbase_reward(true, 666050, 2_000_000),
1_000_000_000
);
}

// old coinbase schedule
Expand Down
Loading