diff --git a/.gitignore b/.gitignore index 1c87b9ee..abc99a6f 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,5 @@ out/ .DS_Store .env -scripts/simulationData/simulationOutput/simulationResults*.json \ No newline at end of file +scripts/simulationData/simulationOutput/simulationResults*.json +scripts/simulationData/simulationSheet*.json \ No newline at end of file diff --git a/scripts/simulation.ts b/scripts/simulation.ts index b444acd1..cc8bbaad 100644 --- a/scripts/simulation.ts +++ b/scripts/simulation.ts @@ -5,6 +5,8 @@ import { TestRunner } from "./utils/facades/TestRunner"; import { Constants, MarketData } from "./utils/facades/types"; import { simulationTesting } from "./simulationTests"; import { SimulationParameters } from "./utils/facades/RoundSimulator"; +import { Account, CallData, hash, Provider } from "starknet"; +import { ERC20Facade } from "./utils/facades/erc20Facade"; async function main(environment: string, port?: string) { const provider = getProvider(environment, port); const devAccount = getAccount(environment, provider); @@ -33,15 +35,28 @@ async function main(environment: string, port?: string) { constants ); + const feeTokenFacade = new ERC20Facade( + "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", + provider + ); + feeTokenFacade.erc20Contract.connect(devAccount); + await feeTokenFacade.erc20Contract.transfer( + "0x0134f47366096198eb8f86e3ae6b075d399ca7abd918a56e01bb3b24963c2f75", + BigInt(1000000000000000000) + ); + await feeTokenFacade.erc20Contract.transfer( + "0x01577908d02E0a3A6B243A149Eb91BB4514f3aAb948CFE63b2f8bb52397618D4", + BigInt(1000000000000000000) + ); await testRunner.ethFacade.supplyERC20( devAccount, provider, ethAddress, vaultAddress ); + await simulationTesting(testRunner); } main(process.argv[2], process.argv[3]); - diff --git a/scripts/simulationTests/index.ts b/scripts/simulationTests/index.ts index f44af61a..61840738 100644 --- a/scripts/simulationTests/index.ts +++ b/scripts/simulationTests/index.ts @@ -35,7 +35,6 @@ async function simulationTesting(testRunner: TestRunner) { const roundData = await simulator.simulateRound(roundParams); data.results.push(roundData); } - console.log("DATA", data); const stringified = JSON.stringify(data); fs.writeFile( `./simulationData/simulationOutput/simulationResults-${Math.floor( @@ -53,13 +52,13 @@ const initial = { liquidityProviders: [1, 2], depositAmounts: ["50000000000000", "50000000000000"], optionBidders: [1, 3], - bidAmounts: [5000, 7000], + }; const repeating = { liquidityProviders: [], depositAmounts: [], optionBidders: [1, 3], - bidAmounts: [5000, 7000], + }; export const generateSheet = () => { @@ -82,10 +81,16 @@ export const generateSheet = () => { return marketData.reservePrice; }), marketData, + bidAmounts:[Math.random(),Math.random()], + withdrawals:[1,2], + withdrawalAmounts:[Math.random()/2,Math.random()/2], } as SimulationSheet; } else return { ...repeating, + bidAmounts:[Math.random(),Math.random()], + withdrawals:[1,2], + withdrawalAmounts:[Math.random()/2,Math.random()/2], bidPrices: initial.optionBidders.map((bidder) => { return marketData.reservePrice; }), diff --git a/scripts/utils/constants.ts b/scripts/utils/constants.ts index fba2d356..1963110c 100644 --- a/scripts/utils/constants.ts +++ b/scripts/utils/constants.ts @@ -17,6 +17,7 @@ type VaultConstructorArgs = { roundTransitionPeriod: number; auctionRunTime: number; optionRunTime: number; + kFactor:number; }; type ConstructorArgs = { @@ -39,12 +40,14 @@ const constructorArgs: { [key: string]: ConstructorArgs } = { "0x7ce7089cb75a590b9485f6851d8998fa885494cc7a70dbae8f3db572586b8a8", }, vault: { - roundTransitionPeriod: 32, - auctionRunTime: 23, - optionRunTime: 23, + roundTransitionPeriod: 32000, + auctionRunTime: 23000, + optionRunTime: 23000, + kFactor:10000, }, optionRound: "", marketAggregator: "", + }, }; const accountDetailsMapping: { [key: string]: AccountDetailsType } = { diff --git a/scripts/utils/facades/RoundSimulator.ts b/scripts/utils/facades/RoundSimulator.ts index 95995846..f6d1ef09 100644 --- a/scripts/utils/facades/RoundSimulator.ts +++ b/scripts/utils/facades/RoundSimulator.ts @@ -6,6 +6,7 @@ import { MarketData, PlaceBidArgs, RefundUnusedBidsArgs, + WithdrawArgs, } from "./types"; import { TestRunner } from "./TestRunner"; import { getOptionRoundContract, getOptionRoundFacade } from "../helpers/setup"; @@ -18,6 +19,11 @@ export type SimulationSheet = { depositAmounts: Array; bidAmounts: Array; bidPrices: Array; + withdrawalsPremium?: Array; + withdrawalsFromQueue?: Array; + withdrawalsFromQueueAmounts?: Array; + withdrawals?: Array; + withdrawalAmounts?: Array; marketData: MarketData; }; @@ -27,7 +33,9 @@ export type SimulationParameters = { refundAllArgs: Array; lpAccounts?: Array; bidderAccounts?: Array; - + withdrawPremiumArgs: Array; + withdrawalQueueArgs?: Array; + withdrawalArgs: Array; exerciseOptionsAllArgs: Array; marketData: MarketData; }; @@ -37,10 +45,10 @@ export type StateData = { lpLockedBalances: Array; lpUnlockedBalances: Array; }; - vaultBalances:{ - vaultLocked:string; - vaultUnlocked:string; - } + vaultBalances: { + vaultLocked: string; + vaultUnlocked: string; + }; ethBalancesBidders: Array; timeStamp?: string | number; }; @@ -75,19 +83,26 @@ export class RoundSimulator { params.bidAllArgs, params.marketData ); - const optionsAvailable = await this.optionRoundFacade.getTotalOptionsAvailable(); + const optionsAvailable = + await this.optionRoundFacade.getTotalOptionsAvailable(); const runningStateData: StateData = await this.simulateRunningState( - params.refundAllArgs + params.refundAllArgs, + params.withdrawPremiumArgs ); const settledStateData: StateData = await this.simulateSettledState( - params.exerciseOptionsAllArgs + params.exerciseOptionsAllArgs, + params.withdrawalArgs ); - const optionsSold = await this.optionRoundFacade.optionRoundContract.total_options_sold(); + const optionsSold = + await this.optionRoundFacade.optionRoundContract.total_options_sold(); - const ethBalanceVault = await this.testRunner.ethFacade.getBalance(this.testRunner.vaultFacade.vaultContract.address); - const ethBalanceRound = await this.testRunner.ethFacade.getBalance(this.optionRoundFacade.optionRoundContract.address); + const ethBalanceVault = await this.testRunner.ethFacade.getBalance( + this.testRunner.vaultFacade.vaultContract.address + ); + const ethBalanceRound = await this.testRunner.ethFacade.getBalance( + this.optionRoundFacade.optionRoundContract.address + ); if (params.marketData.startTime && params.marketData.endTime) { - //Mock timestamps if present on the marketData const difference = Number(params.marketData.endTime) - Number(params.marketData.startTime); @@ -102,10 +117,10 @@ export class RoundSimulator { } return { - ethBalanceRound:ethBalanceRound.toString(), - ethBalanceVault:ethBalanceVault.toString(), - optionsAvailable:optionsAvailable.toString(), - optionsSold:optionsSold.toString(), + ethBalanceRound: ethBalanceRound.toString(), + ethBalanceVault: ethBalanceVault.toString(), + optionsAvailable: optionsAvailable.toString(), + optionsSold: optionsSold.toString(), openStateData, auctioningStateData, runningStateData, @@ -114,12 +129,11 @@ export class RoundSimulator { } async captureLockedUnlockedBalances() { - const lpLockedBalancesBigInt = - await this.testRunner.getLPLockedBalanceAll(this.lpAccounts); + const lpLockedBalancesBigInt = await this.testRunner.getLPLockedBalanceAll( + this.lpAccounts + ); const lpUnlockedBalancesBigint = - await this.testRunner.getLPUnlockedBalanceAll( - this.lpAccounts - ); + await this.testRunner.getLPUnlockedBalanceAll(this.lpAccounts); const lpLockedBalances = lpLockedBalancesBigInt.map((balance) => { return balance.toString(); }); @@ -143,9 +157,9 @@ export class RoundSimulator { const locked = await this.testRunner.vaultFacade.getTotalLocked(); const unlocked = await this.testRunner.vaultFacade.getTotalUnLocked(); return { - vaultLocked:locked.toString(), - vaultUnlocked:unlocked.toString() - } + vaultLocked: locked.toString(), + vaultUnlocked: unlocked.toString(), + }; } async captureEthBalancesOptionBidders() { @@ -177,7 +191,17 @@ export class RoundSimulator { const lockedUnlockedBalances = await this.captureLockedUnlockedBalances(); const vaultBalances = await this.captureVaultBalances(); - const approvalArgs = bidAllArgs.map((arg) => { + const optionsAvailable = + await this.optionRoundFacade.getTotalOptionsAvailable(); + + const bidAllArgsAdjusted = bidAllArgs.map((args) => { + return { + from: args.from, + amount: Math.floor(Number(args.amount) * Number(optionsAvailable)), + price: args.price, + } as PlaceBidArgs; + }); + const approvalArgs = bidAllArgsAdjusted.map((arg) => { const data: ApprovalArgs = { owner: arg.from, spender: this.optionRoundFacade.optionRoundContract.address, @@ -185,19 +209,42 @@ export class RoundSimulator { }; return data; }); + await this.testRunner.approveAll(approvalArgs); - await this.optionRoundFacade.placeBidsAll(bidAllArgs); + await this.optionRoundFacade.placeBidsAll(bidAllArgsAdjusted); const ethBalancesBidders = await this.captureEthBalancesOptionBidders(); return { lockedUnlockedBalances, ethBalancesBidders, - vaultBalances + vaultBalances, }; } - async simulateRunningState(refundAllArgs: Array) { - const data = await this.testRunner.endAuctionBystander(); + async simulateRunningState( + refundAllArgs: Array, + withdrawPremiumArgs: Array + ) { + await this.testRunner.endAuctionBystander(); + + const totalPremiums = await this.optionRoundFacade.getTotalPremiums(); + const startingLiquidity = + await this.optionRoundFacade.getStartingLiquidity(); + const withdrawPremiumArgsAdjusted: Array = []; + for (const args of withdrawPremiumArgs) { + const lockedBalance = + await this.testRunner.vaultFacade.getLPLockedBalance( + args.account.address + ); + const premiumsToWithdraw = + (BigInt(lockedBalance) * BigInt(totalPremiums)) / + BigInt(startingLiquidity); + withdrawPremiumArgs.push({ + account: args.account, + amount: Math.floor(Number(premiumsToWithdraw)), + }); + } + await this.testRunner.withdrawAll(withdrawPremiumArgsAdjusted); const lockedUnlockedBalances = await this.captureLockedUnlockedBalances(); const vaultBalances = await this.captureVaultBalances(); await this.optionRoundFacade.refundUnusedBidsAll(refundAllArgs); @@ -205,16 +252,36 @@ export class RoundSimulator { return { lockedUnlockedBalances, ethBalancesBidders, - vaultBalances + vaultBalances, }; } - async simulateSettledState(exerciseOptionsArgs: Array) { + async simulateSettledState( + exerciseOptionsArgs: Array, + withdrawalArgs: Array + ) { const data = await this.optionRoundFacade.optionRoundContract.get_state(); await this.testRunner.settleOptionRoundBystander(); + const withdrawArgsAdjusted: Array = []; + + for (const args of withdrawalArgs) { + const unlockedBalance = + await this.testRunner.vaultFacade.getLPUnlockedBalance( + args.account.address + ); + console.log("UNLOCKED",unlockedBalance); + withdrawArgsAdjusted.push({ + account:args.account, + amount:Math.floor(Number(args.amount)*Number(unlockedBalance)) + }) + } + + const lpBefore = await this.captureLockedUnlockedBalances(); + await this.testRunner.withdrawAll(withdrawArgsAdjusted); + const lpAfter = await this.captureLockedUnlockedBalances(); + console.log("ARGS:",withdrawalArgs,"\nADjusted:",withdrawArgsAdjusted) const lockedUnlockedBalances = await this.captureLockedUnlockedBalances(); const vaultBalances = await this.captureVaultBalances(); - console.log("3"); await this.optionRoundFacade.exerciseOptionsAll(exerciseOptionsArgs); const ethBalancesBidders = await this.captureEthBalancesOptionBidders(); diff --git a/scripts/utils/facades/erc20Facade.ts b/scripts/utils/facades/erc20Facade.ts index 8e69978e..d2bee38a 100644 --- a/scripts/utils/facades/erc20Facade.ts +++ b/scripts/utils/facades/erc20Facade.ts @@ -75,6 +75,7 @@ export class ERC20Facade { provider ).typedv2(erc20ABI); + await this.supply(devAccount, "0x06Fb643e5c834feA33EACeFc10A2F856E1C317E700523c8eA45681F52D2B1D60",BigInt(10000000000)); for (let i = 0; i < 6; i++) { const lp = getCustomAccount( provider, diff --git a/scripts/utils/facades/optionRoundFacade.ts b/scripts/utils/facades/optionRoundFacade.ts index b1596329..86efbcd6 100644 --- a/scripts/utils/facades/optionRoundFacade.ts +++ b/scripts/utils/facades/optionRoundFacade.ts @@ -21,6 +21,11 @@ export class OptionRoundFacade { } + + async getStartingLiquidity(){ + const res = await this.optionRoundContract.starting_liquidity(); + return convertToBigInt(res); + } async getRoundId() { const res = await this.optionRoundContract.get_round_id(); return convertToBigInt(res); @@ -95,10 +100,9 @@ export class OptionRoundFacade { this.optionRoundContract.connect(from); try { const data = await this.optionRoundContract.place_bid(amount, price); - console.log("SUCCESS", data); } catch (err) { const error = err as LibraryError; - console.log(error.name); + console.log(error.name,from,amount,price,error.message,error.cause); } } diff --git a/scripts/utils/helpers/setup.ts b/scripts/utils/helpers/setup.ts index 1d278e9e..cc5e0e3d 100644 --- a/scripts/utils/helpers/setup.ts +++ b/scripts/utils/helpers/setup.ts @@ -2,9 +2,19 @@ import { CairoUint256, Contract, Provider, TypedContractV2 } from "starknet"; import { stringToHex } from "./common"; import { erc20ABI, optionRoundABI, vaultABI } from "../../abi"; import { OptionRoundFacade } from "../facades/optionRoundFacade"; -import { SimulationParameters, SimulationSheet } from "../facades/RoundSimulator"; -import { DepositArgs, ExerciseOptionArgs, PlaceBidArgs, RefundUnusedBidsArgs } from "../facades/types"; +import { + SimulationParameters, + SimulationSheet, +} from "../facades/RoundSimulator"; +import { + DepositArgs, + ExerciseOptionArgs, + PlaceBidArgs, + RefundUnusedBidsArgs, + WithdrawArgs, +} from "../facades/types"; import { TestRunner } from "../facades/TestRunner"; +import { liquidityProviders } from "../constants"; export const getOptionRoundFacade = async ( provider: Provider, @@ -80,7 +90,7 @@ export const generateSimulationParams = ( (bidder, index) => { const data: PlaceBidArgs = { from: optionBidderAccounts[bidder - 1], - amount: BigInt(simulationSheet.bidAmounts[index]), + amount: Number(simulationSheet.bidAmounts[index]), price: BigInt(simulationSheet.bidPrices[index]), }; return data; @@ -91,10 +101,37 @@ export const generateSimulationParams = ( bidAllArgs.map((bids) => { if (!ref[bids.from.address]) { ref[bids.from.address] = true; - refundAllArgs.push({ from: bids.from, optionBidder: bids.from.address }); + refundAllArgs.push({ + from: bids.from, + optionBidder: bids.from.address, + }); } }); + let withdrawPremiumArgs: Array = []; + if (simulationSheet.withdrawalsPremium) { + withdrawPremiumArgs = simulationSheet.withdrawalsPremium.map( + (bidder) => ({ + account: liquidityProviderAccounts[bidder - 1], + amount: 0, + }) + ); + } + + let withdrawalArgs: Array = []; + if (simulationSheet.withdrawalAmounts && simulationSheet.withdrawals) { + withdrawalArgs = simulationSheet.withdrawals.map((bidder, index) => { + return { + account: liquidityProviderAccounts[bidder - 1], + amount: Number( + simulationSheet.withdrawalAmounts + ? simulationSheet.withdrawalAmounts[index] + : 0 + ), + }; + }); + } + const exerciseOptionsAllArgs: Array = simulationSheet.optionBidders.map((bidder) => ({ from: optionBidderAccounts[bidder - 1], @@ -103,8 +140,10 @@ export const generateSimulationParams = ( depositAllArgs, bidAllArgs, marketData: simulationSheet.marketData, + withdrawPremiumArgs, + withdrawalArgs, exerciseOptionsAllArgs, - refundAllArgs + refundAllArgs, }; return data; }); diff --git a/scripts/utils/katana.ts b/scripts/utils/katana.ts index 04f00433..b18b629e 100644 --- a/scripts/utils/katana.ts +++ b/scripts/utils/katana.ts @@ -14,7 +14,7 @@ export const setNextBlock = async (increase: number, url: string) => { await fetch(url, options) .then((response) => response.json()) - .then((response) => console.log(response)) + .then((response) => {}) .catch((err) => console.error(err)); }; export const mineNextBlock = async (url: string) => { @@ -31,7 +31,7 @@ export const mineNextBlock = async (url: string) => { await fetch(url, options) .then((response) => response.json()) - .then((response) => console.log(response)) + .then((response) =>{}) .catch((err) => console.error(err)); };