Skip to main content

perpcity_sdk/
contracts.rs

1//! On-chain contract bindings generated via Alloy's `sol!` macro.
2//!
3//! Structs, events, errors, and function selectors are derived directly from
4//! `perpcity-contracts/src/interfaces/IPerpManager.sol` and related interfaces.
5//! The `sol!` macro produces ABI-compatible Rust types automatically — no
6//! manual encoding or decoding is needed.
7
8use alloy::sol;
9
10sol! {
11    // ═══════════════════════════════════════════════════════════════════
12    //  Uniswap V4 types used by PerpCity
13    // ═══════════════════════════════════════════════════════════════════
14
15    /// Identifies a Uniswap V4 pool (and PerpCity perp) by its constituent
16    /// parameters.
17    struct PoolKey {
18        address currency0;
19        address currency1;
20        uint24 fee;
21        int24 tickSpacing;
22        address hooks;
23    }
24
25    /// Swap configuration for quoting through the Uniswap V4 pool.
26    struct SwapConfig {
27        PoolKey poolKey;
28        bool isExactIn;
29        bool zeroForOne;
30        uint256 amountSpecified;
31        uint160 sqrtPriceLimitX96;
32        uint128 unspecifiedAmountLimit;
33    }
34
35    // ═══════════════════════════════════════════════════════════════════
36    //  Module interfaces
37    // ═══════════════════════════════════════════════════════════════════
38
39    /// Fee module — returns trading fees for a perp.
40    #[sol(rpc)]
41    interface IFees {
42        function fees(PerpManager.PerpConfig calldata perp)
43            external
44            returns (uint24 cFee, uint24 insFee, uint24 lpFee);
45
46        function utilizationFee(PoolKey calldata key)
47            external
48            returns (uint24 fee);
49
50        function liquidationFee(PerpManager.PerpConfig calldata perp)
51            external
52            returns (uint24 fee);
53    }
54
55    /// Margin ratio module — returns min/max/liquidation margin ratios.
56    #[sol(rpc)]
57    interface IMarginRatios {
58        struct MarginRatios {
59            uint24 min;
60            uint24 max;
61            uint24 liq;
62        }
63
64        function marginRatios(PerpManager.PerpConfig calldata perp, bool isMaker)
65            external
66            returns (MarginRatios memory);
67    }
68
69    // ═══════════════════════════════════════════════════════════════════
70    //  PerpManager — the core protocol contract
71    // ═══════════════════════════════════════════════════════════════════
72
73    /// The PerpManager contract interface. Contains all structs, events,
74    /// errors, and function signatures from IPerpManager.sol and
75    /// PerpManager.sol.
76    #[sol(rpc)]
77    interface PerpManager {
78        // ── Structs ──────────────────────────────────────────────
79
80        struct PerpConfig {
81            PoolKey key;
82            address creator;
83            address vault;
84            address beacon;
85            address fees;
86            address marginRatios;
87            address lockupPeriod;
88            address sqrtPriceImpactLimit;
89        }
90
91        struct Position {
92            bytes32 perpId;
93            uint256 margin;
94            int256 entryPerpDelta;
95            int256 entryUsdDelta;
96            int256 entryCumlFundingX96;
97            uint256 entryCumlBadDebtX96;
98            uint256 entryCumlUtilizationX96;
99            IMarginRatios.MarginRatios marginRatios;
100            MakerDetails makerDetails;
101        }
102
103        struct MakerDetails {
104            uint32 unlockTimestamp;
105            int24 tickLower;
106            int24 tickUpper;
107            uint128 liquidity;
108            int256 entryCumlFundingBelowX96;
109            int256 entryCumlFundingWithinX96;
110            int256 entryCumlFundingDivSqrtPWithinX96;
111        }
112
113        struct CreatePerpParams {
114            address beacon;
115            address fees;
116            address marginRatios;
117            address lockupPeriod;
118            address sqrtPriceImpactLimit;
119            uint160 startingSqrtPriceX96;
120        }
121
122        struct OpenMakerPositionParams {
123            address holder;
124            uint128 margin;
125            uint120 liquidity;
126            int24 tickLower;
127            int24 tickUpper;
128            uint128 maxAmt0In;
129            uint128 maxAmt1In;
130        }
131
132        struct OpenTakerPositionParams {
133            address holder;
134            bool isLong;
135            uint128 margin;
136            uint24 marginRatio;
137            uint128 unspecifiedAmountLimit;
138        }
139
140        struct AdjustNotionalParams {
141            uint256 posId;
142            int256 usdDelta;
143            uint128 perpLimit;
144        }
145
146        struct AdjustMarginParams {
147            uint256 posId;
148            int256 marginDelta;
149        }
150
151        struct ClosePositionParams {
152            uint256 posId;
153            uint128 minAmt0Out;
154            uint128 minAmt1Out;
155            uint128 maxAmt1In;
156        }
157
158        // ── Events ───────────────────────────────────────────────
159
160        event PerpCreated(
161            bytes32 perpId,
162            address beacon,
163            uint256 sqrtPriceX96,
164            uint256 indexPriceX96
165        );
166
167        event PositionOpened(
168            bytes32 perpId,
169            uint256 sqrtPriceX96,
170            uint256 longOI,
171            uint256 shortOI,
172            uint256 posId,
173            bool isMaker,
174            int256 perpDelta,
175            int256 usdDelta,
176            int24 tickLower,
177            int24 tickUpper
178        );
179
180        event NotionalAdjusted(
181            bytes32 perpId,
182            uint256 sqrtPriceX96,
183            uint256 longOI,
184            uint256 shortOI,
185            uint256 posId,
186            int256 newPerpDelta,
187            // Settlement details
188            int256 swapPerpDelta,
189            int256 swapUsdDelta,
190            int256 funding,
191            uint256 utilizationFee,
192            uint256 adl,
193            uint256 tradingFees
194        );
195
196        event MarginAdjusted(
197            bytes32 perpId,
198            uint256 posId,
199            uint256 newMargin
200        );
201
202        event PositionClosed(
203            bytes32 perpId,
204            uint256 sqrtPriceX96,
205            uint256 longOI,
206            uint256 shortOI,
207            uint256 posId,
208            bool wasMaker,
209            bool wasLiquidated,
210            bool wasPartialClose,
211            int256 exitPerpDelta,
212            int256 exitUsdDelta,
213            int24 tickLower,
214            int24 tickUpper,
215            // Settlement details
216            int256 netUsdDelta,
217            int256 funding,
218            uint256 utilizationFee,
219            uint256 adl,
220            uint256 liquidationFee,
221            int256 netMargin
222        );
223
224        event FeesModuleRegistered(address feesModule);
225        event MarginRatiosModuleRegistered(address marginRatiosModule);
226        event LockupPeriodModuleRegistered(address lockupPeriodModule);
227        event SqrtPriceImpactLimitModuleRegistered(address sqrtPriceImpactLimitModule);
228
229        // ── Errors ───────────────────────────────────────────────
230
231        error ZeroLiquidity();
232        error ZeroNotional();
233        error TicksOutOfBounds();
234        error InvalidMargin();
235        error InvalidMarginDelta();
236        error InvalidCaller();
237        error PositionLocked();
238        error ZeroDelta();
239        error InvalidMarginRatio();
240        error FeesNotRegistered();
241        error MarginRatiosNotRegistered();
242        error LockupPeriodNotRegistered();
243        error SqrtPriceImpactLimitNotRegistered();
244        error FeeTooLarge();
245        error MakerNotAllowed();
246        error BeaconNotRegistered();
247        error PerpDoesNotExist();
248        error StartingSqrtPriceTooLow();
249        error StartingSqrtPriceTooHigh();
250        error CouldNotFullyFill();
251        error MarkTooFarFromIndex();
252
253        // ── Perp functions ───────────────────────────────────────
254
255        /// Creates a new perpetual market.
256        function createPerp(CreatePerpParams calldata params)
257            external
258            returns (bytes32 perpId);
259
260        /// Opens a maker (LP) position in a perp.
261        function openMakerPos(bytes32 perpId, OpenMakerPositionParams calldata params)
262            external
263            returns (uint256 posId);
264
265        /// Opens a taker (long/short) position in a perp.
266        function openTakerPos(bytes32 perpId, OpenTakerPositionParams calldata params)
267            external
268            returns (uint256 posId);
269
270        /// Adjusts the notional size of a taker position.
271        function adjustNotional(AdjustNotionalParams calldata params) external;
272
273        /// Adds or removes margin from an open position.
274        function adjustMargin(AdjustMarginParams calldata params) external;
275
276        /// Closes an open position (taker or maker).
277        function closePosition(ClosePositionParams calldata params) external;
278
279        /// Increases the oracle cardinality cap for a perp.
280        function increaseCardinalityCap(bytes32 perpId, uint16 newCardinalityCap) external;
281
282        // ── Module registration (owner only) ─────────────────────
283
284        function registerFeesModule(address feesModule) external;
285        function registerMarginRatiosModule(address marginRatiosModule) external;
286        function registerLockupPeriodModule(address lockupPeriodModule) external;
287        function registerSqrtPriceImpactLimitModule(address sqrtPriceImpactLimitModule) external;
288
289        // ── Module registration queries ──────────────────────────
290
291        function isFeesRegistered(address feesModule)
292            external view returns (bool);
293        function isMarginRatiosRegistered(address marginRatiosModule)
294            external view returns (bool);
295        function isLockupPeriodRegistered(address lockupPeriodModule)
296            external view returns (bool);
297        function isSqrtPriceImpactLimitRegistered(address sqrtPriceImpactLimitModule)
298            external view returns (bool);
299
300        // ── Protocol fee functions (owner only) ──────────────────
301
302        function setProtocolFee(uint24 newProtocolFee) external;
303        function collectProtocolFees(address recipient) external;
304
305        // ── View functions ───────────────────────────────────────
306
307        /// Returns the perp configuration for a given pool ID.
308        function cfgs(bytes32 perpId) external view returns (PerpConfig memory);
309
310        /// Returns a position by its NFT token ID.
311        function positions(uint256 posId) external view returns (Position memory);
312
313        /// Returns the next position ID to be minted.
314        function nextPosId() external view returns (uint256);
315
316        /// Returns the current protocol fee.
317        function protocolFee() external view returns (uint24);
318
319        /// Returns the oracle cardinality cap for a perp.
320        function cardinalityCap(bytes32 perpId) external view returns (uint16);
321
322        /// Returns the time-weighted average sqrtPrice, scaled by 2^96.
323        function timeWeightedAvgSqrtPriceX96(bytes32 perpId, uint32 lookbackWindow)
324            external view returns (uint256 twAvg);
325
326        /// Returns funding rate per second, scaled by 2^96.
327        function fundingPerSecondX96(bytes32 perpId) external view returns (int256);
328
329        /// Returns utilization fee per second, scaled by 2^96.
330        function utilFeePerSecX96(bytes32 perpId) external view returns (uint256);
331
332        /// Returns the insurance fund balance for a perp.
333        function insurance(bytes32 perpId) external view returns (uint128);
334
335        /// Returns taker long and short open interest.
336        function takerOpenInterest(bytes32 perpId)
337            external view returns (uint128 longOI, uint128 shortOI);
338
339        // ── Quote (simulation) functions ─────────────────────────
340
341        /// Simulates opening a maker position.
342        function quoteOpenMakerPosition(bytes32 perpId, OpenMakerPositionParams calldata params)
343            external
344            returns (bytes memory unexpectedReason, int256 perpDelta, int256 usdDelta);
345
346        /// Simulates opening a taker position.
347        function quoteOpenTakerPosition(bytes32 perpId, OpenTakerPositionParams calldata params)
348            external
349            returns (bytes memory unexpectedReason, int256 perpDelta, int256 usdDelta);
350
351        /// Simulates closing a position — returns PnL, funding, and liquidation status.
352        function quoteClosePosition(uint256 posId)
353            external
354            returns (
355                bytes memory unexpectedReason,
356                int256 pnl,
357                int256 funding,
358                int256 netMargin,
359                bool wasLiquidated,
360                uint256 notional
361            );
362
363        /// Simulates a swap in a perp's Uniswap V4 pool.
364        function quoteSwap(
365            bytes32 perpId,
366            bool zeroForOne,
367            bool isExactIn,
368            uint256 amount,
369            uint160 sqrtPriceLimitX96
370        )
371            external
372            returns (bytes memory unexpectedReason, int256 perpDelta, int256 usdDelta);
373
374        /// Simulates two sequential swaps.
375        function quoteTwoSwaps(bytes32 perpId, SwapConfig memory first, SwapConfig memory second)
376            external
377            returns (
378                bytes memory unexpectedReason,
379                int256 perpDelta1,
380                int256 usdDelta1,
381                int256 perpDelta2,
382                int256 usdDelta2
383            );
384
385        // ── ERC721 metadata ──────────────────────────────────────
386
387        function name() external pure returns (string memory);
388        function symbol() external pure returns (string memory);
389        function tokenURI(uint256 tokenId) external pure returns (string memory);
390        function ownerOf(uint256 tokenId) external view returns (address);
391    }
392
393    // ═══════════════════════════════════════════════════════════════════
394    //  ERC20 (USDC) — minimal interface for approve + balanceOf
395    // ═══════════════════════════════════════════════════════════════════
396
397    /// Minimal ERC20 interface for USDC interactions.
398    #[sol(rpc)]
399    interface IERC20 {
400        function approve(address spender, uint256 amount)
401            external
402            returns (bool);
403
404        function allowance(address owner, address spender)
405            external view returns (uint256);
406
407        function balanceOf(address account)
408            external view returns (uint256);
409
410        function transfer(address to, uint256 amount)
411            external
412            returns (bool);
413
414        function transferFrom(address from, address to, uint256 amount)
415            external
416            returns (bool);
417
418        event Transfer(address indexed from, address indexed to, uint256 value);
419        event Approval(address indexed owner, address indexed spender, uint256 value);
420    }
421}