diff --git a/scripts/demo/demo.ts b/scripts/demo/demo.ts new file mode 100644 index 0000000..4d8dacb --- /dev/null +++ b/scripts/demo/demo.ts @@ -0,0 +1,57 @@ +import { ethers, upgrades } from 'hardhat'; + +async function main() { + const [deployer, user1] = await ethers.getSigners(); + + console.log('Deployer:', deployer.address); + console.log('User1:', user1.address); + + // Deploy USDX contract with UUPS upgradeability + const USDXFactory = await ethers.getContractFactory("USDX"); + const usdx = await upgrades.deployProxy(USDXFactory, ['X Protocol USD', 'USDX', deployer.address], { + initializer: 'initialize', + kind: 'uups', + }); + await usdx.deployed(); + console.log("USDX deployed at:", usdx.address); + + // Deploy wUSDX contract with UUPS upgradeability + const WUSDXFactory = await ethers.getContractFactory("wUSDX"); + const wusdx = await upgrades.deployProxy(WUSDXFactory, [usdx.address, deployer.address], { + initializer: 'initialize', + kind: 'uups', + }); + await wusdx.deployed(); + console.log("wUSDX deployed at:", wusdx.address); + + // Grant MINTER and ORACLE roles to the deployer for testing purposes + const MINTER_ROLE = await usdx.MINTER_ROLE(); + const ORACLE_ROLE = await usdx.ORACLE_ROLE(); + await usdx.grantRole(MINTER_ROLE, deployer.address); + await usdx.grantRole(ORACLE_ROLE, deployer.address); + console.log("Granted MINTER and ORACLE roles to deployer."); + + // Mint USDX tokens to User1 + await usdx.mint(user1.address, ethers.utils.parseEther("1000")); + console.log("Minted 1000 USDX to User1"); + + // Perform a rebase on the USDX contract + await usdx.setRewardMultiplier(ethers.utils.parseEther("1.1")); + console.log("Performed rebase with a 10% increase"); + + // Wrap USDX tokens to wUSDX for User1 + await usdx.connect(user1).approve(wusdx.address, ethers.utils.parseEther("500")); + await wusdx.connect(user1).deposit(ethers.utils.parseEther("500"), user1.address); + console.log("User1 wrapped 500 USDX to wUSDX"); + + // Display balances for User1 + const usdxBalance = await usdx.balanceOf(user1.address); + const wusdxBalance = await wusdx.balanceOf(user1.address); + console.log("User1 USDX balance:", ethers.utils.formatEther(usdxBalance)); + console.log("User1 wUSDX balance:", ethers.utils.formatEther(wusdxBalance)); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/scripts/demo/demo2.ts b/scripts/demo/demo2.ts new file mode 100644 index 0000000..59ced16 --- /dev/null +++ b/scripts/demo/demo2.ts @@ -0,0 +1,59 @@ +import { ethers, upgrades } from 'hardhat'; + +async function main() { + const [deployer, user1] = await ethers.getSigners(); + + console.log("=== USDX and wUSDX Deployment ==="); + const USDXFactory = await ethers.getContractFactory("USDX"); + const usdx = await upgrades.deployProxy(USDXFactory, ['X Protocol USD', 'USDX', deployer.address], { + initializer: 'initialize', + kind: 'uups', + }); + await usdx.deployed(); + const WUSDXFactory = await ethers.getContractFactory("wUSDX"); + const wusdx = await upgrades.deployProxy(WUSDXFactory, [usdx.address, deployer.address], { + initializer: 'initialize', + kind: 'uups', + }); + await wusdx.deployed(); + + console.log(`USDX deployed at: ${usdx.address}`); + console.log(`wUSDX deployed at: ${wusdx.address}\n`); + + console.log("=== Grant Roles for Minting and Oracle ==="); + await usdx.grantRole(await usdx.MINTER_ROLE(), deployer.address); + await usdx.grantRole(await usdx.ORACLE_ROLE(), deployer.address); + console.log("Roles granted to deployer.\n"); + + console.log("=== Simulating FOBXX Investment and Rebase ==="); + await usdx.mint(user1.address, ethers.utils.parseEther("1000000")); + console.log("Minted 1,000,000 USDX for User1"); + + await usdx.setRewardMultiplier(ethers.utils.parseEther("1.1")); + console.log("FOBXX investment yield applied with 10% increase.\n"); + + console.log("=== User1 Balance Check ==="); + const usdxBalance = await usdx.balanceOf(user1.address); + const formattedUsdxBalance = ethers.utils.formatEther(usdxBalance); + console.log(`User1 USDX Balance: ${formattedUsdxBalance} USDX`); + + await usdx.connect(user1).approve(wusdx.address, ethers.utils.parseEther("500000")); + await wusdx.connect(user1).deposit(ethers.utils.parseEther("500000"), user1.address); + + const wusdxBalance = await wusdx.balanceOf(user1.address); + const formattedWusdxBalance = ethers.utils.formatEther(wusdxBalance); + console.log(`User1 wUSDX Balance: ${formattedWusdxBalance} wUSDX\n`); + + console.log("=== Risk Management and Transparency ==="); + console.log("Risk Management:"); + console.log(" - Paused: No"); + console.log(" - Blocklist: [None]\n"); + + console.log("Transparency Events:"); + console.log(" - Mint, Rebase, Wrap"); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/scripts/demo/demo3.ts b/scripts/demo/demo3.ts new file mode 100644 index 0000000..4e5ec33 --- /dev/null +++ b/scripts/demo/demo3.ts @@ -0,0 +1,69 @@ +import { ethers, upgrades } from 'hardhat'; + +async function main() { + const [deployer, user1] = await ethers.getSigners(); + + console.log("=== USDX and wUSDX Deployment ==="); + const USDXFactory = await ethers.getContractFactory("USDX"); + const usdx = await upgrades.deployProxy(USDXFactory, ['X Protocol USD', 'USDX', deployer.address], { + initializer: 'initialize', + kind: 'uups', + }); + await usdx.deployed(); + + const WUSDXFactory = await ethers.getContractFactory("wUSDX"); + const wusdx = await upgrades.deployProxy(WUSDXFactory, [usdx.address, deployer.address], { + initializer: 'initialize', + kind: 'uups', + }); + await wusdx.deployed(); + + console.log(`USDX deployed at: ${usdx.address}`); + console.log(`wUSDX deployed at: ${wusdx.address}\n`); + + console.log("=== Grant Roles for Minting and Oracle ==="); + await usdx.grantRole(await usdx.MINTER_ROLE(), deployer.address); + await usdx.grantRole(await usdx.ORACLE_ROLE(), deployer.address); + console.log("Roles granted to deployer.\n"); + + console.log("=== Simulating FOBXX Investment and Rebase ==="); + await usdx.mint(user1.address, ethers.utils.parseEther("1000000")); + console.log("Minted 1,000,000 USDX for User1"); + + await usdx.setRewardMultiplier(ethers.utils.parseEther("1.1")); + console.log("FOBXX investment yield applied with 10% increase.\n"); + + console.log("=== User1 Balance Check ==="); + const usdxBalance = await usdx.balanceOf(user1.address); + console.log(`User1 USDX Balance: ${ethers.utils.formatEther(usdxBalance)} USDX`); + + await usdx.connect(user1).approve(wusdx.address, ethers.utils.parseEther("500000")); + await wusdx.connect(user1).deposit(ethers.utils.parseEther("500000"), user1.address); + + const wusdxBalance = await wusdx.balanceOf(user1.address); + console.log(`User1 wUSDX Balance: ${ethers.utils.formatEther(wusdxBalance)} wUSDX\n`); + + console.log("=== Simulating NAV Update ==="); + const currentNAV = await usdx.rewardMultiplier(); + const updatedNAV = currentNAV.mul(10002).div(10000); // Simulate a 0.02% NAV increase + + await usdx.setRewardMultiplier(updatedNAV); + console.log(`Updated NAV applied: ${ethers.utils.formatEther(updatedNAV)}\n`); + + console.log("=== User1 Balance After NAV Update ==="); + const newBalance = await usdx.balanceOf(user1.address); + console.log(`User1 USDX Balance after NAV update: ${ethers.utils.formatEther(newBalance)} USDX\n`); + + console.log("=== Risk Management and Transparency ==="); + console.log("Risk Management:"); + console.log(" - Paused: No"); + console.log(" - Blocklist: [None]\n"); + + console.log("Transparency Events:"); + console.log(" - Mint, Rebase, Wrap, NAV Update"); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/scripts/demo/demo4.ts b/scripts/demo/demo4.ts new file mode 100644 index 0000000..fc33705 --- /dev/null +++ b/scripts/demo/demo4.ts @@ -0,0 +1,150 @@ +import { ethers, upgrades } from 'hardhat'; +import readline from 'readline'; + +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout +}); + +async function prompt(query: string): Promise { + return new Promise((resolve) => rl.question(query, resolve)); +} + +async function sleep(ms: number): Promise { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +async function main() { + const [deployer, user1, user2] = await ethers.getSigners(); + + console.log("=== USDX and wUSDX Deployment ==="); + const USDXFactory = await ethers.getContractFactory("USDX"); + const usdx = await upgrades.deployProxy(USDXFactory, ['X Protocol USD', 'USDX', deployer.address], { + initializer: 'initialize', + kind: 'uups', + }); + await usdx.deployed(); + + const WUSDXFactory = await ethers.getContractFactory("wUSDX"); + const wusdx = await upgrades.deployProxy(WUSDXFactory, [usdx.address, deployer.address], { + initializer: 'initialize', + kind: 'uups', + }); + await wusdx.deployed(); + + console.log(`USDX deployed at: ${usdx.address}`); + console.log(`wUSDX deployed at: ${wusdx.address}\n`); + + await usdx.grantRole(await usdx.MINTER_ROLE(), deployer.address); + await usdx.grantRole(await usdx.ORACLE_ROLE(), deployer.address); + + while (true) { + const totalSupply = await usdx.totalSupply(); + console.log("\n=== Market Status ==="); + console.log(`USDX Supply: ${ethers.utils.formatEther(totalSupply)}`); + + + console.log("\n=== Demo Menu ==="); + console.log("1. Simulate FOBXX Investment"); + console.log("2. Apply Yield Increase"); + console.log("3. Check User Balances"); + console.log("4. Update NAV"); + console.log("5. Simulate Market Volatility"); + console.log("6. Exit"); + + const choice = await prompt("Enter your choice (1-6): "); + + switch (choice) { + case '1': + await simulateFOBXXInvestment(usdx, user1, user2); + break; + case '2': + await applyYieldIncrease(usdx); + break; + case '3': + await checkUserBalances(usdx, wusdx, user1, user2); + break; + case '4': + await updateNAV(usdx); + break; + case '5': + await simulateMarketVolatility(usdx); + break; + case '6': + rl.close(); + return; + default: + console.log("Invalid choice. Please try again."); + } + } +} + +async function simulateFOBXXInvestment(usdx: any, user1: any, user2: any) { + console.log("\n=== Simulating FOBXX Investment ==="); + await usdx.mint(user1.address, ethers.utils.parseEther("1000000")); + await usdx.mint(user2.address, ethers.utils.parseEther("500000")); + console.log("Minted 1,000,000 USDX for User1 and 500,000 USDX for User2"); + await sleep(2000); +} + +async function applyYieldIncrease(usdx: any) { + console.log("\n=== Applying Yield Increase ==="); + await usdx.setRewardMultiplier(ethers.utils.parseEther("1.1")); + console.log("FOBXX investment yield applied with 10% increase."); + await sleep(2000); +} + +async function checkUserBalances(usdx: any, wusdx: any, user1: any, user2: any) { + console.log("\n=== Checking User Balances ==="); + const user1Balance = await usdx.balanceOf(user1.address); + const user2Balance = await usdx.balanceOf(user2.address); + console.log(`User1 USDX Balance: ${ethers.utils.formatEther(user1Balance)} USDX`); + console.log(`User2 USDX Balance: ${ethers.utils.formatEther(user2Balance)} USDX`); + await sleep(2000); +} + +async function updateNAV(usdx: any) { + console.log("\n=== Updating NAV ==="); + const currentNAV = await usdx.rewardMultiplier(); + const updatedNAV = currentNAV.mul(10002).div(10000); + await usdx.setRewardMultiplier(updatedNAV); + console.log(`Updated NAV applied: ${ethers.utils.formatEther(updatedNAV)}`); + await sleep(2000); +} + +async function simulateMarketVolatility(usdx: any) { + console.log("\n=== Simulating Market Volatility ==="); + const initialNAV = await usdx.rewardMultiplier(); + console.log(`Initial NAV: ${ethers.utils.formatEther(initialNAV)}`); + + for (let i = 0; i < 5; i++) { + try { + // Limit the change to a smaller range, e.g., -0.1% to 0.1% + const change = (Math.random() * 0.002 - 0.001); + const currentNAV = await usdx.rewardMultiplier(); + let updatedNAV = currentNAV.mul(Math.floor(10000 + change * 10000)).div(10000); + + // Ensure the NAV doesn't go below 1 + if (updatedNAV.lt(ethers.utils.parseEther("1"))) { + updatedNAV = ethers.utils.parseEther("1"); + } + + // Ensure the NAV doesn't exceed a maximum value (e.g., 2) + const maxNAV = ethers.utils.parseEther("2"); + if (updatedNAV.gt(maxNAV)) { + updatedNAV = maxNAV; + } + + await usdx.setRewardMultiplier(updatedNAV); + console.log(`NAV updated to: ${ethers.utils.formatEther(updatedNAV)}`); + } catch (error) { + console.log(`Error updating NAV: ${error.message}`); + } + await sleep(1000); + } + } + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); \ No newline at end of file diff --git a/scripts/demo/demo5.ts b/scripts/demo/demo5.ts new file mode 100644 index 0000000..a42eecd --- /dev/null +++ b/scripts/demo/demo5.ts @@ -0,0 +1,156 @@ +import { ethers, upgrades } from 'hardhat'; +import readline from 'readline'; + +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout +}); + +async function prompt(query: string): Promise { + return new Promise((resolve) => rl.question(query, resolve)); +} + +async function sleep(ms: number): Promise { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +async function getCurrentPriceAndSupply(usdx: any) { + const currentNAV = await usdx.rewardMultiplier(); + const totalSupply = await usdx.totalSupply(); + return { + price: ethers.utils.formatEther(currentNAV), + supply: ethers.utils.formatEther(totalSupply) + }; +} + +async function main() { + const [deployer, user1, user2] = await ethers.getSigners(); + + console.log("=== USDX and wUSDX Deployment ==="); + const USDXFactory = await ethers.getContractFactory("USDX"); + const usdx = await upgrades.deployProxy(USDXFactory, ['X Protocol USD', 'USDX', deployer.address], { + initializer: 'initialize', + kind: 'uups', + }); + await usdx.deployed(); + + const WUSDXFactory = await ethers.getContractFactory("wUSDX"); + const wusdx = await upgrades.deployProxy(WUSDXFactory, [usdx.address, deployer.address], { + initializer: 'initialize', + kind: 'uups', + }); + await wusdx.deployed(); + + console.log(`USDX deployed at: ${usdx.address}`); + console.log(`wUSDX deployed at: ${wusdx.address}\n`); + + await usdx.grantRole(await usdx.MINTER_ROLE(), deployer.address); + await usdx.grantRole(await usdx.ORACLE_ROLE(), deployer.address); + + while (true) { + const { price, supply } = await getCurrentPriceAndSupply(usdx); + console.log("\n=== USDX Status ==="); + console.log(`wUSDX Price: $${price}`); + console.log(`USDX Supply: ${supply}`); + + console.log("\n=== Demo Menu ==="); + console.log("1. Simulate FOBXX Investment"); + console.log("2. Apply Yield Increase"); + console.log("3. Check User Balances"); + console.log("4. Update NAV"); + console.log("5. Simulate Market Volatility"); + console.log("6. Exit"); + + const choice = await prompt("Enter your choice (1-6): "); + + switch (choice) { + case '1': + await simulateFOBXXInvestment(usdx, user1, user2); + break; + case '2': + await applyYieldIncrease(usdx); + break; + case '3': + await checkUserBalances(usdx, wusdx, user1, user2); + break; + case '4': + await updateNAV(usdx); + break; + case '5': + await simulateMarketVolatility(usdx); + break; + case '6': + rl.close(); + return; + default: + console.log("Invalid choice. Please try again."); + } + } +} + +async function simulateFOBXXInvestment(usdx: any, user1: any, user2: any) { + console.log("\n=== Simulating FOBXX Investment ==="); + await usdx.mint(user1.address, ethers.utils.parseEther("1000000")); + await usdx.mint(user2.address, ethers.utils.parseEther("500000")); + console.log("Minted 1,000,000 USDX for User1 and 500,000 USDX for User2"); + await sleep(2000); +} + +async function applyYieldIncrease(usdx: any) { + console.log("\n=== Applying Yield Increase ==="); + await usdx.setRewardMultiplier(ethers.utils.parseEther("1.1")); + console.log("FOBXX investment yield applied with 10% increase."); + await sleep(2000); +} + +async function checkUserBalances(usdx: any, wusdx: any, user1: any, user2: any) { + console.log("\n=== Checking User Balances ==="); + const user1Balance = await usdx.balanceOf(user1.address); + const user2Balance = await usdx.balanceOf(user2.address); + console.log(`User1 USDX Balance: ${ethers.utils.formatEther(user1Balance)} USDX`); + console.log(`User2 USDX Balance: ${ethers.utils.formatEther(user2Balance)} USDX`); + await sleep(2000); +} + +async function updateNAV(usdx: any) { + console.log("\n=== Updating NAV ==="); + const currentNAV = await usdx.rewardMultiplier(); + const updatedNAV = currentNAV.mul(10002).div(10000); + await usdx.setRewardMultiplier(updatedNAV); + console.log(`Updated NAV applied: ${ethers.utils.formatEther(updatedNAV)}`); + await sleep(2000); +} + +async function simulateMarketVolatility(usdx: any) { + console.log("\n=== Simulating Market Volatility ==="); + const initialNAV = await usdx.rewardMultiplier(); + console.log(`Initial NAV: ${ethers.utils.formatEther(initialNAV)}`); + + for (let i = 0; i < 5; i++) { + try { + const change = (Math.random() * 0.002 - 0.001); + const currentNAV = await usdx.rewardMultiplier(); + let updatedNAV = currentNAV.mul(Math.floor(10000 + change * 10000)).div(10000); + + if (updatedNAV.lt(ethers.utils.parseEther("1"))) { + updatedNAV = ethers.utils.parseEther("1"); + } + + const maxNAV = ethers.utils.parseEther("2"); + if (updatedNAV.gt(maxNAV)) { + updatedNAV = maxNAV; + } + + await usdx.setRewardMultiplier(updatedNAV); + console.log(`NAV updated to: ${ethers.utils.formatEther(updatedNAV)}`); + } catch (error) { + console.log(`Error updating NAV: ${error.message}`); + } + await sleep(1000); + } +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); \ No newline at end of file diff --git a/scripts/demo/demo6.ts b/scripts/demo/demo6.ts new file mode 100644 index 0000000..1c8525d --- /dev/null +++ b/scripts/demo/demo6.ts @@ -0,0 +1,129 @@ +import { ethers, upgrades } from 'hardhat'; +import readline from 'readline'; + +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout +}); + +async function prompt(query: string): Promise { + return new Promise((resolve) => rl.question(query, resolve)); +} + +async function sleep(ms: number): Promise { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +async function main() { + const [deployer, user1, user2] = await ethers.getSigners(); + + console.log("=== USDX and wUSDX Deployment ==="); + const USDXFactory = await ethers.getContractFactory("USDX"); + const usdx = await upgrades.deployProxy(USDXFactory, ['X Protocol USD', 'USDX', deployer.address], { initializer: 'initialize', kind: 'uups' }); + await usdx.deployed(); + + const WUSDXFactory = await ethers.getContractFactory("wUSDX"); + const wusdx = await upgrades.deployProxy(WUSDXFactory, [usdx.address, deployer.address], { initializer: 'initialize', kind: 'uups' }); + await wusdx.deployed(); + + await usdx.grantRole(await usdx.MINTER_ROLE(), deployer.address); + await usdx.grantRole(await usdx.ORACLE_ROLE(), deployer.address); + + console.log(`USDX deployed at: ${usdx.address}`); + console.log(`wUSDX deployed at: ${wusdx.address}\n`); + + while (true) { + console.log("\n=== Demo Menu ==="); + console.log("1. Mint USDX & Demonstrate Peg"); + console.log("2. Apply Yield Distribution (Rebasing)"); + console.log("3. Wrap USDX to wUSDX"); + console.log("4. Update NAV"); + console.log("5. Simulate Market Volatility"); + console.log("6. Check User Balances"); + console.log("7. Exit"); + + const choice = await prompt("Choose an option (1-7): "); + switch (choice) { + case '1': + await mintAndPeg(usdx, user1, user2); + break; + case '2': + await applyYieldDistribution(usdx); + break; + case '3': + await wrapToWUSDX(usdx, wusdx, user1); + break; + case '4': + await updateNAV(usdx); + break; + case '5': + await simulateVolatility(usdx); + break; + case '6': + await checkUserBalances(usdx, wusdx, user1, user2); + break; + case '7': + rl.close(); + return; + default: + console.log("Invalid option. Please select again."); + } + } +} + +async function mintAndPeg(usdx: any, user1: any, user2: any) { + await usdx.mint(user1.address, ethers.utils.parseEther("1000")); + await usdx.mint(user2.address, ethers.utils.parseEther("500")); + console.log("Peg maintained: 1 USD per USDX. Minted 1,000 to User1 and 500 to User2."); + await sleep(2000); +} + +async function applyYieldDistribution(usdx: any) { + await usdx.setRewardMultiplier(ethers.utils.parseEther("1.05")); + console.log("Yield applied. USDX balances increased by 5%."); + await sleep(2000); +} + +async function wrapToWUSDX(usdx: any, wusdx: any, user: any) { + await usdx.connect(user).approve(wusdx.address, ethers.utils.parseEther("500")); + await wusdx.connect(user).deposit(ethers.utils.parseEther("500"), user.address); + console.log("Wrapped 500 USDX to wUSDX for User."); + await sleep(2000); +} + +async function updateNAV(usdx: any) { + const currentNAV = await usdx.rewardMultiplier(); + const newNAV = currentNAV.mul(10001).div(10000); + await usdx.setRewardMultiplier(newNAV); + console.log(`Updated NAV applied: ${ethers.utils.formatEther(newNAV)}`); + await sleep(2000); +} + +async function simulateVolatility(usdx: any) { + console.log("Simulating Market Volatility..."); + for (let i = 0; i < 3; i++) { + const change = 1 + ((Math.random() - 0.5) / 50); + const currentNAV = await usdx.rewardMultiplier(); + const newNAV = currentNAV.mul(Math.floor(change * 100)).div(100); + await usdx.setRewardMultiplier(newNAV); + console.log(`Adjusted NAV: ${ethers.utils.formatEther(newNAV)}`); + await sleep(1000); + } +} + +async function checkUserBalances(usdx: any, wusdx: any, user1: any, user2: any) { + console.log("\n=== Checking User Balances ==="); + const user1USDXBalance = await usdx.balanceOf(user1.address); + const user1wUSDXBalance = await wusdx.balanceOf(user1.address); + const user2USDXBalance = await usdx.balanceOf(user2.address); + const user2wUSDXBalance = await wusdx.balanceOf(user2.address); + + console.log(`User1: ${ethers.utils.formatEther(user1USDXBalance)} USDX, ${ethers.utils.formatEther(user1wUSDXBalance)} wUSDX`); + console.log(`User2: ${ethers.utils.formatEther(user2USDXBalance)} USDX, ${ethers.utils.formatEther(user2wUSDXBalance)} wUSDX`); + await sleep(2000); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/scripts/demo/video.ts b/scripts/demo/video.ts new file mode 100644 index 0000000..1c8525d --- /dev/null +++ b/scripts/demo/video.ts @@ -0,0 +1,129 @@ +import { ethers, upgrades } from 'hardhat'; +import readline from 'readline'; + +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout +}); + +async function prompt(query: string): Promise { + return new Promise((resolve) => rl.question(query, resolve)); +} + +async function sleep(ms: number): Promise { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +async function main() { + const [deployer, user1, user2] = await ethers.getSigners(); + + console.log("=== USDX and wUSDX Deployment ==="); + const USDXFactory = await ethers.getContractFactory("USDX"); + const usdx = await upgrades.deployProxy(USDXFactory, ['X Protocol USD', 'USDX', deployer.address], { initializer: 'initialize', kind: 'uups' }); + await usdx.deployed(); + + const WUSDXFactory = await ethers.getContractFactory("wUSDX"); + const wusdx = await upgrades.deployProxy(WUSDXFactory, [usdx.address, deployer.address], { initializer: 'initialize', kind: 'uups' }); + await wusdx.deployed(); + + await usdx.grantRole(await usdx.MINTER_ROLE(), deployer.address); + await usdx.grantRole(await usdx.ORACLE_ROLE(), deployer.address); + + console.log(`USDX deployed at: ${usdx.address}`); + console.log(`wUSDX deployed at: ${wusdx.address}\n`); + + while (true) { + console.log("\n=== Demo Menu ==="); + console.log("1. Mint USDX & Demonstrate Peg"); + console.log("2. Apply Yield Distribution (Rebasing)"); + console.log("3. Wrap USDX to wUSDX"); + console.log("4. Update NAV"); + console.log("5. Simulate Market Volatility"); + console.log("6. Check User Balances"); + console.log("7. Exit"); + + const choice = await prompt("Choose an option (1-7): "); + switch (choice) { + case '1': + await mintAndPeg(usdx, user1, user2); + break; + case '2': + await applyYieldDistribution(usdx); + break; + case '3': + await wrapToWUSDX(usdx, wusdx, user1); + break; + case '4': + await updateNAV(usdx); + break; + case '5': + await simulateVolatility(usdx); + break; + case '6': + await checkUserBalances(usdx, wusdx, user1, user2); + break; + case '7': + rl.close(); + return; + default: + console.log("Invalid option. Please select again."); + } + } +} + +async function mintAndPeg(usdx: any, user1: any, user2: any) { + await usdx.mint(user1.address, ethers.utils.parseEther("1000")); + await usdx.mint(user2.address, ethers.utils.parseEther("500")); + console.log("Peg maintained: 1 USD per USDX. Minted 1,000 to User1 and 500 to User2."); + await sleep(2000); +} + +async function applyYieldDistribution(usdx: any) { + await usdx.setRewardMultiplier(ethers.utils.parseEther("1.05")); + console.log("Yield applied. USDX balances increased by 5%."); + await sleep(2000); +} + +async function wrapToWUSDX(usdx: any, wusdx: any, user: any) { + await usdx.connect(user).approve(wusdx.address, ethers.utils.parseEther("500")); + await wusdx.connect(user).deposit(ethers.utils.parseEther("500"), user.address); + console.log("Wrapped 500 USDX to wUSDX for User."); + await sleep(2000); +} + +async function updateNAV(usdx: any) { + const currentNAV = await usdx.rewardMultiplier(); + const newNAV = currentNAV.mul(10001).div(10000); + await usdx.setRewardMultiplier(newNAV); + console.log(`Updated NAV applied: ${ethers.utils.formatEther(newNAV)}`); + await sleep(2000); +} + +async function simulateVolatility(usdx: any) { + console.log("Simulating Market Volatility..."); + for (let i = 0; i < 3; i++) { + const change = 1 + ((Math.random() - 0.5) / 50); + const currentNAV = await usdx.rewardMultiplier(); + const newNAV = currentNAV.mul(Math.floor(change * 100)).div(100); + await usdx.setRewardMultiplier(newNAV); + console.log(`Adjusted NAV: ${ethers.utils.formatEther(newNAV)}`); + await sleep(1000); + } +} + +async function checkUserBalances(usdx: any, wusdx: any, user1: any, user2: any) { + console.log("\n=== Checking User Balances ==="); + const user1USDXBalance = await usdx.balanceOf(user1.address); + const user1wUSDXBalance = await wusdx.balanceOf(user1.address); + const user2USDXBalance = await usdx.balanceOf(user2.address); + const user2wUSDXBalance = await wusdx.balanceOf(user2.address); + + console.log(`User1: ${ethers.utils.formatEther(user1USDXBalance)} USDX, ${ethers.utils.formatEther(user1wUSDXBalance)} wUSDX`); + console.log(`User2: ${ethers.utils.formatEther(user2USDXBalance)} USDX, ${ethers.utils.formatEther(user2wUSDXBalance)} wUSDX`); + await sleep(2000); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +});