Skip to main content

tempo_contracts/precompiles/
stablecoin_dex.rs

1pub use IStablecoinDEX::{
2    IStablecoinDEXErrors as StablecoinDEXError, IStablecoinDEXEvents as StablecoinDEXEvents,
3};
4
5crate::sol! {
6    /// StablecoinDEX interface for managing orderbook based trading of stablecoins.
7    ///
8    /// The StablecoinDEX provides a limit orderbook system where users can:
9    /// - Place limit orders (buy/sell) with specific price ticks
10    /// - Place flip orders that automatically create opposite-side orders when filled
11    /// - Execute swaps against existing liquidity
12    /// - Manage internal balances for trading
13    ///
14    /// The exchange operates on pairs between base tokens and their designated quote tokens,
15    /// using a tick-based pricing system for precise order matching.
16    #[derive(Debug, PartialEq, Eq)]
17    #[sol(abi)]
18    interface IStablecoinDEX {
19        // Structs
20        struct Order {
21            uint128 orderId;
22            address maker;
23            bytes32 bookKey;
24            bool isBid;
25            int16 tick;
26            uint128 amount;
27            uint128 remaining;
28            uint128 prev;
29            uint128 next;
30            bool isFlip;
31            int16 flipTick;
32        }
33
34        struct PriceLevel {
35            uint128 head;
36            uint128 tail;
37            uint128 totalLiquidity;
38        }
39
40        struct Orderbook {
41            address base;
42            address quote;
43            int16 bestBidTick;
44            int16 bestAskTick;
45        }
46
47        // Core Trading Functions
48        function createPair(address base) external returns (bytes32 key);
49        function place(address token, uint128 amount, bool isBid, int16 tick) external returns (uint128 orderId);
50        function placeFlip(address token, uint128 amount, bool isBid, int16 tick, int16 flipTick) external returns (uint128 orderId);
51        function cancel(uint128 orderId) external;
52        function cancelStaleOrder(uint128 orderId) external;
53
54        // Swap Functions
55        function swapExactAmountIn(address tokenIn, address tokenOut, uint128 amountIn, uint128 minAmountOut) external returns (uint128 amountOut);
56        function swapExactAmountOut(address tokenIn, address tokenOut, uint128 amountOut, uint128 maxAmountIn) external returns (uint128 amountIn);
57        function quoteSwapExactAmountIn(address tokenIn, address tokenOut, uint128 amountIn) external view returns (uint128 amountOut);
58        function quoteSwapExactAmountOut(address tokenIn, address tokenOut, uint128 amountOut) external view returns (uint128 amountIn);
59
60        // Balance Management
61        function balanceOf(address user, address token) external view returns (uint128);
62        function withdraw(address token, uint128 amount) external;
63
64        // View Functions
65        function getOrder(uint128 orderId) external view returns (Order memory);
66
67        function getTickLevel(address base, int16 tick, bool isBid) external view returns (uint128 head, uint128 tail, uint128 totalLiquidity);
68        function pairKey(address tokenA, address tokenB) external pure returns (bytes32);
69        function nextOrderId() external view returns (uint128);
70        function books(bytes32 pairKey) external view returns (Orderbook memory);
71
72        // Constants (exposed as view functions)
73        function MIN_TICK() external pure returns (int16);
74        function MAX_TICK() external pure returns (int16);
75        function TICK_SPACING() external pure returns (int16);
76        function PRICE_SCALE() external pure returns (uint32);
77        function MIN_ORDER_AMOUNT() external pure returns (uint128);
78        function MIN_PRICE() external pure returns (uint32);
79        function MAX_PRICE() external pure returns (uint32);
80
81        // Price conversion functions
82        function tickToPrice(int16 tick) external pure returns (uint32 price);
83        function priceToTick(uint32 price) external pure returns (int16 tick);
84
85        // Events
86        event PairCreated(bytes32 indexed key, address indexed base, address indexed quote);
87        event OrderPlaced(uint128 indexed orderId, address indexed maker, address indexed token, uint128 amount, bool isBid, int16 tick, bool isFlipOrder, int16 flipTick);
88        event OrderFilled(uint128 indexed orderId, address indexed maker, address indexed taker, uint128 amountFilled, bool partialFill);
89        event OrderCancelled(uint128 indexed orderId);
90
91        // Errors
92        error Unauthorized();
93        error PairDoesNotExist();
94        error PairAlreadyExists();
95        error OrderDoesNotExist();
96        error IdenticalTokens();
97        error InvalidToken();
98        error TickOutOfBounds(int16 tick);
99        error InvalidTick();
100        error InvalidFlipTick();
101        error InsufficientBalance();
102        error InsufficientLiquidity();
103        error InsufficientOutput();
104        error MaxInputExceeded();
105        error BelowMinimumOrderSize(uint128 amount);
106        error InvalidBaseToken();
107        error OrderNotStale();
108    }
109}
110
111impl StablecoinDEXError {
112    /// Creates an unauthorized access error.
113    pub const fn unauthorized() -> Self {
114        Self::Unauthorized(IStablecoinDEX::Unauthorized {})
115    }
116
117    /// Creates an error when pair does not exist.
118    pub const fn pair_does_not_exist() -> Self {
119        Self::PairDoesNotExist(IStablecoinDEX::PairDoesNotExist {})
120    }
121
122    /// Creates an error when pair already exists.
123    pub const fn pair_already_exists() -> Self {
124        Self::PairAlreadyExists(IStablecoinDEX::PairAlreadyExists {})
125    }
126
127    /// Creates an error when order does not exist.
128    pub const fn order_does_not_exist() -> Self {
129        Self::OrderDoesNotExist(IStablecoinDEX::OrderDoesNotExist {})
130    }
131
132    /// Creates an error when trying to swap identical tokens.
133    pub const fn identical_tokens() -> Self {
134        Self::IdenticalTokens(IStablecoinDEX::IdenticalTokens {})
135    }
136
137    /// Creates an error when a token address is not a valid TIP20 token.
138    pub const fn invalid_token() -> Self {
139        Self::InvalidToken(IStablecoinDEX::InvalidToken {})
140    }
141
142    /// Creates an error for tick out of bounds.
143    pub const fn tick_out_of_bounds(tick: i16) -> Self {
144        Self::TickOutOfBounds(IStablecoinDEX::TickOutOfBounds { tick })
145    }
146
147    /// Creates an error for invalid flip tick.
148    pub const fn invalid_flip_tick() -> Self {
149        Self::InvalidFlipTick(IStablecoinDEX::InvalidFlipTick {})
150    }
151
152    /// Creates an error for invalid tick.
153    pub const fn invalid_tick() -> Self {
154        Self::InvalidTick(IStablecoinDEX::InvalidTick {})
155    }
156
157    /// Creates an error for insufficient balance.
158    pub const fn insufficient_balance() -> Self {
159        Self::InsufficientBalance(IStablecoinDEX::InsufficientBalance {})
160    }
161
162    /// Creates an error for insufficient liquidity.
163    pub const fn insufficient_liquidity() -> Self {
164        Self::InsufficientLiquidity(IStablecoinDEX::InsufficientLiquidity {})
165    }
166
167    /// Creates an error for insufficient output.
168    pub const fn insufficient_output() -> Self {
169        Self::InsufficientOutput(IStablecoinDEX::InsufficientOutput {})
170    }
171
172    /// Creates an error for max input exceeded.
173    pub const fn max_input_exceeded() -> Self {
174        Self::MaxInputExceeded(IStablecoinDEX::MaxInputExceeded {})
175    }
176
177    /// Creates an error for order amount below minimum.
178    pub const fn below_minimum_order_size(amount: u128) -> Self {
179        Self::BelowMinimumOrderSize(IStablecoinDEX::BelowMinimumOrderSize { amount })
180    }
181
182    /// Creates an error for invalid base token.
183    pub const fn invalid_base_token() -> Self {
184        Self::InvalidBaseToken(IStablecoinDEX::InvalidBaseToken {})
185    }
186
187    /// Creates an error when order is not stale
188    pub const fn order_not_stale() -> Self {
189        Self::OrderNotStale(IStablecoinDEX::OrderNotStale {})
190    }
191}