Skip to content

Commit

Permalink
feat: bonding curve test and script with token integration
Browse files Browse the repository at this point in the history
  • Loading branch information
VanshSahay committed Feb 13, 2025
1 parent 1b4afd5 commit e616fa1
Show file tree
Hide file tree
Showing 13 changed files with 1,458 additions and 108 deletions.
7 changes: 1 addition & 6 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,12 @@ jobs:
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
version: stable

- name: Show Forge version
run: |
forge --version
- name: Run Forge fmt
run: |
forge fmt --check
id: fmt

- name: Run Forge build
run: |
forge build --sizes
Expand Down
8 changes: 3 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@
cache/
out/

# Ignores development broadcast logs
!/broadcast
/broadcast/*/31337/
/broadcast/**/dry-run/

# Docs
docs/

# Dotenv file
.env

# Broadcast logs
broadcast/
192 changes: 152 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,66 +1,178 @@
## Foundry

**Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.**

Foundry consists of:

- **Forge**: Ethereum testing framework (like Truffle, Hardhat and DappTools).
- **Cast**: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data.
- **Anvil**: Local Ethereum node, akin to Ganache, Hardhat Network.
- **Chisel**: Fast, utilitarian, and verbose solidity REPL.

## Documentation

https://book.getfoundry.sh/

## Usage

### Build

# Dataset Bonding Curve Smart Contracts

This repository contains smart contracts implementing a bonding curve mechanism for dataset tokens. The system allows for the creation and pricing of dataset tokens using a bonding curve pricing model.

## Overview

The project consists of two main contracts:

1. **DatasetToken**: An ERC1155-based token contract for representing datasets
2. **DatasetBondingCurve**: A contract implementing the bonding curve pricing mechanism with the following features:
- Initial price: 0.01 ETH
- Price multiplier: 1.5x increase per token
- Automated price calculation based on token supply

## Contract Functions

### DatasetToken Contract (`DeployDataset.sol`)

#### Core Functions
- `mintDatasetToken(OwnershipShare[], string, string, string, string, uint256, string[])`: Mints a new dataset token with multiple owners, metadata, and initial price
- `purchaseDataset(uint256)`: Allows users to purchase a dataset token at the current bonding curve price
- `setBondingCurve(address)`: Sets the bonding curve contract address (admin only)
- `updatePrice(uint256, uint256)`: Updates the price of a dataset (primary owner only)

#### View Functions
- `getTokensByTag(string)`: Returns all token IDs associated with a specific tag
- `getTokenTags(uint256)`: Returns all tags for a specific token
- `getTokenOwners(uint256)`: Returns ownership information for a token
- `getTotalTokens()`: Returns the total number of tokens minted
- `getTokensByOwner(address)`: Returns all token IDs owned by an address
- `getDatasetIPFSHash(uint256)`: Returns the IPFS hash for a purchased dataset

### DatasetBondingCurve Contract

#### Core Functions
- `setInitialPrice(uint256, uint256)`: Sets the initial price for a token's bonding curve
- `calculatePrice(uint256)`: Calculates the current price for a specific token
- `getCurrentPrice(uint256)`: View function to get the current price
- `recordPurchase(uint256)`: Records a purchase to update the bonding curve
- `updateDatasetTokenAddress(address)`: Updates the dataset token contract address

## User Workflow

### For Dataset Owners

1. **Creating a Dataset Token**
```solidity
// Example ownership structure
OwnershipShare[] shares = [
OwnershipShare(owner1, 7000), // 70%
OwnershipShare(owner2, 3000) // 30%
];
// Mint token with metadata
datasetToken.mintDatasetToken(
shares,
"Dataset Name",
"Description",
"contentHash",
"ipfsHash",
initialPrice,
["tag1", "tag2"]
);
```

2. **Managing Dataset**
- Update price if needed using `updatePrice()`
- Monitor ownership and sales through events
- Add or remove tags as needed

### For Dataset Buyers

1. **Discovering Datasets**
- Browse datasets by tags using `getTokensByTag()`
- View dataset metadata and ownership information
- Check current prices using `getCurrentPrice()`

2. **Purchasing a Dataset**
```solidity
// Get current price
uint256 price = bondingCurve.getCurrentPrice(tokenId);
// Purchase dataset
datasetToken.purchaseDataset{value: price}(tokenId);
```

3. **Accessing Dataset**
- After purchase, retrieve IPFS hash using `getDatasetIPFSHash()`
- Access dataset content through IPFS

