From 69d4ffc84fa28187ff65b966d7cec74ec49416f4 Mon Sep 17 00:00:00 2001 From: VanshSahay Date: Wed, 12 Feb 2025 15:03:44 +0530 Subject: [PATCH] feat: bonding curve contract --- src/DatasetBondingCurve.sol | 117 ++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 src/DatasetBondingCurve.sol diff --git a/src/DatasetBondingCurve.sol b/src/DatasetBondingCurve.sol new file mode 100644 index 0000000..cb82ea3 --- /dev/null +++ b/src/DatasetBondingCurve.sol @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.18; + +import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; +import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; +import {DatasetToken} from "./DeployDataset.sol"; + +contract DatasetBondingCurve is Ownable { + using Math for uint256; + + // The Dataset Token contract + DatasetToken public datasetToken; + + // Bonding curve parameters + uint256 public constant PRICE_MULTIPLIER = 1.5 ether; // 1.5x increase per token + uint256 public constant DENOMINATOR = 1 ether; + + // Mapping to store initial prices for each token + mapping(uint256 => uint256) public tokenInitialPrices; + // Mapping to store the number of purchases for each token + mapping(uint256 => uint256) public tokenPurchaseCount; + + event PriceCalculated(uint256 indexed tokenId, uint256 price); + event InitialPriceSet(uint256 indexed tokenId, uint256 initialPrice); + + constructor( + address datasetTokenAddress, + address initialOwner + ) Ownable(initialOwner) { + require( + datasetTokenAddress != address(0), + "Invalid dataset token address" + ); + datasetToken = DatasetToken(datasetTokenAddress); + } + + /** + * @dev Set the initial price for a token's bonding curve + * @param tokenId The ID of the token + * @param initialPrice The initial price in wei + */ + function setInitialPrice(uint256 tokenId, uint256 initialPrice) external { + require( + msg.sender == address(datasetToken), + "Only dataset token contract can set initial price" + ); + require(initialPrice > 0, "Initial price must be greater than 0"); + require(tokenInitialPrices[tokenId] == 0, "Initial price already set"); + + tokenInitialPrices[tokenId] = initialPrice; + emit InitialPriceSet(tokenId, initialPrice); + } + + /** + * @dev Calculate the price for a specific token based on its bonding curve + * Price = initialPrice * (PRICE_MULTIPLIER ^ purchaseCount) + */ + function calculatePrice(uint256 tokenId) public returns (uint256) { + require(tokenInitialPrices[tokenId] > 0, "Token initial price not set"); + + uint256 price = tokenInitialPrices[tokenId]; + uint256 purchases = tokenPurchaseCount[tokenId]; + + // Apply multiplier based on number of purchases + for (uint256 i = 0; i < purchases; i++) { + price = (price * PRICE_MULTIPLIER) / DENOMINATOR; + } + + emit PriceCalculated(tokenId, price); + return price; + } + + /** + * @dev View function to get the current price without emitting an event + */ + function getCurrentPrice(uint256 tokenId) external view returns (uint256) { + require(tokenInitialPrices[tokenId] > 0, "Token initial price not set"); + + uint256 price = tokenInitialPrices[tokenId]; + uint256 purchases = tokenPurchaseCount[tokenId]; + + // Apply multiplier based on number of purchases + for (uint256 i = 0; i < purchases; i++) { + price = (price * PRICE_MULTIPLIER) / DENOMINATOR; + } + + return price; + } + + /** + * @dev Record a purchase of a token to update its bonding curve + * @param tokenId The ID of the token that was purchased + */ + function recordPurchase(uint256 tokenId) external { + require( + msg.sender == address(datasetToken), + "Only dataset token contract can record purchases" + ); + require(tokenInitialPrices[tokenId] > 0, "Token initial price not set"); + + tokenPurchaseCount[tokenId]++; + } + + /** + * @dev Update the dataset token contract address + * @param newDatasetTokenAddress The new address of the dataset token contract + */ + function updateDatasetTokenAddress( + address newDatasetTokenAddress + ) external onlyOwner { + require( + newDatasetTokenAddress != address(0), + "Invalid dataset token address" + ); + datasetToken = DatasetToken(newDatasetTokenAddress); + } +}