Problem Description
I’m implementing a bonding curve for pass pricing in my protocol and encountering two issues:
- Arithmetic Overflow: The multiplication in the price calculation is causing overflow errors in Move
- Price Suppression: When fixing the overflow, the resulting prices are too low
Current Implementation
Python Reference (Working as Expected)
def get_price(supply, amount):
# Constants
DEFAULT_WEIGHT_A = 30000000 # 0.3 * 10^8
DEFAULT_WEIGHT_B = 20000000 # 0.2 * 10^8
DEFAULT_WEIGHT_C = 2
WAD = 100000000 # 10^8
INITIAL_PRICE = 1 * WAD
# Add adjustment factor to supply
adjusted_supply = supply + DEFAULT_WEIGHT_C
if adjusted_supply == 0:
return INITIAL_PRICE
# Calculate summations
n1 = adjusted_supply - 1
sum1 = (n1 * adjusted_supply * (2 * n1 + 1)) // 6
n2 = n1 + amount
sum2 = (n2 * (adjusted_supply + amount) * (2 * n2 + 1)) // 6
# Calculate final price
summation = DEFAULT_WEIGHT_A * (sum2 - sum1)
price = ((DEFAULT_WEIGHT_B * summation) // WAD * INITIAL_PRICE) // WAD
return max(price, INITIAL_PRICE)
MOVE Implementation (Causing Overflow)
public fun calculate_price(supply: u64, amount: u64, is_sell: bool): u64 acquires Config {
let config = borrow_global<Config>(@podium);
let adjusted_supply = supply + config.weight_c;
if (adjusted_supply == 0) {
return INITIAL_PRICE
};
let n1 = adjusted_supply - 1;
let sum1 = (n1 * adjusted_supply * (2 * n1 + 1)) / 6;
let n2 = n1 + amount;
let sum2 = (n2 * (adjusted_supply + amount) * (2 * n2 + 1)) / 6;
let summation = config.weight_a * (sum2 - sum1);
let price = (config.weight_b * summation * INITIAL_PRICE) / (WAD * WAD);
if (price < INITIAL_PRICE) {
INITIAL_PRICE
} else {
price
}
}
Expected Price Progression
First 10 passes: ~$1-15 range
First 50 passes: ~$15-75 range
First 100 passes: ~$75-200 range
Questions
What’s the best way to handle the multiplication overflow in Move while maintaining the desired price curve?
Should we be using different scaling factors or a different order of operations?
Are there any Move-specific patterns for handling large number calculations in bonding curves?
Additional Context
Using WAD = 100000000 (10^8) for decimal scaling
Initial price is set to 1 MOVE (100000000 in internal units)
The weights are currently:
weight_a = 30000000 (0.3 10^8)
weight_b = 20000000 (0.2 10^8)
weight_c = 2
Any insights on implementing this correctly in Move would be greatly appreciated!