### Price Mechanism

The bonding curve implements an automated market maker with the following characteristics:

1. **Initial Pricing**
- Each dataset starts at its set initial price
- Price increases by 1.5x after each purchase

2. **Price Calculation**
```
Current Price = Initial Price * (1.5 ^ Number of Purchases)
```

3. **Revenue Distribution**
- Sales revenue is automatically distributed to owners based on their ownership percentages
- Payments are instant and trustless

## Prerequisites

- [Foundry](https://book.getfoundry.sh/getting-started/installation)
- Ethereum wallet with some ETH for deployment
- Environment variables set up (see Configuration section)

## Installation

1. Clone the repository:
```shell
$ forge build
git clone <repository-url>
cd <repository-name>
```

### Test

2. Install dependencies:
```shell
$ forge test
forge install
```

### Format
## Configuration

```shell
$ forge fmt
Create a `.env` file in the root directory with the following variables:
```
PRIVATE_KEY=your_private_key
RPC_URL=your_rpc_url
```

### Gas Snapshots
## Building

To build the contracts:
```shell
$ forge snapshot
forge build
```

### Anvil
## Testing

Run the test suite:
```shell
$ anvil
forge test
```

### Deploy

For more detailed test output:
```shell
$ forge script script/Counter.s.sol:CounterScript --rpc-url <your_rpc_url> --private-key <your_private_key>
forge test -vv
```

### Cast

For gas reports:
```shell
$ cast <subcommand>
forge test --gas-report
```

### Help
## Deployment

The deployment process involves two steps:

1. Deploy the DatasetToken contract
2. Deploy the DatasetBondingCurve contract

To deploy the contracts:
```shell
$ forge --help
$ anvil --help
$ cast --help
source .env
forge script script/DeployBondingCurve.s.sol:DeployBondingCurve --rpc-url $RPC_URL --private-key $PRIVATE_KEY --broadcast
```

## Security

- The contracts use OpenZeppelin's standard implementations for security
- Ownership controls are in place for administrative functions
- Price calculations are done with proper decimal handling to prevent rounding errors
- Reentrancy protection is implemented for all state-changing functions
- Multi-owner support with percentage-based revenue distribution
5 changes: 5 additions & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,10 @@
src = "src"
out = "out"
libs = ["lib"]
remappings = ["@openzeppelin/=lib/openzeppelin-contracts/"]
via-ir = true

# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options

[fmt]
number_underscore = "thousands"
19 changes: 0 additions & 19 deletions script/Counter.s.sol

This file was deleted.

34 changes: 34 additions & 0 deletions script/DeployBondingCurve.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

import {Script} from "forge-std/Script.sol";
import {DatasetBondingCurve} from "../src/DatasetBondingCurve.sol";
import {DatasetToken} from "../src/DeployDataset.sol";

contract DeployBondingCurve is Script {
function run() external returns (DatasetBondingCurve, DatasetToken) {
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
address deployerAddress = vm.addr(deployerPrivateKey);

vm.startBroadcast(deployerPrivateKey);

// First deploy the DatasetToken contract
DatasetToken datasetToken = new DatasetToken(
"ipfs://",
deployerAddress
);

// Then deploy the BondingCurve contract
DatasetBondingCurve bondingCurve = new DatasetBondingCurve(
address(datasetToken),
deployerAddress
);

// Set the bonding curve in the dataset token contract
datasetToken.setBondingCurve(address(bondingCurve));

vm.stopBroadcast();

return (bondingCurve, datasetToken);
}
}
28 changes: 28 additions & 0 deletions script/DeployDataset.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

import {Script} from "forge-std/Script.sol";
import {DatasetToken} from "../src/DeployDataset.sol";

contract DeployDatasetScript is Script {
function setUp() public {}

function run() public {
// Retrieve the private key from environment variable
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");

// Start broadcasting transactions
vm.startBroadcast(deployerPrivateKey);

// Deploy the contract
// Parameters:
// 1. Base URI for metadata (e.g., IPFS gateway URL)
// 2. Initial owner address (msg.sender in this case)
new DatasetToken(
"https://api.example.com/metadata/", // Replace with your actual metadata URI NOTE: Discuss with Rahul on how we were setting this up
vm.addr(deployerPrivateKey) // Set deployer as initial owner
);

vm.stopBroadcast();
}
}
14 changes: 0 additions & 14 deletions src/Counter.sol

This file was deleted.

Loading

0 comments on commit e616fa1

Please sign in to comment.