A Solidity smart contract for exchanging USDT for pUSD tokens based on a three-part bonding curve.
The BondingCurveExchange contract allows users to buy pUSD tokens using USDT, with the price determined by a piecewise bonding curve. The contract is designed to be deployed on BNB Chain and interacts with BEP20 tokens.
The price per pUSD is defined by a three-part bonding curve based on the total amount of pUSD released:
- Stage 1: First 1 trillion pUSD (0–1e12) are sold at a fixed rate of 1 USDT = 100,000 pUSD
- Stage 2: Next 2 trillion pUSD (1e12–3e12) are sold at a linearly decreasing rate from 100,000 → 1 pUSD per USDT
- Stage 3: Final 1 trillion pUSD (3e12–4e12) are sold at a fixed rate of 1 USDT = 1 pUSD
- Accepts USDT (BEP20, 18 decimals) and sends users pUSD (BEP20, 18 decimals)
- pUSD is a fixed-supply token with a total supply of 4 trillion (4e12)
- Tracks released pUSD via a
releasedvariable - No reverse exchange (users cannot convert pUSD back to USDT)
- No fee (the full amount of USDT is used for the exchange)
- USDT received is retained in the contract and can be withdrawn by the owner
- Owner is defined at deployment and has exclusive withdrawal access
Returns the current exchange rate (pUSD per USDT) based on the amount of pUSD released.
function getRate() public view returns (uint256)Calculates how much pUSD a user will receive for a given amount of USDT.
function calculatePurchaseAmount(uint256 usdtAmount) public view returns (uint256)Allows users to buy pUSD tokens with USDT.
function buy(uint256 usdtAmount) external returns (uint256)Allows the owner to withdraw USDT from the contract.
function withdrawUSDT(address to) external onlyOwner- Node.js and npm installed
- Hardhat installed
- BNB Chain wallet with BNB for gas
- USDT and pUSD token addresses
- Clone the repository and install dependencies:
git clone <repository-url>
cd pusd-curve
npm install- Create a
.envfile with the following variables:
# Use hardware wallet or secure enclave for production
USDT_ADDRESS=usdt_token_address
PUSD_ADDRESS=pusd_token_address
Security Note: Never commit sensitive information to version control. Use .env.local for local development and encrypted secrets for CI/CD.
- Deploy the contract:
npx hardhat run scripts/deploy-exchange.js --network bsc- After deployment, transfer pUSD tokens to the contract:
// Using ethers.js or web3.js
const pusdToken = await ethers.getContractAt("IERC20", pusdAddress);
await pusdToken.transfer(exchangeAddress, ethers.utils.parseEther("4000000000000"));- Verify the contract on BscScan:
npx hardhat verify --network bsc <contract-address> <usdt-address> <pusd-address>This project uses optimized compilation settings to improve performance and reduce contract size. The optimizations include:
- Solidity optimizer with 2000 runs
- Yul optimizer with advanced settings
- Parallel compilation using multiple CPU cores
- Enhanced caching for faster builds
- Contract size monitoring
To compile the contracts with these optimizations:
npm run compile # Standard compilation
npm run compile:clean # Clean and compile
npm run compile:time # Measure compilation time
npm run size # Show contract sizesFor more details on the compilation optimizations, see COMPILATION.md.
When integrating with a DApp, the typical user flow is:
- Display the current exchange rate by calling
getRate() - When the user enters a USDT amount, calculate the expected pUSD amount by calling
calculatePurchaseAmount(usdtAmount) - Check if the user has approved the contract to spend their USDT by calling
usdt.allowance(userAddress, contractAddress) - If needed, prompt the user to approve the contract by calling
usdt.approve(contractAddress, amount) - Execute the purchase by calling
buy(usdtAmount)
Users can also interact with the contract directly through wallets like MetaMask or through BscScan:
- First, approve the BondingCurveExchange contract to spend USDT by calling the
approvefunction on the USDT contract - Then call the
buyfunction with the desired USDT amount
Run the tests with:
npx hardhat testThe tests cover:
- Deployment validation
- Rate calculation for all three stages
- Purchase amount calculation
- Buy function
- Withdrawal functionality
MIT