Skip to content

Commit 1ce092a

Browse files
pg-agentclaude
andcommitted
refactor: move tokenomics presets to presets package
Moves AutonomousBuyback and StreamToken preset contracts from game_components_tokenomics to game_components_presets. Changes: - Added preset contracts to packages/presets/src/ - Updated presets Scarb.toml with tokenomics and interfaces dependencies - Removed presets module from tokenomics package - Added test-only preset contracts in tokenomics tests/mocks/ for unit testing - Exported ERC20_UNIT constant from tokenomics for presets to use This follows the pattern where components live in their own packages and presets (deployable contracts) live in a central presets package. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 4eb8905 commit 1ce092a

9 files changed

Lines changed: 168 additions & 14 deletions

File tree

packages/presets/Scarb.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@ edition.workspace = true
77

88
[dependencies]
99
game_components_leaderboard = { path = "../leaderboard" }
10+
game_components_tokenomics = { path = "../tokenomics" }
11+
game_components_interfaces = { path = "../interfaces" }
1012
starknet.workspace = true
1113
openzeppelin_token.workspace = true
1214
openzeppelin_introspection.workspace = true
1315
openzeppelin_access.workspace = true
16+
ekubo.workspace = true
1417

1518
[[target.starknet-contract]]
1619

packages/tokenomics/src/presets/autonomous_buyback.cairo renamed to packages/presets/src/autonomous_buyback.cairo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ pub mod AutonomousBuyback {
2323
use game_components_interfaces::tokenomics::buyback::{
2424
GlobalBuybackConfig, IBuybackAdmin, TokenBuybackConfig,
2525
};
26+
use game_components_tokenomics::buyback::BuybackComponent;
2627
use openzeppelin_access::ownable::OwnableComponent;
2728
use starknet::ContractAddress;
28-
use crate::buyback::buyback::BuybackComponent;
2929

3030
// Embed components
3131
component!(path: BuybackComponent, storage: buyback, event: BuybackEvent);

packages/presets/src/lib.cairo

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,12 @@
88
///
99
/// ## Available Presets
1010
/// - **Leaderboard**: Tournament leaderboard management with scoring and ranking
11+
/// - **AutonomousBuyback**: Autonomous token buyback via Ekubo TWAMM
12+
/// - **StreamToken**: ERC20 token with built-in TWAMM distribution
1113

14+
pub mod autonomous_buyback;
1215
pub mod leaderboard;
16+
pub mod stream_token;
17+
18+
pub use autonomous_buyback::AutonomousBuyback;
19+
pub use stream_token::StreamToken;

packages/tokenomics/src/presets/stream_token.cairo renamed to packages/presets/src/stream_token.cairo

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@
1212
#[starknet::contract]
1313
pub mod StreamToken {
1414
use game_components_interfaces::tokenomics::stream::{DistributionOrder, LiquidityConfig};
15+
use game_components_tokenomics::ERC20_UNIT;
16+
use game_components_tokenomics::stream::StreamComponent;
1517
use openzeppelin_token::erc20::{ERC20Component, ERC20HooksEmptyImpl};
1618
use starknet::ContractAddress;
17-
use crate::stream::stream::StreamComponent;
1819

1920
// Embed components
2021
component!(path: ERC20Component, storage: erc20, event: ERC20Event);
@@ -102,7 +103,6 @@ pub mod StreamToken {
102103
);
103104

104105
// Mint tokens to registry for registration (1 token = 10^18 units)
105-
use crate::constants::ERC20_UNIT;
106106
self.erc20.mint(registry_address, ERC20_UNIT.into());
107107

108108
// Register token with Ekubo

packages/tokenomics/src/lib.cairo

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
pub mod buyback;
2929
pub mod constants;
3030
pub mod factory;
31-
pub mod presets;
3231
pub mod stream;
3332

3433
// Re-exports for convenience - Buyback
@@ -39,7 +38,7 @@ pub use buyback::{
3938
};
4039

4140
// Re-exports for convenience - Constants
42-
pub use constants::Errors;
41+
pub use constants::{ERC20_UNIT, Errors};
4342

4443
// Re-exports for convenience - Factory
4544
pub use factory::StreamTokenFactory;

packages/tokenomics/src/presets.cairo

Lines changed: 0 additions & 9 deletions
This file was deleted.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
pub mod mock_erc20;
22
pub mod mock_registry;
3+
pub mod test_autonomous_buyback;
4+
pub mod test_stream_token;
35

46
pub use mock_erc20::{IMockERC20Dispatcher, IMockERC20DispatcherTrait, MockERC20};
57
pub use mock_registry::{IMockTokenRegistryDispatcher, IMockTokenRegistryDispatcherTrait};
8+
pub use test_autonomous_buyback::AutonomousBuyback;
9+
pub use test_stream_token::StreamToken;
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/// Test-only Autonomous Buyback contract for unit testing
2+
/// This is identical to the preset in game_components_presets but defined here
3+
/// so tokenomics tests can use `declare("AutonomousBuyback")`.
4+
#[starknet::contract]
5+
pub mod AutonomousBuyback {
6+
use game_components_interfaces::tokenomics::buyback::{
7+
GlobalBuybackConfig, IBuybackAdmin, TokenBuybackConfig,
8+
};
9+
use game_components_tokenomics::buyback::BuybackComponent;
10+
use openzeppelin_access::ownable::OwnableComponent;
11+
use starknet::ContractAddress;
12+
13+
component!(path: BuybackComponent, storage: buyback, event: BuybackEvent);
14+
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);
15+
16+
#[abi(embed_v0)]
17+
impl BuybackImpl = BuybackComponent::BuybackImpl<ContractState>;
18+
impl BuybackInternalImpl = BuybackComponent::InternalImpl<ContractState>;
19+
20+
#[abi(embed_v0)]
21+
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;
22+
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;
23+
24+
#[storage]
25+
struct Storage {
26+
#[substorage(v0)]
27+
buyback: BuybackComponent::Storage,
28+
#[substorage(v0)]
29+
ownable: OwnableComponent::Storage,
30+
}
31+
32+
#[event]
33+
#[derive(Drop, starknet::Event)]
34+
enum Event {
35+
#[flat]
36+
BuybackEvent: BuybackComponent::Event,
37+
#[flat]
38+
OwnableEvent: OwnableComponent::Event,
39+
}
40+
41+
#[constructor]
42+
fn constructor(
43+
ref self: ContractState,
44+
owner: ContractAddress,
45+
global_config: GlobalBuybackConfig,
46+
positions_address: ContractAddress,
47+
extension_address: ContractAddress,
48+
) {
49+
self.ownable.initializer(owner);
50+
self.buyback.initializer(global_config, positions_address, extension_address);
51+
}
52+
53+
#[abi(embed_v0)]
54+
impl BuybackAdminImpl of IBuybackAdmin<ContractState> {
55+
fn set_global_config(ref self: ContractState, config: GlobalBuybackConfig) {
56+
self.ownable.assert_only_owner();
57+
self.buyback.set_global_config(config);
58+
}
59+
60+
fn set_token_config(
61+
ref self: ContractState,
62+
sell_token: ContractAddress,
63+
config: Option<TokenBuybackConfig>,
64+
) {
65+
self.ownable.assert_only_owner();
66+
self.buyback.set_token_config(sell_token, config);
67+
}
68+
}
69+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/// Test-only Stream Token contract for unit testing
2+
/// This is identical to the preset in game_components_presets but defined here
3+
/// so tokenomics tests can use `declare("StreamToken")`.
4+
#[starknet::contract]
5+
pub mod StreamToken {
6+
use game_components_interfaces::tokenomics::stream::{DistributionOrder, LiquidityConfig};
7+
use game_components_tokenomics::ERC20_UNIT;
8+
use game_components_tokenomics::stream::StreamComponent;
9+
use openzeppelin_token::erc20::{ERC20Component, ERC20HooksEmptyImpl};
10+
use starknet::ContractAddress;
11+
12+
component!(path: ERC20Component, storage: erc20, event: ERC20Event);
13+
component!(path: StreamComponent, storage: stream, event: StreamEvent);
14+
15+
pub impl ERC20Config of ERC20Component::ImmutableConfig {
16+
const DECIMALS: u8 = 18;
17+
}
18+
19+
#[abi(embed_v0)]
20+
impl ERC20MixinImpl = ERC20Component::ERC20MixinImpl<ContractState>;
21+
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;
22+
23+
#[abi(embed_v0)]
24+
impl StreamImpl = StreamComponent::StreamImpl<ContractState>;
25+
26+
#[abi(embed_v0)]
27+
impl StreamSetupImpl = StreamComponent::StreamSetupImpl<ContractState>;
28+
29+
impl StreamInternalImpl = StreamComponent::InternalImpl<ContractState>;
30+
31+
#[storage]
32+
struct Storage {
33+
#[substorage(v0)]
34+
erc20: ERC20Component::Storage,
35+
#[substorage(v0)]
36+
stream: StreamComponent::Storage,
37+
}
38+
39+
#[event]
40+
#[derive(Drop, starknet::Event)]
41+
enum Event {
42+
#[flat]
43+
ERC20Event: ERC20Component::Event,
44+
#[flat]
45+
StreamEvent: StreamComponent::Event,
46+
}
47+
48+
#[constructor]
49+
fn constructor(
50+
ref self: ContractState,
51+
name: ByteArray,
52+
symbol: ByteArray,
53+
total_supply: u128,
54+
factory: ContractAddress,
55+
positions_address: ContractAddress,
56+
core_address: ContractAddress,
57+
registry_address: ContractAddress,
58+
extension_address: ContractAddress,
59+
liquidity_config: LiquidityConfig,
60+
distribution_orders: Span<DistributionOrder>,
61+
) {
62+
self.erc20.initializer(name, symbol);
63+
self
64+
.stream
65+
.initializer(
66+
factory,
67+
positions_address,
68+
core_address,
69+
registry_address,
70+
extension_address,
71+
liquidity_config,
72+
distribution_orders,
73+
);
74+
75+
self.erc20.mint(registry_address, ERC20_UNIT.into());
76+
self.stream.register_token();
77+
78+
let remaining_supply: u256 = (total_supply - ERC20_UNIT).into();
79+
self.erc20.mint(factory, remaining_supply);
80+
}
81+
}

0 commit comments

Comments
 (0)