diff --git a/.github/workflows/auto-assign.yml b/.github/workflows/auto-assign.yml new file mode 100644 index 0000000..499949b --- /dev/null +++ b/.github/workflows/auto-assign.yml @@ -0,0 +1,73 @@ +name: CI/CD Pipeline + +on: + push: + branches: + - main + pull_request: + branches: + - main + workflow_dispatch: # Allows you to manually trigger the workflow + +jobs: + build: + name: Build Contracts + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: 18 + + - name: Install dependencies + run: npm install + + - name: Compile contracts + run: npx hardhat compile + + test: + name: Run Tests + runs-on: ubuntu-latest + needs: build # Ensures tests run after build stage + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: 18 + + - name: Install dependencies + run: npm install + + - name: Run tests + run: npx hardhat test + + deploy: + name: Deploy Contracts + runs-on: ubuntu-latest + needs: test # Ensures deployment runs after tests pass + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: 18 + + - name: Install dependencies + run: npm install + + - name: Deploy contracts + run: npx hardhat run scripts/deploy.js --network mainnet + env: + PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }} + INFURA_API_KEY: ${{ secrets.INFURA_API_KEY }} diff --git a/contracts/SEQICO.sol b/contracts/SEQICO.sol index 245c13b..7450c1d 100644 --- a/contracts/SEQICO.sol +++ b/contracts/SEQICO.sol @@ -9,8 +9,16 @@ contract SEQICO is Ownable { IERC20 public usdt; IERC20 public usdc; + // Price per token in wei (ETH has 18 decimals) + // Example: 0.00189 ETH per token (approximately $3.79 at $2000/ETH) uint256 public pricePerTokenETH; + + // Price per token in USDT units (USDT has 6 decimals) + // Example: 3790000 = 3.79 USDT per token uint256 public pricePerTokenUSDT; + + // Price per token in USDC units (USDC has 6 decimals) + // Example: 3790000 = 3.79 USDC per token uint256 public pricePerTokenUSDC; event TokensPurchased(address indexed buyer, uint256 amount, string payment); @@ -37,7 +45,9 @@ contract SEQICO is Ownable { function buyWithETH(uint256 tokenAmount) external payable { require(tokenAmount > 0, "Amount must be greater than 0"); - uint256 requiredETH = pricePerTokenETH * tokenAmount; + // Calculate required ETH: price per token * number of tokens / 1e18 + // Division by 1e18 converts from wei units to prevent overflow + uint256 requiredETH = pricePerTokenETH * tokenAmount / 1e18; require(msg.value >= requiredETH, "Insufficient ETH sent"); require(seqToken.balanceOf(address(this)) >= tokenAmount, "Not enough SEQ tokens"); @@ -53,6 +63,7 @@ contract SEQICO is Ownable { function buyWithUSDT(uint256 tokenAmount) external { require(tokenAmount > 0, "Amount must be greater than 0"); + // Calculate required USDT: price per token * number of tokens / 1e18 uint256 requiredUSDT = pricePerTokenUSDT * tokenAmount / 1e18; require(seqToken.balanceOf(address(this)) >= tokenAmount, "Not enough SEQ tokens"); require(usdt.allowance(msg.sender, address(this)) >= requiredUSDT, "Approve USDT first"); @@ -65,6 +76,7 @@ contract SEQICO is Ownable { function buyWithUSDC(uint256 tokenAmount) external { require(tokenAmount > 0, "Amount must be greater than 0"); + // Calculate required USDC: price per token * number of tokens / 1e18 uint256 requiredUSDC = pricePerTokenUSDC * tokenAmount / 1e18; require(seqToken.balanceOf(address(this)) >= tokenAmount, "Not enough SEQ tokens"); require(usdc.allowance(msg.sender, address(this)) >= requiredUSDC, "Approve USDC first"); @@ -82,4 +94,4 @@ contract SEQICO is Ownable { function withdrawERC20(address token, address recipient) public onlyOwner { IERC20(token).transfer(recipient, IERC20(token).balanceOf(address(this))); } -} \ No newline at end of file +} diff --git a/scripts/example-values.js b/scripts/example-values.js new file mode 100644 index 0000000..66adc03 --- /dev/null +++ b/scripts/example-values.js @@ -0,0 +1,61 @@ +// Example values for SEQICO contract deployment +// Token price: $3.79 USD per SEQ token + +import { ethers } from "hardhat"; + +// Example price values for a $3.79 token +async function calculatePriceValues() { + console.log("=== SEQICO Price Calculation Examples ==="); + console.log("Target token price: $3.79 USD per SEQ token\n"); + + // ETH Price Calculation + // Assuming ETH = $2000 USD (adjust based on current market price) + const ethPriceUSD = 2000; // Current ETH price in USD + const tokenPriceUSD = 3.79; + const tokenPriceETH = tokenPriceUSD / ethPriceUSD; // 3.79 / 2000 = 0.001895 ETH + + const pricePerTokenETH = ethers.parseEther(tokenPriceETH.toString()); + console.log(`ETH Price Calculation:`); + console.log(`- ETH price: $${ethPriceUSD} USD`); + console.log(`- Token price in ETH: ${tokenPriceETH} ETH`); + console.log(`- pricePerTokenETH: ${pricePerTokenETH.toString()} wei`); + console.log(`- For deployment: ethers.parseEther("${tokenPriceETH}")\n`); + + // USDT Price Calculation + // USDT has 6 decimal places + const pricePerTokenUSDT = ethers.parseUnits(tokenPriceUSD.toString(), 6); + console.log(`USDT Price Calculation:`); + console.log(`- Token price: $${tokenPriceUSD} USDT`); + console.log(`- pricePerTokenUSDT: ${pricePerTokenUSDT.toString()} (6 decimals)`); + console.log(`- For deployment: ethers.parseUnits("${tokenPriceUSD}", 6)\n`); + + // USDC Price Calculation + // USDC has 6 decimal places + const pricePerTokenUSDC = ethers.parseUnits(tokenPriceUSD.toString(), 6); + console.log(`USDC Price Calculation:`); + console.log(`- Token price: $${tokenPriceUSD} USDC`); + console.log(`- pricePerTokenUSDC: ${pricePerTokenUSDC.toString()} (6 decimals)`); + console.log(`- For deployment: ethers.parseUnits("${tokenPriceUSD}", 6)\n`); + + console.log("=== Complete Deployment Example ==="); + console.log(` +const SEQICO = await ethers.getContractFactory("SEQICO"); +const seqICO = await SEQICO.deploy( + seqTokenAddress, + usdtAddress, + usdcAddress, + ethers.parseEther("${tokenPriceETH}"), // ${tokenPriceETH} ETH per token + ethers.parseUnits("${tokenPriceUSD}", 6), // ${tokenPriceUSD} USDT per token + ethers.parseUnits("${tokenPriceUSD}", 6) // ${tokenPriceUSD} USDC per token +); + `); + + return { + pricePerTokenETH, + pricePerTokenUSDT, + pricePerTokenUSDC + }; +} + +// Run the calculation +calculatePriceValues().catch(console.error); \ No newline at end of file diff --git a/scripts/price-examples.js b/scripts/price-examples.js new file mode 100644 index 0000000..6a15b3c --- /dev/null +++ b/scripts/price-examples.js @@ -0,0 +1,52 @@ +// Example values for SEQICO contract deployment +// Token price: $3.79 USD per SEQ token + +console.log("=== SEQICO Price Calculation Examples ==="); +console.log("Target token price: $3.79 USD per SEQ token\n"); + +// ETH Price Calculation +// Assuming ETH = $2000 USD (adjust based on current market price) +const ethPriceUSD = 2000; // Current ETH price in USD +const tokenPriceUSD = 3.79; +const tokenPriceETH = tokenPriceUSD / ethPriceUSD; // 3.79 / 2000 = 0.001895 ETH + +// Calculate wei value (1 ETH = 1e18 wei) +const pricePerTokenETHWei = Math.floor(tokenPriceETH * 1e18); + +console.log(`ETH Price Calculation:`); +console.log(`- ETH price: $${ethPriceUSD} USD`); +console.log(`- Token price in ETH: ${tokenPriceETH} ETH`); +console.log(`- pricePerTokenETH: ${pricePerTokenETHWei} wei`); +console.log(`- For deployment: ethers.parseEther("${tokenPriceETH}")\n`); + +// USDT Price Calculation (6 decimal places) +const pricePerTokenUSDT = Math.floor(tokenPriceUSD * 1e6); +console.log(`USDT Price Calculation:`); +console.log(`- Token price: $${tokenPriceUSD} USDT`); +console.log(`- pricePerTokenUSDT: ${pricePerTokenUSDT} (6 decimals)`); +console.log(`- For deployment: ethers.parseUnits("${tokenPriceUSD}", 6)\n`); + +// USDC Price Calculation (6 decimal places) +const pricePerTokenUSDC = Math.floor(tokenPriceUSD * 1e6); +console.log(`USDC Price Calculation:`); +console.log(`- Token price: $${tokenPriceUSD} USDC`); +console.log(`- pricePerTokenUSDC: ${pricePerTokenUSDC} (6 decimals)`); +console.log(`- For deployment: ethers.parseUnits("${tokenPriceUSD}", 6)\n`); + +console.log("=== Raw Values for Constructor ==="); +console.log(`pricePerTokenETH: ${pricePerTokenETHWei}`); +console.log(`pricePerTokenUSDT: ${pricePerTokenUSDT}`); +console.log(`pricePerTokenUSDC: ${pricePerTokenUSDC}\n`); + +console.log("=== Complete Deployment Example ==="); +console.log(` +const SEQICO = await ethers.getContractFactory("SEQICO"); +const seqICO = await SEQICO.deploy( + seqTokenAddress, + usdtAddress, + usdcAddress, + ethers.parseEther("${tokenPriceETH}"), // ${tokenPriceETH} ETH per token + ethers.parseUnits("${tokenPriceUSD}", 6), // ${tokenPriceUSD} USDT per token + ethers.parseUnits("${tokenPriceUSD}", 6) // ${tokenPriceUSD} USDC per token +); +`); \ No newline at end of file