Learn what a Bonding Curve is, explore its types, use cases and discover key auditing methods to secure smart contract pricing models.
Bonding curves are powerful pricing mechanisms, commonly used in token issuance, prediction markets, DAOs, and decentralized applications to determine token prices based on supply. But with great power comes many edge cases and attack surfaces.
A bonding curve is a mathematical function that defines the price of a token in relation to its supply. As tokens are bought (minted), the supply increases and the price follows the curve. When tokens are sold (burned), the price decreases accordingly.
The bonding curve is usually backed by a reserve pool (e.g., ETH, DAI), which ensures liquidity. Multiple types of bonding curves vary the token prices based on the supply and at different rates based on its design.
Linear bonding curve is one of the simplest forms of bonding curve and have a pretty simple equation to understand.
1P(s) = a * s + b
2
3P(s): Price at token supply s
4a: Slope of the line (price increase per token)
5b: Base price of the token
In the above equation, notice how the price is directly dependent on the supply; as the supply increases, the price of the token increases as well, with the opposite true for selling as selling or burning tokens would decrease the supply and hence the price.
Let’s understand this by an example value:
Then:
As the supply of tokens increases, the price of each token increases in the same pattern.
The function getPriceLinear
is applies the linear bonding curve and returns the price of assets based on the token supply.
1function getPriceLinear(uint256 supply) public view returns (uint256) {
2 return a * supply + b;
3}
The exponential bonding curve rewards the initial buyers heavily as the price of the tokens increases at a very rapid rate as the supply of minted assets increases in the pool. It is perfect for limited mints, NFT launches, or tokens that want scarcity to reflect in price.
1P(s) = a * e ^ (b * s)
2
3P(s): Price of the next token based on current supply s
4a: Starting Price or base price (when supply is zero)
5e: Euler’s number ≈ 2.718
6b: Growth coefficient (determines how fast price increases)
7s: Current tokens supply
Directly computing e ^ (b * s)
is expensive or even infeasible in Solidity or Cairo due to precision issues, a lack of floating-point support, and constant exponential math. We can apply an approximation to make the calculation; it essentially acts as a discrete version of exponential growth:
1P(s) = a * (1 + r) ^ s
2
3r ≈ small value (e.g., 0.01 or 1% growth per token)
So instead of calling exp()
functions, you just multiply the base price by (1 + r)^s
in fixed-point math.
Let’s understand the exponential bonding curves with an example:
then, P(10) = 1 * (1 + 0.01)^10 = 1 * (1.01)^10 ≈ 1.1046 ETH
And if supply = 100, then
P(100) = 1 * (1.01)^100 ≈ 2.7048 ETH
1function getPriceExponential(uint256 supply) public view returns (uint256) {
2 return a * (1 + r)**supply;
3}
The logarithmic curves follow the logarithmic equation to get to the price of an asset based on the supply. The price of tokens increases rapidly at first with the supply and then slows down as the supply grows.
1P(s) = a * ln(s + 1)
2
3P(s): Price at supply s
4a: Scaling factor (sets steepness of curve)
5ln: Natural logarithm (base e)
6s: current token supply
7s+1: To avoid log(0)
Let’s understand this by an example value:
Using the logarithmic bonding curve formula:
P(s) = 0.01 * ln(s + 1)
Then:
As the supply of tokens increases, the price of each token increases, but at a slowing rate. The logarithmic curve keeps early tokens cheap while still introducing gradual growth over time.
1function getPriceLogarithmic(uint256 supply) public view returns (uint256) {
2 return a * log2(supply + 1); // approximation using log2 or log10
3}
It is important to note that solidity doesn’t natively support floating points, so logarithmic functions are approximated with math libraries like ABDKMath64x64.
Sigmoid pricing curve is unique in its calculation when it increases the price with the supply and offers different use cases.
1P(s) = L / (1 + e ^ (-k * (s - x0)))
2
3P(s): Price at token supply s
4L: Maximum value (asymptote)
5k: Steepness
6x0: Midpoint of curve
7e: Euler’s number (≈ 2.718), base of natural log
Let’s understand this by an example value:
Using the Sigmoid Bonding Curve Formula:
P(s) = L / (1 + e ^ (-k * (s - x0)))
Then:
As the supply increases, the token price gradually rises, slow at the beginning, steeper around the midpoint (s = 3), and flattens as it approaches the price ceiling (L = 1.0). This curve is ideal for fair distribution with a soft cap on the token price.
1function sigmoid(uint256 x) public pure returns (uint256) {
2 // Use integer approximation or external math lib
3 // Placeholder: Replace with fixed-point sigmoid
4 return L / (1 + exp(-k * (x - x0)));
5}
Like an exponential curve, a sigmoid curve needs libraries like PRBMath or ABDKMath64x64 for precision.
Bonding curves are mathematical models that define the relationship between token price and supply. They are integral to various DeFi applications, including:
Bonding curve smart contracts typically include the following functions:
buy()
: Allows users to purchase tokens by sending collateral (e.g., ETH, DAI). The function calculates the number of tokens to mint based on the bonding curve formula.sell()
: Enables users to sell tokens back to the contract in exchange for collateral. The function calculates the return amount and burns the sold tokens.getPrice()
: Returns the current price of a token based on the bonding curve.getReserve()
: Provides the current reserve balance held by the contract.calculatePurchaseReturn()
/ calculateSaleReturn()
: Helper functions that compute the amount of tokens to mint or collateral to return for a given transaction.setTaxRate()
: (If applicable) Sets the tax rate on buy/sell transactions, directing a portion of the transaction to a treasury or other designated address.Bonding curves encode economic logic into on-chain math. This makes them incentive-aligned, but also financially gameable. As a security auditor, here’s where attackers might target:
Target Surface: Public buy() / sell() functions with predictable price updates.
amountOutMin
. So, price changes between transactions are exploitable.Mitigations:
minReturn
parameters.Target Surface: Bonding curves that update price based on liquidity or reserves.
Real World Example:
Pump.fun exploit where the attacker flash-loaned into the curve, manipulated price perception, and dumped.
Mitigations:
Target Surface: Linear/Exponential bonding curves with no trade caps.
Mitigations:
Target Surface: Edge-case math inside calculateBuyReturn() / calculateSellReturn().
0
Or 1 wei may break assumptions, triggering division-by-zero or DoS due to assert violations or underflows in early implementations.Mitigations:
amount > 0
.roundingError != 0
via precise math (e.g., FullMath
, PRBMath
, or mulDiv
).Target Surface: Custom curve math (k = xy, sigmoid, exp curves).
pow
, log
, or sqrt
Math may cause underflows, overflows, or rounding bugs.Mitigations:
PRBMathUD60x18
, ABDKMath64x64
).Target Surface: Bonding curves influenced by oracles (e.g., bonding against ETH/USD rate).
Mitigations:
Target Surface: Buy/sell functions with taxPercent or fee logic.
Mitigations:
tax > 100%
edge cases.stETH
, cDAI
).Target Surface: Logic built on economic assumptions instead of secure math.
Mechanism: When custom math works "correctly" but can be gamed due to flawed incentives.
Example: alternating trust/distrust voting in Ethos' bonding curve to suppress price rise.
Mitigations:
invariant: price must rise if total buy > sell
).When auditing bonding curve smart contracts, consider the following points. While this checklist is a strong starting point, it is not exhaustive, as bonding curves can vary widely in design and purpose. Novel implementations may introduce custom logic, unique pricing formulas, or hybrid mechanisms. Always analyze each bonding curve in its specific business and technical context.
Precision Handling: Ensure the contract handles decimal values accurately to prevent rounding errors.
Tax Implementation: Verify that any tax mechanisms are correctly implemented and cannot be bypassed.
Zero-Value Inputs: Check how the contract handles zero-value inputs to prevent unexpected behavior.
Arithmetic Operations: Ensure that operations are ordered correctly (e.g., multiplication before division) to maintain accuracy.
Edge Case Handling: Test the contract with very large and very small input values to identify potential vulnerabilities.
Token Compatibility: Confirm that the contract interacts correctly with various ERC20 tokens, including those with non-standard implementations.
Initialization State: Review the contract's initial state to ensure it doesn't lead to unintended behavior.
Rounding Errors: Assess the potential for rounding errors and their impact on users.
Stuck Funds: Determine if there are scenarios where funds could become irretrievable within the contract.
Denial-of-Service (DoS) Risks: Evaluate the contract's resilience against DoS attacks.
Volatility Management: Analyze how the bonding curve responds to rapid price changes and whether it can be exploited.
In the Ethos Network, the bonding curve for trust and distrust votes was defined as:
1function _calcVotePrice(Market memory market, bool isPositive) private pure returns (uint256) {
2 uint256 totalVotes = market.votes[TRUST] + market.votes[DISTRUST];
3 return (market.votes[isPositive ? TRUST : DISTRUST] * market.basePrice) / totalVotes;
4}
Exploit Scenario:
An attacker alternates between buying trust and distrust votes to keep the ratio balanced, preventing significant price increases. Later, they sell all distrust votes, causing the price of trust votes to remain lower than expected, allowing them to buy back trust votes at a reduced price and profit from the manipulation.
References:
Bonding curves are of different types and serve different use cases across the industry. This guide covers different types of bonding curves, including Linear Bonding Curve, Exponential Bonding Curve, Logarithmic Bonding Curve, and Sigmoid (S-Curve) Bonding Curve.
It also provides a strong foundation for starting auditing these bonding curves with a separte checklist while explaining the core features of such curves. These curves can be targeted through different kinds of attack vectors, including Sandwich Attacks, Flash Loan Attacks, Curve Arithmetic Inaccuracies, and more.
At QuillAudits, with our 7+ years of experience, we hold the expertise to handle different types of codebases including those utilizing bonding curves for pricing. Our focus on securing smart contracts is backed by a Multi-Layered Auditing Framework, which helps us catch bugs effectively through our two-layer approach.
Contents
Get updates on our community, partners, events, and everything happening across the ecosystem — delivered straight to your inbox.
Subscribe Now!
Office 104/105 Level 1, Emaar Square, Building 4 Sheikh Mohammed Bin Rashid Boulevard Downtown Dubai, United Arab Emirates P.O box: 416654
Privacy PolicyAll Rights Reserved. © 2025. QuillAudits - LLC
Office 104/105 Level 1, Emaar Square, Building 4 Sheikh Mohammed Bin Rashid Boulevard Downtown Dubai, United Arab Emirates P.O box: 416654
audits@quillaudits.comAll Rights Reserved. © 2025. QuillAudits - LLC
Privacy Policy