Morpheus is an implementation of Paradigm's groundbreaking Prediction Market Automated Market Maker (PM-AMM), forged on the high-performance Aptos blockchain. Morpheus translates sophisticated financial theory into tested Move smart contracts, harnessing the full power of the Aptos Fungible Asset framework. Our mission is to deliver a capital-efficient, mathematically precise, and fully decentralized platform for the future of prediction markets.
The core of Morpheus translates the complex mathematical foundations of the PM-AMM—rooted in Gaussian score dynamics and normal distribution functions—into a secure and modular set of on-chain smart contracts. It provides a superior alternative to traditional AMMs, which are ill-suited for the unique price dynamics of binary outcome tokens.
pm_amm package deployed at : 0xf95728f054fc19c29a9015073408d46b3c18a5c0d9dda993be3ef35280f20f78
create_prediction_market: https://explorer.aptoslabs.com/txn/6897272898?network=testnet
mint_prediction_tokens: https://explorer.aptoslabs.com/txn/6897273580?network=testnet
add_market_liquidity: https://explorer.aptoslabs.com/txn/6897274357?network=testnet
buy_yes_tokens: https://explorer.aptoslabs.com/txn/6897281054?network=testnet
- Overview
- Architecture
- Features
- Getting Started
- Usage
- Deployment
- Project Status
- Contributing
- Project License
- References
Morpheus is a high-fidelity, open-source implementation of Paradigm's innovative Prediction Market Automated Market Maker (PM-AMM), built on the Aptos blockchain using the Move language. It addresses the shortcomings of traditional AMMs for prediction markets by providing a capital-efficient and mathematically sound framework for trading binary outcome tokens.
The platform offers a seamless user experience, allowing anyone to create new prediction markets, explore existing ones, and engage in a full suite of DeFi activities. The user journey is designed to be simple and powerful:
- Discover or Create: Users can either browse a list of existing markets or create their own from scratch.
- Interact on a Dedicated Market Page: Each market has a dedicated interface that serves as a central hub for all user actions.
- Engage with Core Features: From the market page, users can:
- Swap: Trade outcome tokens to speculate on the result.
- Mint Pair: Deposit collateral to receive a full set of outcome tokens.
- Add/Remove Liquidity: Provide capital to the AMM to earn fees.
- View Analytics: Access detailed data and performance metrics for the market.
The ultimate goal is to deliver a robust, decentralized, and user-friendly hub for prediction markets on the Aptos network.
Prediction markets, a compelling application of decentralized finance (DeFi), have been hindered by a fundamental liquidity problem. Standard Automated Market Makers (AMMs) are ill-suited for the unique financial instruments of prediction markets, known as outcome tokens, forcing reliance on less efficient order book models. The Portfolio Management Automated Market Maker (pm-AMM) is a novel mechanism designed specifically to solve this challenge.
Prediction markets use outcome tokens, which have a binary payoff: they resolve to $1 if a specific event occurs and $0 if it does not. For any event, a "YES" and "NO" token pair is created. The price of a token, bounded between $0 and $1, represents the market's implied probability of that outcome. Unlike standard assets, their value converges to a known state ($0 or $1) at a known future time, a dynamic that conventional AMMs fail to model.
The Constant Product Market Maker (CPMM), with its
- Guaranteed Loss at Expiration: At expiration, one token becomes worthless. Arbitrageurs will drain the valuable tokens from the pool, leaving LPs with a portfolio of zero-value assets. This is a permanent, 100% capital loss.
- Inefficient Liquidity Profile: A CPMM provides liquidity across an infinite price range, which is inefficient for outcome tokens priced between 0 and 1. It fails to account for the changing volatility of outcome tokens as they approach expiration, providing a static and mismatched liquidity profile.
This asset-model mismatch highlights the need for specialized financial protocols. The pm-AMM represents a paradigm shift, moving from a generic trading curve to a design based on a rigorous model of the underlying asset.
The pm-AMM is built on a new theoretical toolkit that models outcome token price evolution, quantifies LP risk, and proposes a novel principle to manage that risk.
The pm-AMM uses a model called Gaussian score dynamics. This model is ideal for markets where the outcome depends on whether an underlying value or "score" (e.g., vote margin, point difference) is above a threshold at a future time. The model assumes this score follows a Brownian motion (a random walk), and the token's price is the probability that the score will end above the threshold. This is analogous to the Black-Scholes model for binary options and allows for a quantitative, model-driven AMM design.
The key risk metric for the pm-AMM is Loss-vs-Rebalancing (LVR), which is the rate of expected losses LPs incur from adverse selection. It quantifies the value extracted by arbitrageurs trading against the AMM's stale prices. Unlike impermanent loss, LVR measures the pure cost of market-making by isolating the loss incurred by a delta-hedged position, representing the unavoidable cost of having passive orders exploited by better-informed traders.
The pm-AMM's core design philosophy is the Uniform AMM. An AMM is "uniform" if its expected LVR is a constant fraction of the pool's value, regardless of the asset's current price. This makes LP risk stable and predictable, allowing LPs to accurately model their costs (LVR) and determine the trading fees required for profitability. This transforms liquidity provision from a speculative activity into a calculable business.
The Static pm-AMM is the first implementation of this philosophy, designed to achieve uniform LVR with respect to price at a fixed point in time.
The trading curve of the static pm-AMM is defined by the following invariant equation :
Where:
-
$x$ is the AMM's reserve of one outcome token (e.g., the "NO" token). -
$y$ is the reserve of the complementary outcome token (e.g., the "YES" token). -
$L$ is a liquidity parameter that scales the overall size of the pool. A larger$L$ corresponds to a deeper market with lower price impact (slippage) for a given trade size. -
$\phi(z) = \frac{1}{\sqrt{2\pi}}e^{-z^2/2}$ is the probability density function (PDF) of the standard normal distribution. -
$\Phi(z) = \int_{-\infty}^{z} \phi(u)du$ is the cumulative distribution function (CDF) of the standard normal distribution.
This formula is a direct mathematical consequence of the Gaussian score dynamics assumption. It is derived by solving a differential equation that sets the rate of change of fractional LVR with respect to price to zero, ensuring the AMM's trading curve meets its risk-management objective.
The pm-AMM's invariant concentrates liquidity around a 50% probability and provides less liquidity at extreme probabilities (near 0% or 100%). This is a rational design choice, as legacy models suffer from disproportionately high LVR at these price extremes. The pm-AMM withdraws liquidity from these dangerous zones and deploys it where uncertainty and trading activity are highest, aligning capital efficiency with the market's risk profile.
The Static pm-AMM successfully normalizes LP risk across price, but it does not account for the dimension of time. The Dynamic pm-AMM extends the model to address the changing risk profile of a prediction market as it approaches its expiration date, aiming to create a constant expected rate of loss over the market's entire lifetime.
As a prediction market's expiration nears, uncertainty resolves, and prices accelerate towards 0 or 1. This period of heightened volatility magnifies LVR for LPs. A static liquidity profile is ill-equipped to handle this, leading to an escalating rate of loss as time decays.
The Dynamic pm-AMM makes the liquidity parameter a function of the time remaining until expiration,
The key innovation is replacing the constant liquidity term
The design of the Dynamic pm-AMM leads to a predictable rate of loss for liquidity providers. This is achieved by ensuring the expected Loss-vs-Rebalancing (LVR) is constant. The derivation begins with the formula for the instantaneous rate of LVR at any time
Here,
-
Find the Expected Instantaneous LVR: The model is designed so that the expected value of the pool,
$\mathbb{E}[V_t]$ , decreases in a way that perfectly counteracts the shrinking time to expiration. This results in a constant expected rate of loss :
where
-
Integrate Over Time: To find the total expected LVR over the lifetime of the market (from
$t=0$ to$t=T$ ), we integrate this constant expected rate :
- Calculate the Final Result: Solving the integral gives the total expected loss :
This powerful result shows that an LP can expect to lose exactly half of their initial capital (
The pm-AMM framework is a significant advancement over existing designs, with implications for both LPs and protocol designers.
The following table provides a comparative analysis of the pm-AMM against the Constant Product Market Maker (CPMM) and the Logarithmic Market Scoring Rule (LMSR), another popular mechanism for prediction markets.
| Feature | Constant Product (CPMM) | Logarithmic (LMSR) | Static pm-AMM | Dynamic pm-AMM |
|---|---|---|---|---|
| Invariant | ||||
| Asset Suitability | General purpose tokens | Prediction Markets (Subsidized) | Outcome Tokens (Unsubsidized) | Outcome Tokens (Unsubsidized) |
| Liquidity Profile | Uniformly distributed | Concentrated by subsidy | Statically concentrated at p=0.5
|
Dynamically concentrated, decaying over time |
| LVR Behavior | High at price extremes; unpredictable | High at price extremes | Uniform across price (at fixed t) | Uniform across price & time (in expectation) |
| LP Loss Profile | Guaranteed loss at expiry | Potential loss, subsidized by maker | Predictable loss rate vs. price | Predictable total loss over market lifetime |
| Key Weakness | Asset-model mismatch; capital inefficient | Requires external market maker subsidy | LVR increases near expiry | May under-provide liquidity when fees are highest |
The pm-AMM is a landmark in the maturation of DeFi, providing a specialized, theoretically grounded solution for prediction markets. It shifts AMM design from heuristic curve-fitting towards explicit, model-based risk management. This signals a broader evolution away from one-size-fits-all protocols towards a diverse ecosystem of specialized financial machinery, with the pm-AMM's methodology providing a robust foundation for the next generation of AMMs.
The protocol's architecture is designed with a strong emphasis on modularity, security, and clarity. It separates pure mathematical logic from stateful contract management, which significantly enhances auditability, testability, and maintainability. The system is composed of several distinct modules, each with a specific responsibility.
A high-level map of the core smart contract modules within the pm_amm package is provided below. This serves as a guide for developers to navigate the codebase and understand the separation of concerns.
| Module | Responsibility | Key Files |
|---|---|---|
pm_amm.move |
Main entry point; aggregates user-facing functions and manages global protocol state. | sources/pm_amm.move |
prediction_market.move |
Manages the lifecycle of a single market, including Fungible Asset (FA) tokens, collateral, and LP interactions. | sources/market/prediction_market.move |
pool_state.move |
Core state management for the AMM pool (reserves, liquidity parameter |
sources/core/pool_state.move |
invariant.move |
Direct implementation of the PM-AMM mathematical invariant and core formulas (pricing, optimal reserves). | sources/core/invariant.move |
liquidity_math.move |
Pure functions for calculating liquidity addition/removal based on a desired value increase. | sources/amm_math/liquidity_math.move |
swap_math.move |
Pure functions for calculating swap quotes and outcomes, abstracting the core swap logic. | sources/amm_math/swap_math.move |
dynamic_tracking.move |
Manages LP withdrawals and loss tracking for dynamic pools, implementing time-dependent LVR features. | sources/core/dynamic_tracking.move |
fixed_point.move |
Foundational library for 64.64 fixed-point arithmetic, crucial for all mathematical operations. | sources/math/fixed_point.move |
normal_dist.move |
Implements the CDF, PDF, and inverse CDF of the normal distribution, the mathematical bedrock of the PM-AMM. | sources/math/normal_dist.move |
This layered design is a key architectural strength. By isolating pure, stateless mathematical computations in modules like invariant.move and liquidity_math.move, the most complex and high-risk components of the AMM can be rigorously tested in isolation. The stateful modules, such as prediction_market.move, are then responsible for the simpler logic of asset transfers and state transitions, reducing the surface area for bugs and making the protocol significantly more robust and auditable.
-
1. Landing Page - The Central Hub:
- All users start on the main Landing Page, which acts as the gateway to the entire ecosystem.
-
2. Market Discovery and Creation:
- From the landing page, users can choose one of two paths:
- Explore Existing Markets: Browse a curated list of all active and past prediction markets to find opportunities for trading or liquidity provision.
- Create a New Market: Use the intuitive creation tool to launch a new prediction market with a unique question, outcome, and parameters.
- From the landing page, users can choose one of two paths:
-
3. The Market Interaction Page:
- Whether creating a new market or selecting an existing one, the user is directed to a dedicated Market Page. This page serves as the primary dashboard for all interactions related to that specific market.
-
4. Core User Actions:
- From the market page, users can seamlessly perform a variety of core DeFi actions:
- Swap: Trade between the market's outcome tokens (e.g., YES vs. NO) to speculate on the final result.
- Mint Pair: Deposit collateral to mint a complete set of outcome tokens (one of each possible outcome).
- Add Liquidity: Become a liquidity provider by depositing assets into the AMM pool to earn trading fees.
- Remove Liquidity: Withdraw your provided liquidity and any accumulated fees.
- Analytics: Access a detailed dashboard with key metrics, price history, and performance data for the market.
- From the market page, users can seamlessly perform a variety of core DeFi actions:
The swapping mechanism allows traders to express their belief in an outcome by trading between a pair of complementary outcome tokens (e.g., "YES" and "NO").
-
Core Functions: Swaps are initiated through the
buy_yes_tokensandbuy_no_tokensentry functions in the mainpm_ammmodule. These functions serve as the public-facing API for traders. -
Execution Flow:
- A trader's call is routed to the corresponding function in
prediction_market.move, such asbuy_yes. - The
prediction_marketmodule handles all Fungible Asset (FA) operations. It authenticates the user, withdraws the input tokens (e.g., NO tokens) from the user's account, and prepares to transfer the output tokens (e.g., YES tokens). - The core calculation is delegated to the
pool_statemodule, specificallyswap_y_to_x_direct(for a NO-to-YES swap) orswap_x_to_y_direct. - The
pool_statemodule uses the pure, stateless functions inswap_math.moveto determine the swap's outcome based on the current pool reserves and liquidity. -
swap_mathultimately relies oninvariant.moveto solve the PM-AMM invariant equation and find the resulting token amounts. - After the calculation,
prediction_marketupdates its internal FA reserves and transfers the output tokens to the trader.
- A trader's call is routed to the corresponding function in
-
Mathematical Foundation: Unlike constant-product AMMs where price is a simple ratio of reserves, the PM-AMM's price is a direct representation of probability, derived from the cumulative distribution function (CDF) of the normal distribution, denoted as
$\Phi$ . The price$P$ of the YES token (reserve$x$ ) is given by the marginal price formula :
This formula is implemented in the invariant_amm::calculate_marginal_price function. Here,
To participate in trading, users first need to acquire the outcome tokens. This is achieved through a collateralization process.
- Core Function:
mint_prediction_tokens. - Mechanism: A user deposits a specified amount of a collateral asset (e.g., APT coin) into the market contract. In return, the protocol mints and sends the user a complete set of outcome tokens—an equal amount of YES and NO tokens. For example, depositing 1 APT might yield 1,000,000 YES tokens and 1,000,000 NO tokens.
- Economic Principle: This 1-to-1 collateralization (1 unit of collateral for 1 set of outcome tokens) establishes a crucial economic peg. After the market is resolved, each winning token is redeemable for one unit of the collateral asset (scaled appropriately). This ensures the system is always fully backed and solvent. The
prediction_market::mint_prediction_tokensfunction manages the secure transfer of collateral into the market's dedicated resource account and handles the minting of the new FA-based YES and NO tokens.
Liquidity provision in the PM-AMM is fundamentally different from traditional AMMs, offering a more intuitive and capital-efficient experience.
-
Core Function:
add_market_liquidity. -
Key Innovation: Instead of requiring Liquidity Providers (LPs) to deposit a specific pair of tokens in a certain ratio, the PM-AMM allows them to add liquidity by specifying a single metric: the
desired_value_increase. This is a direct and practical implementation of one of the core theoretical concepts from the Paradigm research paper. -
Mechanism:
- An LP calls
add_market_liquidity, providing a rawu128value that represents their desired contribution to the pool's total value, formatted as a fixed-point number. - The call is handled by
prediction_market::add_pretrade_liquidity. - This function fetches the current market price
$P$ from thepool_state. - The core logic is executed within
liquidity_math::add_liquidity_pm_amm. This function takes thedesired_value_increaseand the current price$P$ to calculate the necessary increase in the liquidity parameter,$\Delta L$ . - With
$\Delta L$ determined, the protocol then calculates the exact amounts of YES and NO tokens the LP must deposit to achieve this liquidity increase without altering the current market price. - The protocol pulls these precise token amounts from the LP's wallet and mints new LP tokens in return.
- An LP calls
-
Mathematical Foundation: The relationship between the pool's value V(P), its price
$P$ , and its liquidity$L$ is defined as$V(P) = L \phi(\Phi^{-1}(P))$ , where$\phi$ is the probability density function (PDF) of the normal distribution. To add liquidity at the current price, the protocol computes the required change in liquidity,$\Delta L$ , from the user's desired value increase,$\Delta V(P)$ , using the inverse relationship :
This invariant_amm::calculate_optimal_reserves function to determine the precise token deposits required. This elegant mechanism abstracts away the complexity for the LP, who only needs to decide on a single value to contribute.
LPs can withdraw their capital and earned fees by redeeming their LP tokens.
- Core Function:
remove_market_liquidity. - Mechanism: An LP initiates the process by calling the function with the amount of LP tokens they wish to burn. The
prediction_market::remove_liquidityfunction orchestrates the withdrawal. - Proportional Withdrawal: The protocol calculates the LP's proportional share of the current YES and NO token reserves based on the amount of LP tokens being burned. This is handled by
liquidity_math::remove_liquidity_pm_amm, which effectively reverses the value-based addition process. - Integrated Fee Distribution: A key feature of this implementation is the automatic and fair distribution of trading fees. When an LP removes liquidity, the
remove_liquidityfunction first calculates their proportional share of all fees that have accumulated in the market's fee vaults. These fee earnings are transferred to the LP along with their principal liquidity, ensuring an immediate and fair settlement of their returns.
Every prediction market must eventually be resolved to reflect the true outcome of the real-world event.
- Core Function:
resolve_prediction_market. - Mechanism: After the event's conclusion and the market's expiration time has passed, the designated market creator calls this function. They provide a single boolean argument,
outcome_yes, which declares whether the "YES" or "NO" outcome was the correct one. - Security and Trust: The
prediction_market::resolve_marketfunction includes a critical access control check:assert!(raddr == m.creator, E_NOT_AUTHORIZED). This ensures that only the original creator of the market can act as the oracle and report the final outcome. This represents a centralized trust assumption in the protocol's design. - State Transition: A successful resolution sets the market's
resolvedflag totrueand permanently records the outcome. This action disables all further trading and liquidity operations, transitioning the market into a settlement-only state.
Once a market is resolved, participants can redeem their tokens for the underlying collateral.
- Core Function:
settle_tokens_with_collateral. - Mechanism: Token holders call this function to settle their positions. They specify the amount of YES and NO tokens they wish to redeem. The
prediction_market::settle_tokens_with_collateralfunction verifies the market's resolved outcome. It proceeds to burn all tokens submitted by the user (both winning and losing) but only pays out collateral for the winning tokens. - Example: If a market resolves to "YES", and a user holds 100 YES tokens and 50 NO tokens, settling this entire position will burn all 150 tokens and return 100 units of collateral to the user. This design encourages users to settle their full position, cleaning up token balances and ensuring a complete redemption cycle.
This implementation brings the theoretical advantages of the PM-AMM to life with a suite of powerful features designed for prediction markets.
-
Mathematically Rigorous Pricing: The protocol avoids simplistic pricing models. Instead, it is founded on Gaussian score dynamics, providing a principled and robust framework for modeling the price evolution of outcome tokens. This is implemented through the
normal_dist.moveandinvariant.movemodules. - Concentrated & Capital-Efficient Liquidity: The PM-AMM's unique invariant curve naturally concentrates liquidity around a 50% probability, where market uncertainty and trading activity are typically highest. This makes it significantly more capital-efficient for prediction markets compared to general-purpose AMMs like Uniswap V2.
-
Dynamic, Time-Decaying Liquidity: The protocol supports dynamic pools for markets with a known expiration date. In these pools, the effective liquidity
$L$ automatically and predictably decreases as the expiration time approaches, following the formula$L_t = L_0\sqrt{T-t}$ . This feature, implemented inpool_state::get_effective_liquidity, helps LPs manage the heightened risk and volatility near a market's resolution. -
Uniform LVR (Loss-vs-Rebalancing): The dynamic pool model is designed to offer a more predictable return profile for LPs by targeting a uniform Loss-vs-Rebalancing (LVR). This is achieved through the combination of time-decaying liquidity and a systematic LP withdrawal mechanism managed by the
dynamic_tracking.movemodule, which allows LPs to de-risk their positions over the market's lifetime. - Value-Based Liquidity Provision: Simplifying the LP experience, the protocol allows providers to contribute capital by specifying a single value they wish to add to the pool. The smart contracts then automatically calculate the optimal amounts of YES and NO tokens required, maximizing efficiency and removing guesswork.
- Built on Aptos with Fungible Assets: The entire system is built using the modern Aptos Fungible Asset (FA) standard for all its tokens (YES, NO, and LP). This ensures full composability and compatibility with the broader Aptos DeFi ecosystem, allowing tokens to be used in other protocols, wallets, and explorers.
Follow these instructions to set up the project locally for development and testing.
- Aptos CLI: You must have the Aptos CLI installed. Follow the official instructions at aptos.dev.
- Move Language: A basic understanding of the Move programming language is recommended.
- Node.js: Required for running client-side scripts or a potential frontend application.
Clone the repository to your local machine:
git clone <repository_url>
cd <repository_name>Ensure your Aptos CLI is configured to a local network, devnet, or testnet. You can create a new profile or use an existing one. The project's dependencies, primarily the AptosFramework, are managed in the Move.toml file.
-
Start a local network (optional):
aptos node run-local-testnet --with-faucet
-
Compile the project: Before compiling, you may need to fetch the dependencies defined in
Move.toml.# Set up a profile if you haven't already aptos init --profile local # Compile the Move package aptos move compile --named-addresses pm_amm=<YOUR_ACCOUNT_ADDRESS>
-
Run the test suite: The project includes a comprehensive test suite. To run all tests, execute:
aptos move testFor more detailed testing instructions, including how to run specific test modules, refer to the
tests/README.mdfile.
You can interact with the deployed smart contracts using the Aptos CLI. The JSON files in the repository root and /json_files directory provide examples of the required arguments for each function.
Note: Replace 0x... with the actual address where the pm_amm module is deployed.
-
Create a Prediction Market:
# See create_market_args.json for the argument structure and types aptos move run \ --function-id '0x...::pm_amm::create_prediction_market' \ --json-file create_market_args.json
-
Add Liquidity to a Market:
# See add_liquidity_args.json for the argument structure aptos move run \ --function-id '0x...::pm_amm::add_market_liquidity' \ --json-file add_liquidity_args.json
-
Execute a Swap (Buy YES Tokens):
# See buy_yes_args.json for the argument structure aptos move run \ --function-id '0x...::pm_amm::buy_yes_tokens' \ --json-file buy_yes_args.json
-
View Market Information:
# See get_market_info.json for the argument structure aptos move view \ --function-id '0x...::pm_amm::get_market_info' \ --json-file json_files/get_market_info.json
Follow these steps to deploy the PM-AMM protocol to an Aptos network (devnet, testnet, or mainnet).
-
Compile the Package with Metadata: Compile the contracts and save the build metadata. This is required for deployment. Replace
<DEPLOYER_ADDRESS>with the address of the account you are deploying from.aptos move compile --save-metadata --named-addresses pm_amm=<DEPLOYER_ADDRESS>
-
Publish to the Network: Use the
publishcommand with the appropriate profile for your target network.# Ensure your CLI is configured for the target network aptos move publish --profile <PROFILE_NAME>
-
Initialize the Protocol: After the module is published, the designated admin account must call the
initializefunction one time to set up the global protocol configuration, such as the fee recipient address.aptos move run \ --function-id '<DEPLOYER_ADDRESS>::pm_amm::initialize' \ --args 'address:<FEE_RECIPIENT_ADDRESS>' 'u16:<PROTOCOL_FEE_RATE>'
This function can only be called once and is protected to ensure it's called by the account that deployed the contract.
- Current Stage: The protocol is considered Beta and is feature-complete according to the core design of the PM-AMM.
- Audits: The smart contracts have not yet undergone a formal third-party security audit. Use in a production environment is at your own risk.
- Testing: The project is supported by a comprehensive test suite that covers mathematical correctness, contract integration, and various edge cases. The testing philosophy and coverage details can be found in
tests/README.md. The codebase demonstrates a strong commitment to quality and correctness through its extensive testing.
Contributions are welcome! If you'd like to contribute to the project, please follow these steps:
- Fork the repository.
- Create a new feature branch (
git checkout -b feature/NewFeature). - Make your changes and commit them (
git commit -m 'Add some NewFeature'). - Ensure your changes are accompanied by corresponding tests.
- Push your changes to your branch (
git push origin feature/NewFeature). - Open a Pull Request for review.
This project is licensed under the Apache 2.0 License.
- Primary Research Paper: pm-amm by Paradigm
- Aptos Move Language Documentation:(https://aptos.dev/move/book/introduction)
- Aptos Fungible Asset Standard:(https://aptos.dev/standards/fungible-asset)










